bpf: Don't echo user-supplied map info fields back to userspace

Commit ea2e6467ac ("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 zeroing the structure and copying in
only hash and hash_size from userspace before the output fields are
filled in.

Fixes: ea2e6467ac ("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>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20261016191635.662690-1-daniel@iogearbox.net
This commit is contained in:
Daniel Borkmann 2026-10-16 21:16:35 +02:00 committed by Alexei Starovoitov
parent 645f5fcf7a
commit 458575e1f2
No known key found for this signature in database

View File

@ -5448,7 +5448,11 @@ static int bpf_map_get_info_by_fd(struct file *file,
info_len = min_t(u32, sizeof(info), info_len);
memset(&info, 0, sizeof(info));
if (copy_from_user(&info, uinfo, info_len))
if (info_len >= offsetofend(struct bpf_map_info, hash) &&
get_user(info.hash, &uinfo->hash))
return -EFAULT;
if (info_len >= offsetofend(struct bpf_map_info, hash_size) &&
get_user(info.hash_size, &uinfo->hash_size))
return -EFAULT;
info.type = map->map_type;