BPF List
 help / color / mirror / Atom feed
* [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