@@ -6876,147 +6876,57 @@ static void coerce_reg_to_size(struct bpf_reg_state *reg, int size)
68766876 reg_bounds_sync(reg);
68776877}
68786878
6879- static void set_sext64_default_val(struct bpf_reg_state *reg, int size)
6880- {
6881- if (size == 1) {
6882- reg->smin_value = reg->s32_min_value = S8_MIN;
6883- reg->smax_value = reg->s32_max_value = S8_MAX;
6884- } else if (size == 2) {
6885- reg->smin_value = reg->s32_min_value = S16_MIN;
6886- reg->smax_value = reg->s32_max_value = S16_MAX;
6887- } else {
6888- /* size == 4 */
6889- reg->smin_value = reg->s32_min_value = S32_MIN;
6890- reg->smax_value = reg->s32_max_value = S32_MAX;
6891- }
6892- reg->umin_value = reg->u32_min_value = 0;
6893- reg->umax_value = U64_MAX;
6894- reg->u32_max_value = U32_MAX;
6895- reg->var_off = tnum_unknown;
6896- }
6897-
68986879static void coerce_reg_to_size_sx(struct bpf_reg_state *reg, int size)
68996880{
6900- s64 init_s64_max, init_s64_min, s64_max, s64_min, u64_cval;
6901- u64 top_smax_value, top_smin_value;
6902- u64 num_bits = size * 8;
6881+ s64 smin_value, smax_value;
69036882
6904- if (tnum_is_const(reg->var_off)) {
6905- u64_cval = reg->var_off.value;
6906- if (size == 1)
6907- reg->var_off = tnum_const((s8)u64_cval);
6908- else if (size == 2)
6909- reg->var_off = tnum_const((s16)u64_cval);
6910- else
6911- /* size == 4 */
6912- reg->var_off = tnum_const((s32)u64_cval);
6913-
6914- u64_cval = reg->var_off.value;
6915- reg->smax_value = reg->smin_value = u64_cval;
6916- reg->umax_value = reg->umin_value = u64_cval;
6917- reg->s32_max_value = reg->s32_min_value = u64_cval;
6918- reg->u32_max_value = reg->u32_min_value = u64_cval;
6883+ if (size >= 8)
69196884 return;
6920- }
69216885
6922- top_smax_value = ((u64)reg->smax_value >> num_bits) << num_bits;
6923- top_smin_value = ((u64)reg->smin_value >> num_bits) << num_bits;
6886+ reg->var_off = tnum_scast(reg->var_off, size);
69246887
6925- if (top_smax_value != top_smin_value)
6926- goto out ;
6888+ smin_value = -(1LL << (size * 8 - 1));
6889+ smax_value = (1LL << (size * 8 - 1)) - 1 ;
69276890
6928- /* find the s64_min and s64_min after sign extension */
6929- if (size == 1) {
6930- init_s64_max = (s8)reg->smax_value;
6931- init_s64_min = (s8)reg->smin_value;
6932- } else if (size == 2) {
6933- init_s64_max = (s16)reg->smax_value;
6934- init_s64_min = (s16)reg->smin_value;
6935- } else {
6936- init_s64_max = (s32)reg->smax_value;
6937- init_s64_min = (s32)reg->smin_value;
6938- }
6939-
6940- s64_max = max(init_s64_max, init_s64_min);
6941- s64_min = min(init_s64_max, init_s64_min);
6891+ reg->smin_value = smin_value;
6892+ reg->smax_value = smax_value;
69426893
6943- /* both of s64_max/s64_min positive or negative */
6944- if ((s64_max >= 0) == (s64_min >= 0)) {
6945- reg->s32_min_value = reg->smin_value = s64_min;
6946- reg->s32_max_value = reg->smax_value = s64_max;
6947- reg->u32_min_value = reg->umin_value = s64_min;
6948- reg->u32_max_value = reg->umax_value = s64_max;
6949- reg->var_off = tnum_range(s64_min, s64_max);
6950- return;
6951- }
6894+ reg->s32_min_value = (s32)smin_value;
6895+ reg->s32_max_value = (s32)smax_value;
69526896
6953- out:
6954- set_sext64_default_val(reg, size);
6955- }
6956-
6957- static void set_sext32_default_val(struct bpf_reg_state *reg, int size)
6958- {
6959- if (size == 1) {
6960- reg->s32_min_value = S8_MIN;
6961- reg->s32_max_value = S8_MAX;
6962- } else {
6963- /* size == 2 */
6964- reg->s32_min_value = S16_MIN;
6965- reg->s32_max_value = S16_MAX;
6966- }
6897+ reg->umin_value = 0;
6898+ reg->umax_value = U64_MAX;
69676899 reg->u32_min_value = 0;
69686900 reg->u32_max_value = U32_MAX;
6969- reg->var_off = tnum_subreg(tnum_unknown);
6901+
6902+ __update_reg_bounds(reg);
69706903}
69716904
69726905static void coerce_subreg_to_size_sx(struct bpf_reg_state *reg, int size)
69736906{
6974- s32 init_s32_max, init_s32_min, s32_max, s32_min, u32_val;
6975- u32 top_smax_value, top_smin_value;
6976- u32 num_bits = size * 8;
6977-
6978- if (tnum_is_const(reg->var_off)) {
6979- u32_val = reg->var_off.value;
6980- if (size == 1)
6981- reg->var_off = tnum_const((s8)u32_val);
6982- else
6983- reg->var_off = tnum_const((s16)u32_val);
6907+ s32 smin_value, smax_value;
69846908
6985- u32_val = reg->var_off.value;
6986- reg->s32_min_value = reg->s32_max_value = u32_val;
6987- reg->u32_min_value = reg->u32_max_value = u32_val;
6909+ if (size >= 4)
69886910 return;
6989- }
69906911
6991- top_smax_value = ((u32)reg->s32_max_value >> num_bits) << num_bits;
6992- top_smin_value = ((u32)reg->s32_min_value >> num_bits) << num_bits;
6912+ reg->var_off = tnum_subreg(tnum_scast(reg->var_off, size));
69936913
6994- if (top_smax_value != top_smin_value)
6995- goto out ;
6914+ smin_value = -(1 << (size * 8 - 1));
6915+ smax_value = (1 << (size * 8 - 1)) - 1 ;
69966916
6997- /* find the s32_min and s32_min after sign extension */
6998- if (size == 1) {
6999- init_s32_max = (s8)reg->s32_max_value;
7000- init_s32_min = (s8)reg->s32_min_value;
7001- } else {
7002- /* size == 2 */
7003- init_s32_max = (s16)reg->s32_max_value;
7004- init_s32_min = (s16)reg->s32_min_value;
7005- }
7006- s32_max = max(init_s32_max, init_s32_min);
7007- s32_min = min(init_s32_max, init_s32_min);
7008-
7009- if ((s32_min >= 0) == (s32_max >= 0)) {
7010- reg->s32_min_value = s32_min;
7011- reg->s32_max_value = s32_max;
7012- reg->u32_min_value = (u32)s32_min;
7013- reg->u32_max_value = (u32)s32_max;
7014- reg->var_off = tnum_subreg(tnum_range(s32_min, s32_max));
7015- return;
7016- }
6917+ reg->s32_min_value = smin_value;
6918+ reg->s32_max_value = smax_value;
70176919
7018- out:
7019- set_sext32_default_val(reg, size);
6920+ reg->u32_min_value = 0;
6921+ reg->u32_max_value = U32_MAX;
6922+
6923+ __update_reg32_bounds(reg);
6924+
6925+ reg->umin_value = reg->u32_min_value;
6926+ reg->umax_value = reg->u32_max_value;
6927+
6928+ reg->smin_value = reg->umin_value;
6929+ reg->smax_value = reg->umax_value;
70206930}
70216931
70226932static bool bpf_map_is_rdonly(const struct bpf_map *map)
0 commit comments