Skip to content

Commit 64e21f9

Browse files
danobiKernel Patches Daemon
authored and
Kernel Patches Daemon
committed
bpf: verifier: Do not extract constant map keys for irrelevant maps
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. This fix works because nullness elision is only allowed for {PERCPU_}ARRAY maps, and keys for these are within u32 range. See next commit for an example via selftest. Acked-by: Eduard Zingerman <[email protected]> Reported-by: Marc Hartmayer <[email protected]> Reported-by: Ilya Leoshkevich <[email protected]> Tested-by: Marc Hartmayer <[email protected]> Signed-off-by: Daniel Xu <[email protected]>
1 parent 1a4be3f commit 64e21f9

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

kernel/bpf/verifier.c

+7-3
Original file line numberDiff line numberDiff line change
@@ -9206,6 +9206,8 @@ static s64 get_constant_map_key(struct bpf_verifier_env *env,
92069206
return reg->var_off.value;
92079207
}
92089208

9209+
static bool can_elide_value_nullness(enum bpf_map_type type);
9210+
92099211
static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
92109212
struct bpf_call_arg_meta *meta,
92119213
const struct bpf_func_proto *fn,
@@ -9354,9 +9356,11 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
93549356
err = check_helper_mem_access(env, regno, key_size, BPF_READ, false, NULL);
93559357
if (err)
93569358
return err;
9357-
meta->const_map_key = get_constant_map_key(env, reg, key_size);
9358-
if (meta->const_map_key < 0 && meta->const_map_key != -EOPNOTSUPP)
9359-
return meta->const_map_key;
9359+
if (can_elide_value_nullness(meta->map_ptr->map_type)) {
9360+
meta->const_map_key = get_constant_map_key(env, reg, key_size);
9361+
if (meta->const_map_key < 0 && meta->const_map_key != -EOPNOTSUPP)
9362+
return meta->const_map_key;
9363+
}
93609364
break;
93619365
case ARG_PTR_TO_MAP_VALUE:
93629366
if (type_may_be_null(arg_type) && register_is_null(reg))

0 commit comments

Comments
 (0)