diff options
| author | Josef Bacik <josef@toxicpanda.com> | 2026-10-17 23:09:39 +0000 |
|---|---|---|
| committer | Alexei Starovoitov <ast@kernel.org> | 2026-10-18 00:36:43 +0000 |
| commit | 4eaf4d71b91a983489227336adcab33d8eae58a5 (patch) | |
| tree | d61fa9e4c9a0fc04fdce120ddbb31264f4089ea4 /include/linux | |
| parent | b6458abbafe4bf4b992d2c5ee06ab529e8428591 (diff) | |
| download | linux-4eaf4d71b91a983489227336adcab33d8eae58a5.tar.gz linux-4eaf4d71b91a983489227336adcab33d8eae58a5.zip | |
bpf: Keep the symbols of a program until it has ended
When the last reference to a program goes, __bpf_prog_put_noref() takes
its symbols out of the kallsyms tree and frees its line info at once, and
waits for the grace periods only with the rest. But the program may still
be running: the link or the array it was called from is gone, the call is
not over.
search_bpf_extables() finds the exception table of a program by its
symbol. A load that faults, and that the table is there to fix up, is
fatal from then on:
Oops: general protection fault, probably for non-canonical address
0xdead0000000006f8: 0000 [#1] SMP NOPTI
RIP: 0010:0xffffffffc06008f6
It takes a program that is detached and closed on one CPU while it runs on
another. Unwinders and bpf_prog_find_from_stack() do not know the program
any more either, and the stack dump of a BPF stream reads the freed line
info.
Free the line info behind the grace periods the program needs, as it is
done with the BTF that its text comes from. Remove the symbols in
bpf_prog_free_deferred(), which runs behind them as well. The symbols are
looked up under rcu_read_lock(), so the images and the program itself are
freed one more grace period later. All that the program refers to is
released when it was before.
Fixes: 3dec541b2e63 ("bpf: Add support for BTF pointers to x86 JIT")
Fixes: d7c431cafcb4 ("bpf: Add dump_stack() analogue to print to BPF stderr")
Signed-off-by: Josef Bacik <josef@toxicpanda.com>
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Link: https://patch.msgid.link/20261017230950.802052-6-alexei.starovoitov@gmail.com
Diffstat (limited to 'include/linux')
| -rw-r--r-- | include/linux/bpf.h | 1 |
1 files changed, 1 insertions, 0 deletions
diff --git a/include/linux/bpf.h b/include/linux/bpf.h index a10af47978a4..feb7de6483e3 100644 --- a/include/linux/bpf.h +++ b/include/linux/bpf.h @@ -1971,6 +1971,7 @@ struct bpf_prog_aux { union { struct work_struct work; struct rcu_head rcu; + struct rcu_work rwork; }; struct bpf_stream *stream[2]; struct mutex st_ops_assoc_mutex; |
