On Sat, 2025-02-01 at 12:58 -0700, Daniel Xu wrote: > Previously, we were trying to extract constant map keys for all > bpf_map_lookup_elem(), regardless of map type. This is an issue if the > map has a u64 key and the value is very high, as it can be interpreted > as a negative signed value. This in turn is treated as an error value by > check_func_arg() which causes a valid program to be incorrectly > rejected. > > Fix by only extracting constant map keys for relevant maps. See next > commit for an example via selftest. > > Reported-by: Marc Hartmayer <mhartmay@xxxxxxxxxxxxx> > Reported-by: Ilya Leoshkevich <iii@xxxxxxxxxxxxx> > Tested-by: Marc Hartmayer <mhartmay@xxxxxxxxxxxxx> > Signed-off-by: Daniel Xu <dxu@xxxxxxxxx> Acked-by: Eduard Zingerman <eddyz87@xxxxxxxxx> Nit: would be good if commit message said something along the lines: ... the fix works because nullness elision is only allowed for {PERCPU_}ARRAY maps, and keys for these are within u32 range ... > --- > kernel/bpf/verifier.c | 10 +++++++--- > 1 file changed, 7 insertions(+), 3 deletions(-) > > diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c > index 9971c03adfd5..e9176a5ce215 100644 > --- a/kernel/bpf/verifier.c > +++ b/kernel/bpf/verifier.c > @@ -9206,6 +9206,8 @@ static s64 get_constant_map_key(struct bpf_verifier_env *env, > return reg->var_off.value; > } > > +static bool can_elide_value_nullness(enum bpf_map_type type); > + > static int check_func_arg(struct bpf_verifier_env *env, u32 arg, > struct bpf_call_arg_meta *meta, > const struct bpf_func_proto *fn, > @@ -9354,9 +9356,11 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg, > err = check_helper_mem_access(env, regno, key_size, BPF_READ, false, NULL); > if (err) > return err; > - meta->const_map_key = get_constant_map_key(env, reg, key_size); > - if (meta->const_map_key < 0 && meta->const_map_key != -EOPNOTSUPP) > - return meta->const_map_key; > + if (can_elide_value_nullness(meta->map_ptr->map_type)) { > + meta->const_map_key = get_constant_map_key(env, reg, key_size); > + if (meta->const_map_key < 0 && meta->const_map_key != -EOPNOTSUPP) > + return meta->const_map_key; > + } > break; > case ARG_PTR_TO_MAP_VALUE: > if (type_may_be_null(arg_type) && register_is_null(reg))