* [PATCH] bpf: Reject offloaded maps as map-in-map inner maps
@ 2026-11-12 10:56 Shihuang Liu
2026-11-12 11:31 ` bot+bpf-ci
0 siblings, 1 reply; 2+ messages in thread
From: Shihuang Liu @ 2026-11-12 10:56 UTC (permalink / raw)
To: bpf
Cc: netdev, linux-kernel, Alexei Starovoitov, Daniel Borkmann,
Andrii Nakryiko, Eduard Zingerman, Kumar Kartikeya Dwivedi,
Martin KaFai Lau, Song Liu, Yonghong Song, Jiri Olsa,
Emil Tsalapatis, Ihor Solodrai, Jakub Kicinski, Quentin Monnet,
Shihuang Liu
bpf_map_update_elem() on an ARRAY_OF_MAPS or HASH_OF_MAPS map accepts
the fd of an offloaded map. A program that then looks up the inner map
gets a pointer computed with the software map layout: with an ARRAY
template the write lands in struct bpf_offloaded_map.dev_priv, with a
HASH template __htab_map_lookup_elem() reads bpf_htab fields past the
320-byte offloaded map allocation (KASAN slab-out-of-bounds). An
offloaded map used as inner_map_fd is accepted as well, and the first
inner lookup jumps to an invalid address because bpf_map_offload_ops
has no map_lookup_elem.
The root cause is that bpf_map_meta_equal() compares map_type,
key_size, value_size, map_flags and the btf record only, and
bpf_map_fd_get_ptr() relies on the template's map_meta_equal() without
comparing ops. Offloaded maps share map_type (ARRAY/HASH) with the
software maps, but use bpf_map_offload_ops and a different object
layout, while the verifier and the JIT keep using the template's ops
and layout.
Reject offloaded maps in bpf_map_meta_alloc() so they cannot be an
inner-map template, and require inner_map_meta->ops == inner_map->ops
in bpf_map_fd_get_ptr().
Fixes: a38845729ea398 ("bpf: offload: add map offload infrastructure")
Signed-off-by: Shihuang Liu <shlomojune6@gmail.com>
---
kernel/bpf/map_in_map.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/kernel/bpf/map_in_map.c b/kernel/bpf/map_in_map.c
index 0fa3f2ac0f992f..5aa1f8249feb51 100644
--- a/kernel/bpf/map_in_map.c
+++ b/kernel/bpf/map_in_map.c
@@ -22,6 +22,8 @@ struct bpf_map *bpf_map_meta_alloc(int inner_map_ufd)
return ERR_PTR(-EINVAL);
if (inner_map->excl_prog_sha)
return ERR_PTR(-ENOTSUPP);
+ if (bpf_map_is_offloaded(inner_map))
+ return ERR_PTR(-EOPNOTSUPP);
if (!inner_map->ops->map_meta_equal)
return ERR_PTR(-ENOTSUPP);
@@ -110,7 +112,8 @@ void *bpf_map_fd_get_ptr(struct bpf_map *map,
return ERR_PTR(-ENOTSUPP);
inner_map_meta = map->inner_map_meta;
- if (inner_map_meta->ops->map_meta_equal(inner_map_meta, inner_map)) {
+ if (inner_map_meta->ops == inner_map->ops &&
+ inner_map_meta->ops->map_meta_equal(inner_map_meta, inner_map)) {
bpf_map_inc(inner_map);
/* Its users are those of the outer maps from now on */
WRITE_ONCE(inner_map->was_inner_map, true);
--
2.43.0
^ permalink raw reply [flat|nested] 2+ messages in thread* Re: [PATCH] bpf: Reject offloaded maps as map-in-map inner maps
2026-11-12 10:56 [PATCH] bpf: Reject offloaded maps as map-in-map inner maps Shihuang Liu
@ 2026-11-12 11:31 ` bot+bpf-ci
0 siblings, 0 replies; 2+ messages in thread
From: bot+bpf-ci @ 2026-11-12 11:31 UTC (permalink / raw)
To: shlomojune6, bpf
Cc: netdev, linux-kernel, ast, daniel, andrii, eddyz87, memxor,
martin.lau, song, yonghong.song, jolsa, emil, ihor.solodrai,
kuba, qmo, shlomojune6, ast, andrii, daniel, martin.lau, eddyz87,
yonghong.song, mason, ihor.solodrai
[-- Attachment #1: Type: text/plain, Size: 1442 bytes --]
> bpf: Reject offloaded maps as map-in-map inner maps
TL;DR: Nit only: the comment in bpf_map_meta_equal() saying ops need no
comparison now contradicts the new ops check in bpf_map_fd_get_ptr(); suggests
updating it or moving the check there.
> diff --git a/kernel/bpf/map_in_map.c b/kernel/bpf/map_in_map.c
> --- a/kernel/bpf/map_in_map.c
> +++ b/kernel/bpf/map_in_map.c
[ ... ]
> @@ -110,7 +112,8 @@ void *bpf_map_fd_get_ptr(struct bpf_map *map,
> return ERR_PTR(-ENOTSUPP);
>
> inner_map_meta = map->inner_map_meta;
> - if (inner_map_meta->ops->map_meta_equal(inner_map_meta, inner_map)) {
> + if (inner_map_meta->ops == inner_map->ops &&
> + inner_map_meta->ops->map_meta_equal(inner_map_meta, inner_map)) {
This isn't a bug, but the comment in bpf_map_meta_equal() still says:
/* No need to compare ops because it is covered by map_type */
Offloaded maps share map_type with software maps but use
bpf_map_offload_ops, so that comment now contradicts the new ops check
here. Could it be updated or dropped?
Another option is to move the ops comparison into bpf_map_meta_equal(),
which array_map_meta_equal() and xsk_map_meta_equal() also call, and
replace the comment there.
---
AI reviewed your patch. Please fix the bug or email reply why it's not a bug.
See: https://github.com/kernel-patches/vmtest/blob/master/ci/claude/README.md
CI run summary: https://github.com/kernel-patches/bpf/actions/runs/43208166255
^ permalink raw reply [flat|nested] 2+ messages in thread
end of thread, other threads:[~2026-11-12 11:31 UTC | newest]
Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-12 10:56 [PATCH] bpf: Reject offloaded maps as map-in-map inner maps Shihuang Liu
2026-11-12 11:31 ` bot+bpf-ci
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®