diff options
| author | Yuan Chen <chenyuan@kylinos.cn> | 2026-09-28 17:11:21 +0800 |
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2026-10-03 08:30:19 +0000 |
| commit | 5ec398d9ec8fe13f8058af9a2e5f5e8f46e0a35a (patch) | |
| tree | 946f18a4bc37bbb9e19890d0e62c64a8fb46d885 /kernel | |
| parent | 2b5440b31cafad2fb4b4a83efb780a6d7430a385 (diff) | |
bpf: Roll back freplace link state when bpf_arch_text_poke() fails
A freplace attach claims the target prog by bumping
tgt_prog->aux->freplace_link_cnt and setting tr->extension_prog.
bpf_arch_text_poke() then makes the extension take effect. If the
poke fails, the claims are never released: the attach unwinds
through bpf_link_cleanup(), which clears link->prog, so
bpf_trampoline_unlink_prog() never runs.
Drop the link count under ext_mutex on the error path, and set
tr->extension_prog only after the poke succeeded. The count is
still bumped before the poke: it blocks prog_array updates while
the entry is patched.
Fixes: d6083f040d5d ("bpf: Prevent tailcall infinite loop caused by freplace")
Fixes: be8704ff07d2 ("bpf: Introduce dynamic program extensions")
Suggested-by: Leon Hwang <leon.hwang@linux.dev>
Signed-off-by: Yuan Chen <chenyuan@kylinos.cn>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Acked-by: Leon Hwang <leon.hwang@linux.dev>
Link: https://patch.msgid.link/20260928091121.219333-1-chenyuan_fl@163.com
Diffstat (limited to 'kernel')
| -rw-r--r-- | kernel/bpf/trampoline.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/kernel/bpf/trampoline.c b/kernel/bpf/trampoline.c index d880ad6913b3..fc94d6062109 100644 --- a/kernel/bpf/trampoline.c +++ b/kernel/bpf/trampoline.c @@ -1026,10 +1026,17 @@ static int __bpf_trampoline_link_prog(struct bpf_tramp_node *node, err = bpf_freplace_link_tgt_prog(tgt_prog); if (err) return err; + err = bpf_arch_text_poke(tr->func.addr, BPF_MOD_NOP, + BPF_MOD_JUMP, NULL, + node->link->prog->bpf_func); + if (err) { + /* Undo the claim from bpf_freplace_link_tgt_prog(). */ + guard(mutex)(&tgt_prog->aux->ext_mutex); + tgt_prog->aux->freplace_link_cnt--; + return err; + } tr->extension_prog = node->link->prog; - return bpf_arch_text_poke(tr->func.addr, BPF_MOD_NOP, - BPF_MOD_JUMP, NULL, - node->link->prog->bpf_func); + return 0; } err = bpf_trampoline_add_prog(tr, node, cnt); if (err) |
