@@ -6878,147 +6878,57 @@ static void coerce_reg_to_size(struct bpf_reg_state *reg, int size)
68786878 reg_bounds_sync(reg);
68796879}
68806880
6881- static void set_sext64_default_val(struct bpf_reg_state *reg, int size)
6882- {
6883- if (size == 1) {
6884- reg->smin_value = reg->s32_min_value = S8_MIN;
6885- reg->smax_value = reg->s32_max_value = S8_MAX;
6886- } else if (size == 2) {
6887- reg->smin_value = reg->s32_min_value = S16_MIN;
6888- reg->smax_value = reg->s32_max_value = S16_MAX;
6889- } else {
6890- /* size == 4 */
6891- reg->smin_value = reg->s32_min_value = S32_MIN;
6892- reg->smax_value = reg->s32_max_value = S32_MAX;
6893- }
6894- reg->umin_value = reg->u32_min_value = 0;
6895- reg->umax_value = U64_MAX;
6896- reg->u32_max_value = U32_MAX;
6897- reg->var_off = tnum_unknown;
6898- }
6899-
69006881static void coerce_reg_to_size_sx(struct bpf_reg_state *reg, int size)
69016882{
6902- s64 init_s64_max, init_s64_min, s64_max, s64_min, u64_cval;
6903- u64 top_smax_value, top_smin_value;
6904- u64 num_bits = size * 8;
6883+ s64 smin_value, smax_value;
69056884
6906- if (tnum_is_const(reg->var_off)) {
6907- u64_cval = reg->var_off.value;
6908- if (size == 1)
6909- reg->var_off = tnum_const((s8)u64_cval);
6910- else if (size == 2)
6911- reg->var_off = tnum_const((s16)u64_cval);
6912- else
6913- /* size == 4 */
6914- reg->var_off = tnum_const((s32)u64_cval);
6915-
6916- u64_cval = reg->var_off.value;
6917- reg->smax_value = reg->smin_value = u64_cval;
6918- reg->umax_value = reg->umin_value = u64_cval;
6919- reg->s32_max_value = reg->s32_min_value = u64_cval;
6920- reg->u32_max_value = reg->u32_min_value = u64_cval;
6885+ if (size >= 8)
69216886 return;
6922- }
69236887
6924- top_smax_value = ((u64)reg->smax_value >> num_bits) << num_bits;
6925- top_smin_value = ((u64)reg->smin_value >> num_bits) << num_bits;
6888+ reg->var_off = tnum_scast(reg->var_off, size);
69266889
6927- if (top_smax_value != top_smin_value)
6928- goto out ;
6890+ smin_value = -(1LL << (size * 8 - 1));
6891+ smax_value = (1LL << (size * 8 - 1)) - 1 ;
69296892
6930- /* find the s64_min and s64_min after sign extension */
6931- if (size == 1) {
6932- init_s64_max = (s8)reg->smax_value;
6933- init_s64_min = (s8)reg->smin_value;
6934- } else if (size == 2) {
6935- init_s64_max = (s16)reg->smax_value;
6936- init_s64_min = (s16)reg->smin_value;
6937- } else {
6938- init_s64_max = (s32)reg->smax_value;
6939- init_s64_min = (s32)reg->smin_value;
6940- }
6941-
6942- s64_max = max(init_s64_max, init_s64_min);
6943- s64_min = min(init_s64_max, init_s64_min);
6893+ reg->smin_value = smin_value;
6894+ reg->smax_value = smax_value;
69446895
6945- /* both of s64_max/s64_min positive or negative */
6946- if ((s64_max >= 0) == (s64_min >= 0)) {
6947- reg->s32_min_value = reg->smin_value = s64_min;
6948- reg->s32_max_value = reg->smax_value = s64_max;
6949- reg->u32_min_value = reg->umin_value = s64_min;
6950- reg->u32_max_value = reg->umax_value = s64_max;
6951- reg->var_off = tnum_range(s64_min, s64_max);
6952- return;
6953- }
6896+ reg->s32_min_value = (s32)smin_value;
6897+ reg->s32_max_value = (s32)smax_value;
69546898
6955- out:
6956- set_sext64_default_val(reg, size);
6957- }
6958-
6959- static void set_sext32_default_val(struct bpf_reg_state *reg, int size)
6960- {
6961- if (size == 1) {
6962- reg->s32_min_value = S8_MIN;
6963- reg->s32_max_value = S8_MAX;
6964- } else {
6965- /* size == 2 */
6966- reg->s32_min_value = S16_MIN;
6967- reg->s32_max_value = S16_MAX;
6968- }
6899+ reg->umin_value = 0;
6900+ reg->umax_value = U64_MAX;
69696901 reg->u32_min_value = 0;
69706902 reg->u32_max_value = U32_MAX;
6971- reg->var_off = tnum_subreg(tnum_unknown);
6903+
6904+ __update_reg_bounds(reg);
69726905}
69736906
69746907static void coerce_subreg_to_size_sx(struct bpf_reg_state *reg, int size)
69756908{
6976- s32 init_s32_max, init_s32_min, s32_max, s32_min, u32_val;
6977- u32 top_smax_value, top_smin_value;
6978- u32 num_bits = size * 8;
6979-
6980- if (tnum_is_const(reg->var_off)) {
6981- u32_val = reg->var_off.value;
6982- if (size == 1)
6983- reg->var_off = tnum_const((s8)u32_val);
6984- else
6985- reg->var_off = tnum_const((s16)u32_val);
6909+ s32 smin_value, smax_value;
69866910
6987- u32_val = reg->var_off.value;
6988- reg->s32_min_value = reg->s32_max_value = u32_val;
6989- reg->u32_min_value = reg->u32_max_value = u32_val;
6911+ if (size >= 4)
69906912 return;
6991- }
69926913
6993- top_smax_value = ((u32)reg->s32_max_value >> num_bits) << num_bits;
6994- top_smin_value = ((u32)reg->s32_min_value >> num_bits) << num_bits;
6914+ reg->var_off = tnum_subreg(tnum_scast(reg->var_off, size));
69956915
6996- if (top_smax_value != top_smin_value)
6997- goto out ;
6916+ smin_value = -(1 << (size * 8 - 1));
6917+ smax_value = (1 << (size * 8 - 1)) - 1 ;
69986918
6999- /* find the s32_min and s32_min after sign extension */
7000- if (size == 1) {
7001- init_s32_max = (s8)reg->s32_max_value;
7002- init_s32_min = (s8)reg->s32_min_value;
7003- } else {
7004- /* size == 2 */
7005- init_s32_max = (s16)reg->s32_max_value;
7006- init_s32_min = (s16)reg->s32_min_value;
7007- }
7008- s32_max = max(init_s32_max, init_s32_min);
7009- s32_min = min(init_s32_max, init_s32_min);
7010-
7011- if ((s32_min >= 0) == (s32_max >= 0)) {
7012- reg->s32_min_value = s32_min;
7013- reg->s32_max_value = s32_max;
7014- reg->u32_min_value = (u32)s32_min;
7015- reg->u32_max_value = (u32)s32_max;
7016- reg->var_off = tnum_subreg(tnum_range(s32_min, s32_max));
7017- return;
7018- }
6919+ reg->s32_min_value = smin_value;
6920+ reg->s32_max_value = smax_value;
70196921
7020- out:
7021- set_sext32_default_val(reg, size);
6922+ reg->u32_min_value = 0;
6923+ reg->u32_max_value = U32_MAX;
6924+
6925+ __update_reg32_bounds(reg);
6926+
6927+ reg->umin_value = reg->u32_min_value;
6928+ reg->umax_value = reg->u32_max_value;
6929+
6930+ reg->smin_value = reg->umin_value;
6931+ reg->smax_value = reg->umax_value;
70226932}
70236933
70246934static bool bpf_map_is_rdonly(const struct bpf_map *map)
0 commit comments