mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
synced 2026-07-22 02:17:36 -04:00
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: d2102f2f5d ("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>
This commit is contained in:
committed by
Kumar Kartikeya Dwivedi
parent
71385b78db
commit
53040a81ae
@@ -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 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
|
||||
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;
|
||||
|
||||
Reference in New Issue
Block a user