From a83512036e0809497ee3259ba7458de287949b94 Mon Sep 17 00:00:00 2001 From: Daniel Borkmann Date: Fri, 25 Sep 2026 19:52:36 +0200 Subject: [PATCH] bpf: Clear the insn array used flag with release semantics A program that fails after the JIT ran, for example in bpf_check_tail_call(), has already stored its jitted offsets and target pointers into the insn array maps it uses through bpf_prog_update_insn_ptrs() when release_insn_arrays() hands them back by clearing the used flag with a plain atomic_set(). Nothing orders those stores before the flag, so on a weakly ordered architecture they can still be in flight when the next program takes the map: it is acquired with atomic_xchg() in bpf_insn_array_init() and reset there, and the late stores then land on top of whatever the new owner has written since, be it that reset or the pointers its own JIT stored, leaving entries that point into an image which is about to be freed. Clear the flag with atomic_set_release() instead, so that everything the releasing program stored is visible before the map can be acquired again. This pairs with the fully ordered atomic_xchg() on the acquire side. Fixes: b4ce5923e780 ("bpf, x86: add new map type: instructions array") Signed-off-by: Daniel Borkmann Signed-off-by: Alexei Starovoitov Link: https://patch.msgid.link/20260925175244.1136329-10-daniel@iogearbox.net --- kernel/bpf/bpf_insn_array.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/kernel/bpf/bpf_insn_array.c b/kernel/bpf/bpf_insn_array.c index 5874abd1f743..61d6a076dfdb 100644 --- a/kernel/bpf/bpf_insn_array.c +++ b/kernel/bpf/bpf_insn_array.c @@ -232,7 +232,8 @@ void bpf_insn_array_release(struct bpf_map *map) { struct bpf_insn_array *insn_array = cast_insn_array(map); - atomic_set(&insn_array->used, 0); + /* Paired with atomic_xchg() in bpf_insn_array_init(). */ + atomic_set_release(&insn_array->used, 0); } void bpf_insn_array_adjust(struct bpf_map *map, u32 off, u32 len)