diff options
| author | Andrii Nakryiko <andrii@kernel.org> | 2026-07-01 11:27:37 -0700 |
|---|---|---|
| committer | Andrii Nakryiko <andrii@kernel.org> | 2026-07-01 11:27:38 -0700 |
| commit | 09e7d46e33dd95803c3105eaba0e6de02dd1713e (patch) | |
| tree | be1005a67a053b20f512863c47f661e4dafa408f /include/uapi | |
| parent | f29997a6d920cdfa2c43995e17c596c599ff261b (diff) | |
| parent | 163944262f8646bf3a1eec557b6aff1f38582a9f (diff) | |
| download | linux-next-09e7d46e33dd95803c3105eaba0e6de02dd1713e.tar.gz linux-next-09e7d46e33dd95803c3105eaba0e6de02dd1713e.zip | |
Merge branch 'bpf-copy-per-cpu-map-value-padding-in-copy_map_value_long'
Leon Hwang says:
====================
bpf: Copy per-CPU map value padding in copy_map_value_long()
Sashiko reported [1]:
This is a pre-existing issue, but does iterating over per-CPU maps expose
uninitialized kernel heap memory?
When working with per-CPU maps, temporary buffers are allocated using kmalloc
without the __GFP_ZERO flag in functions like bpf_iter_init_array_map in
kernel/bpf/arraymap.c:
kernel/bpf/arraymap.c:bpf_iter_init_array_map() {
...
value_buf = kmalloc(buf_size, GFP_USER | __GFP_NOWARN);
...
}
This is also done in kernel/bpf/hashtab.c:bpf_iter_init_hash_map().
If the map contains a BTF record, bpf_obj_memcpy in include/linux/bpf.h
explicitly stops at map->value_size instead of filling the entire rounded-up
size:
include/linux/bpf.h:bpf_obj_memcpy() {
...
memcpy(dst + curr_off, src + curr_off, size - curr_off);
...
}
This fails to overwrite the padding bytes up to round_up(map->value_size, 8).
[1] https://lore.kernel.org/bpf/20260622150844.28C551F000E9@smtp.kernel.org/
===
For example,
struct map_uninit_value {
struct prog_test_ref_kfunc __kptr_untrusted *unref_ptr;
__u32 data;
} __attribute__((packed));
struct {
__uint(type, BPF_MAP_TYPE_PERCPU_ARRAY);
__type(key, int);
__type(value, struct map_uninit_value);
__uint(max_entries, 1);
} pcpu_array SEC(".maps");
There are 4 padding bytes in the kernel percpu_array map elements.
When lookup element from 'pcpu_array' map, for each CPU, the 4 padding
bytes memory allocated by syscall.c::map_lookup_elem():kvmalloc() could
be exposed to user space.
Without the fix, the selftest could fail with:
test_map_uninit_mem_exposure:FAIL:zeroed tail bytes unexpected memory
mismatch
actual:
2B 2B 2B 2B
expected:
00 00 00 00
====================
Link: https://patch.msgid.link/20260624155115.85196-1-leon.hwang@linux.dev
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Diffstat (limited to 'include/uapi')
0 files changed, 0 insertions, 0 deletions
