linux/kernel/bpf
Kumar Kartikeya Dwivedi 1df97a7453 bpf: Register dtor for freeing special fields
There is a race window where BPF hash map elements can leak special
fields if the program with access to the map value recreates these
special fields between the check_and_free_fields done on the map value
and its eventual return to the memory allocator.

Several ways were explored prior to this patch, most notably [0] tried
to use a poison value to reject attempts to recreate special fields for
map values that have been logically deleted but still accessible to BPF
programs (either while sitting in the free list or when reused). While
this approach works well for task work, timers, wq, etc., it is harder
to apply the idea to kptrs, which have a similar race and failure mode.

Instead, we change bpf_mem_alloc to allow registering destructor for
allocated elements, such that when they are returned to the allocator,
any special fields created while they were accessible to programs in the
mean time will be freed. If these values get reused, we do not free the
fields again before handing the element back. The special fields thus
may remain initialized while the map value sits in a free list.

When bpf_mem_alloc is retired in the future, a similar concept can be
introduced to kmalloc_nolock-backed kmem_cache, paired with the existing
idea of a constructor.

Note that the destructor registration happens in map_check_btf, after
the BTF record is populated and (at that point) avaiable for inspection
and duplication. Duplication is necessary since the freeing of embedded
bpf_mem_alloc can be decoupled from actual map lifetime due to logic
introduced to reduce the cost of rcu_barrier()s in mem alloc free path in
9f2c6e96c6 ("bpf: Optimize rcu_barrier usage between hash map and bpf_mem_alloc.").

As such, once all callbacks are done, we must also free the duplicated
record. To remove dependency on the bpf_map itself, also stash the key
size of the map to obtain value from htab_elem long after the map is
gone.

  [0]: https://lore.kernel.org/bpf/20260216131341.1285427-1-mykyta.yatsenko5@gmail.com

Fixes: 14a324f6a6 ("bpf: Wire up freeing of referenced kptr")
Fixes: 1bfbc267ec ("bpf: Enable bpf_timer and bpf_wq in any context")
Reported-by: Alexei Starovoitov <ast@kernel.org>
Tested-by: syzbot@syzkaller.appspotmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260227224806.646888-2-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
2026-02-27 15:39:00 -08:00
..
preload umd: Remove usermode driver framework 2025-07-26 21:03:04 +02:00
arena.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
arraymap.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
bloom_filter.c bpf: Check bloom filter map value size 2024-03-27 09:56:17 -07:00
bpf_cgrp_storage.c bpf: Switch to bpf_selem_unlink_nofail in bpf_local_storage_{map_free, destroy} 2026-02-06 14:47:59 -08:00
bpf_inode_storage.c bpf: Switch to bpf_selem_unlink_nofail in bpf_local_storage_{map_free, destroy} 2026-02-06 14:47:59 -08:00
bpf_insn_array.c bpf: Return EACCES for incorrect access to insn array 2026-01-13 19:36:18 -08:00
bpf_iter.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
bpf_local_storage.c bpf: Switch to bpf_selem_unlink_nofail in bpf_local_storage_{map_free, destroy} 2026-02-06 14:47:59 -08:00
bpf_lru_list.c bpf: Replace get_next_cpu() with cpumask_next_wrap() 2025-08-18 15:11:02 +02:00
bpf_lru_list.h bpf: Adjust free target to avoid global starvation of LRU map 2025-06-18 18:50:14 -07:00
bpf_lsm.c bpf: annotate file argument as __nullable in bpf_lsm_mmap_file 2025-12-21 10:56:33 -08:00
bpf_lsm_proto.c bpf: annotate file argument as __nullable in bpf_lsm_mmap_file 2025-12-21 10:56:33 -08:00
bpf_struct_ops.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
bpf_task_storage.c bpf: Switch to bpf_selem_unlink_nofail in bpf_local_storage_{map_free, destroy} 2026-02-06 14:47:59 -08:00
btf.c Convert 'alloc_flex' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
btf_iter.c bpf: Remove custom build rule 2024-08-30 08:55:26 -07:00
btf_relocate.c bpf: Remove custom build rule 2024-08-30 08:55:26 -07:00
cgroup.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
cgroup_iter.c bpf: add new BPF_CGROUP_ITER_CHILDREN control option 2026-01-27 09:05:54 -08:00
core.c Convert more 'alloc_obj' cases to default GFP_KERNEL arguments 2026-02-21 20:03:00 -08:00
cpumap.c bpf: cpumap: propagate underlying error in cpu_map_update_elem() 2025-12-09 23:53:27 -08:00
cpumask.c bpf: Remove redundant KF_TRUSTED_ARGS flag from all kfuncs 2026-01-02 12:04:28 -08:00
crypto.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
devmap.c bpf: Fix stack-out-of-bounds write in devmap 2026-02-26 11:25:53 -08:00
disasm.c bpf: disasm: add support for BPF_JMP|BPF_JA|BPF_X 2025-11-05 17:53:23 -08:00
disasm.h
dispatcher.c bpf: Add kernel symbol for struct_ops trampoline 2024-11-12 17:13:46 -08:00
dmabuf_iter.c bpf: Fix truncated dmabuf iterator reads 2025-12-09 23:48:34 -08:00
hashtab.c bpf: Register dtor for freeing special fields 2026-02-27 15:39:00 -08:00
helpers.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
inode.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
Kconfig bpf: Update the bpf_prog_calc_tag to use SHA256 2025-09-18 19:10:20 -07:00
kmem_cache_iter.c bpf: Add open coded version of kmem_cache iterator 2024-11-01 11:08:32 -07:00
link_iter.c bpf: Clean up individual BTF_ID code 2025-07-16 18:34:42 -07:00
liveness.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
local_storage.c bpf: Add BPF_F_CPU and BPF_F_ALL_CPUS flags support for percpu_cgroup_storage maps 2026-01-06 20:48:32 -08:00
log.c bpf, x86: add support for indirect jumps 2025-11-05 17:53:23 -08:00
lpm_trie.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
Makefile bpf: annotate file argument as __nullable in bpf_lsm_mmap_file 2025-12-21 10:56:33 -08:00
map_in_map.c bpf: switch maps to CLASS(fd, ...) 2024-08-13 15:58:17 -07:00
map_in_map.h bpf: Add map and need_defer parameters to .map_fd_put_ptr() 2023-12-04 17:50:26 -08:00
map_iter.c bpf: Remove redundant KF_TRUSTED_ARGS flag from all kfuncs 2026-01-02 12:04:28 -08:00
memalloc.c bpf: Register dtor for freeing special fields 2026-02-27 15:39:00 -08:00
mmap_unlock_work.h
mprog.c bpf: Handle bpf_mprog_query with NULL entry 2023-10-06 17:11:20 -07:00
net_namespace.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
offload.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
percpu_freelist.c bpf: Convert percpu_freelist.c to rqspinlock 2025-03-19 08:03:05 -07:00
percpu_freelist.h bpf: Convert percpu_freelist.c to rqspinlock 2025-03-19 08:03:05 -07:00
prog_iter.c bpf: Clean up individual BTF_ID code 2025-07-16 18:34:42 -07:00
queue_stack_maps.c bpf: Convert queue_stack map to rqspinlock 2025-04-10 12:51:10 -07:00
range_tree.c bpf: arena: Reintroduce memcg accounting 2026-01-02 14:31:59 -08:00
range_tree.h bpf: Introduce range_tree data structure and use it in bpf arena 2024-11-13 13:52:45 -08:00
relo_core.c bpf: Remove custom build rule 2024-08-30 08:55:26 -07:00
reuseport_array.c bpf: Use sockfd_put() helper 2024-08-30 08:57:47 -07:00
ringbuf.c bpf: Add SPDX license identifiers to a few files 2026-01-16 14:50:00 -08:00
rqspinlock.c mm.git review status for linus..mm-nonmm-stable 2026-02-12 12:13:01 -08:00
rqspinlock.h rqspinlock: Protect waiters in queue from stalls 2025-03-19 08:03:05 -07:00
stackmap.c bpf-next-6.19 2025-12-03 16:54:54 -08:00
stream.c bpf: Add bpf_stream_print_stack stack dumping kfunc 2026-02-03 10:41:16 -08:00
syscall.c Convert remaining multi-line kmalloc_obj/flex GFP_KERNEL uses 2026-02-22 08:26:33 -08:00
sysfs_btf.c Driver core changes for 6.17-rc1 2025-07-29 12:15:39 -07:00
task_iter.c vfs-6.13.file 2024-11-18 10:30:29 -08:00
tcx.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
tnum.c bpf: Add bitwise tracking for BPF_END 2026-02-04 13:22:39 -08:00
token.c treewide: Replace kmalloc with kmalloc_obj for non-scalar types 2026-02-21 01:02:28 -08:00
trampoline.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00
verifier.c Convert 'alloc_obj' family to use the new default GFP_KERNEL argument 2026-02-21 17:09:51 -08:00