* [PATCH bpf-next] bpf: Don't echo user-supplied map info fields back to userspace
@ 2026-10-16 16:41 Daniel Borkmann
2026-10-16 17:47 ` Alexei Starovoitov
0 siblings, 1 reply; 3+ messages in thread
From: Daniel Borkmann @ 2026-10-16 16:41 UTC (permalink / raw)
To: alexei.starovoitov; +Cc: bpf, Quentin Monnet, Tianyi Chen, KP Singh
Commit ea2e6467ac36 ("bpf: Return hashes of maps in BPF_OBJ_GET_INFO_BY_FD")
started copying struct bpf_map_info in from userspace in order to read
the new hash and hash_size input fields. Before that, the kernel ignored
the contents of the user buffer and returned a zeroed structure with only
the output fields filled in.
Some output fields are only set for certain maps: btf_id, btf_key_type_id
and btf_value_type_id when the map has BTF (and btf_vmlinux_id for
struct_ops maps, ifindex, netns_dev and netns_ino when the map is
offloaded). For all other maps, these fields now return whatever
userspace passed in before.
This breaks userspace which reuses one bpf_map_info for several queries.
Restore the original behavior by keeping only hash and hash_size from
the user copy and zeroing everything else before the output fields are
filled in.
Fixes: ea2e6467ac36 ("bpf: Return hashes of maps in BPF_OBJ_GET_INFO_BY_FD")
Reported-by: Quentin Monnet <qmo@kernel.org>
Reported-by: Tianyi Chen <hi@tychen.cc>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Cc: KP Singh <kpsingh@kernel.org>
---
kernel/bpf/syscall.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index 654f896af265..0b11ba9837c2 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -5437,8 +5437,9 @@ static int bpf_map_get_info_by_fd(struct file *file,
union bpf_attr __user *uattr)
{
struct bpf_map_info __user *uinfo = u64_to_user_ptr(attr->info.info);
+ u32 info_len = attr->info.info_len, len, hash_size;
struct bpf_map_info info;
- u32 info_len = attr->info.info_len, len;
+ u64 hash;
int err;
len = offsetofend(struct bpf_map_info, hash_size);
@@ -5450,7 +5451,11 @@ static int bpf_map_get_info_by_fd(struct file *file,
memset(&info, 0, sizeof(info));
if (copy_from_user(&info, uinfo, info_len))
return -EFAULT;
-
+ hash = info.hash;
+ hash_size = info.hash_size;
+ memset(&info, 0, sizeof(info));
+ info.hash = hash;
+ info.hash_size = hash_size;
info.type = map->map_type;
info.id = map->id;
info.key_size = map->key_size;
--
2.43.0
^ permalink raw reply related [flat|nested] 3+ messages in thread
* Re: [PATCH bpf-next] bpf: Don't echo user-supplied map info fields back to userspace
2026-10-16 16:41 [PATCH bpf-next] bpf: Don't echo user-supplied map info fields back to userspace Daniel Borkmann
@ 2026-10-16 17:47 ` Alexei Starovoitov
2026-10-16 18:28 ` Daniel Borkmann
0 siblings, 1 reply; 3+ messages in thread
From: Alexei Starovoitov @ 2026-10-16 17:47 UTC (permalink / raw)
To: Daniel Borkmann; +Cc: bpf, Quentin Monnet, Tianyi Chen, KP Singh
On Fri, Oct 16, 2026 at 06:41 PM Daniel Borkmann <daniel@iogearbox.net> wrote:
> @@ -5450,7 +5451,11 @@ static int bpf_map_get_info_by_fd(struct file *file,
> memset(&info, 0, sizeof(info));
> if (copy_from_user(&info, uinfo, info_len))
> return -EFAULT;
> -
> + hash = info.hash;
> + hash_size = info.hash_size;
> + memset(&info, 0, sizeof(info));
> + info.hash = hash;
> + info.hash_size = hash_size;
can we do
memset(&info, 0, offsetof(struct bpf_map_info, hash));
here instead ?
hash and hash_size are the last two fields and the padding after them
is checked by bpf_check_uarg_tail_zero() above.
Then no need for two extra variables and the 2nd full memset.
^ permalink raw reply [flat|nested] 3+ messages in thread
* Re: [PATCH bpf-next] bpf: Don't echo user-supplied map info fields back to userspace
2026-10-16 17:47 ` Alexei Starovoitov
@ 2026-10-16 18:28 ` Daniel Borkmann
0 siblings, 0 replies; 3+ messages in thread
From: Daniel Borkmann @ 2026-10-16 18:28 UTC (permalink / raw)
To: Alexei Starovoitov; +Cc: bpf, Quentin Monnet, Tianyi Chen, KP Singh
On 10/16/26 7:47 PM, Alexei Starovoitov wrote:
> On Fri, Oct 16, 2026 at 06:41 PM Daniel Borkmann <daniel@iogearbox.net> wrote:
>> @@ -5450,7 +5451,11 @@ static int bpf_map_get_info_by_fd(struct file *file,
>> memset(&info, 0, sizeof(info));
>> if (copy_from_user(&info, uinfo, info_len))
>> return -EFAULT;
>> -
>> + hash = info.hash;
>> + hash_size = info.hash_size;
>> + memset(&info, 0, sizeof(info));
>> + info.hash = hash;
>> + info.hash_size = hash_size;
>
> can we do
> memset(&info, 0, offsetof(struct bpf_map_info, hash));
> here instead ?
> hash and hash_size are the last two fields and the padding after them
> is checked by bpf_check_uarg_tail_zero() above.
> Then no need for two extra variables and the 2nd full memset.
Yeap, will check.. or alternatively memset and only copy the two
members into the zeroed struct; will check what looks better and
do a v2.
Thanks,
Daniel
^ permalink raw reply [flat|nested] 3+ messages in thread
end of thread, other threads:[~2026-10-16 18:28 UTC | newest]
Thread overview: 3+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-10-16 16:41 [PATCH bpf-next] bpf: Don't echo user-supplied map info fields back to userspace Daniel Borkmann
2026-10-16 17:47 ` Alexei Starovoitov
2026-10-16 18:28 ` Daniel Borkmann
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox