summaryrefslogtreecommitdiff
path: root/kernel/bpf
diff options
context:
space:
mode:
authorNuoqi Gui <gnq25@mails.tsinghua.edu.cn>2026-06-07 21:24:13 +0800
committerKumar Kartikeya Dwivedi <memxor@gmail.com>2026-06-08 13:32:52 +0200
commit53040a81ae57cdca8af8ac36fe4e661730cf7c6b (patch)
treef3f92cb0731f565923b00a940f83132c79a815e0 /kernel/bpf
parent71385b78dbc290328e3b04ebd9b27786642afaca (diff)
bpf: Keep dynamic inner array lookups nullable
An ARRAY_OF_MAPS can use an array created with BPF_F_INNER_MAP as its inner map template. A concrete inner array with a different max_entries value can then replace the template. After a successful outer map lookup, the verifier represents the resulting map pointer using the inner map template. Const-key lookup nullness elision consequently uses the template max_entries even though the runtime helper uses the concrete inner map max_entries. Do not elide lookup result nullness for maps marked with BPF_F_INNER_MAP, because the template max_entries does not prove that the key is in bounds for the concrete runtime map. Fixes: d2102f2f5d75 ("bpf: verifier: Support eliding map lookup nullness") Signed-off-by: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn> Acked-by: Eduard Zingerman <eddyz87@gmail.com> Acked-by: Jiri Olsa <jolsa@kernel.org> Cc: stable@vger.kernel.org Link: https://lore.kernel.org/bpf/20260607-f01-v2-v2-1-da48453146e8@mails.tsinghua.edu.cn Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Diffstat (limited to 'kernel/bpf')
-rw-r--r--kernel/bpf/verifier.c15
1 files changed, 9 insertions, 6 deletions
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 0c1cf506c219..ed7ba0e6a9ce 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -8179,7 +8179,7 @@ static int get_constant_map_key(struct bpf_verifier_env *env,
return 0;
}
-static bool can_elide_value_nullness(enum bpf_map_type type);
+static bool can_elide_value_nullness(const struct bpf_map *map);
static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
struct bpf_call_arg_meta *meta,
@@ -8298,7 +8298,7 @@ skip_type_check:
err = check_helper_mem_access(env, reg, argno_from_reg(regno), key_size, BPF_READ, false, NULL);
if (err)
return err;
- if (can_elide_value_nullness(meta->map.ptr->map_type)) {
+ if (can_elide_value_nullness(meta->map.ptr)) {
err = get_constant_map_key(env, reg, key_size, &meta->const_map_key);
if (err < 0) {
meta->const_map_key = -1;
@@ -10068,13 +10068,16 @@ static void update_loop_inline_state(struct bpf_verifier_env *env, u32 subprogno
state->callback_subprogno == subprogno);
}
-/* Returns whether or not the given map type can potentially elide
+/* Returns whether or not the given map can potentially elide
* lookup return value nullness check. This is possible if the key
* is statically known.
*/
-static bool can_elide_value_nullness(enum bpf_map_type type)
+static bool can_elide_value_nullness(const struct bpf_map *map)
{
- switch (type) {
+ if (map->map_flags & BPF_F_INNER_MAP)
+ return false;
+
+ switch (map->map_type) {
case BPF_MAP_TYPE_ARRAY:
case BPF_MAP_TYPE_PERCPU_ARRAY:
return true;
@@ -10414,7 +10417,7 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
}
if (func_id == BPF_FUNC_map_lookup_elem &&
- can_elide_value_nullness(meta.map.ptr->map_type) &&
+ can_elide_value_nullness(meta.map.ptr) &&
meta.const_map_key >= 0 &&
meta.const_map_key < meta.map.ptr->max_entries)
ret_flag &= ~PTR_MAYBE_NULL;