]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
bpf: Ensure RCU lock is held around bpf_prog_ksym_find
authorKumar Kartikeya Dwivedi <memxor@gmail.com>
Thu, 3 Jul 2025 20:48:10 +0000 (13:48 -0700)
committerAlexei Starovoitov <ast@kernel.org>
Fri, 4 Jul 2025 02:30:06 +0000 (19:30 -0700)
Add a warning to ensure RCU lock is held around tree lookup, and then
fix one of the invocations in bpf_stack_walker. The program has an
active stack frame and won't disappear. Use the opportunity to remove
unneeded invocation of is_bpf_text_address.

Fixes: f18b03fabaa9 ("bpf: Implement BPF exceptions")
Reviewed-by: Emil Tsalapatis <emil@etsalapatis.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20250703204818.925464-5-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
kernel/bpf/core.c
kernel/bpf/helpers.c

index 2dc5b846ae501d0729ab5007d4799b1e16665b85..833442661742e49069fbaa882d57518035549a93 100644 (file)
@@ -782,7 +782,10 @@ bool is_bpf_text_address(unsigned long addr)
 
 struct bpf_prog *bpf_prog_ksym_find(unsigned long addr)
 {
-       struct bpf_ksym *ksym = bpf_ksym_find(addr);
+       struct bpf_ksym *ksym;
+
+       WARN_ON_ONCE(!rcu_read_lock_held());
+       ksym = bpf_ksym_find(addr);
 
        return ksym && ksym->prog ?
               container_of(ksym, struct bpf_prog_aux, ksym)->prog :
index 6bfcbcdf6588cd345ed4fc27910d3ebf907dcc22..3d33181d5e677571941d4ab1161fab30ee85cb49 100644 (file)
@@ -2981,9 +2981,16 @@ static bool bpf_stack_walker(void *cookie, u64 ip, u64 sp, u64 bp)
        struct bpf_throw_ctx *ctx = cookie;
        struct bpf_prog *prog;
 
-       if (!is_bpf_text_address(ip))
-               return !ctx->cnt;
+       /*
+        * The RCU read lock is held to safely traverse the latch tree, but we
+        * don't need its protection when accessing the prog, since it has an
+        * active stack frame on the current stack trace, and won't disappear.
+        */
+       rcu_read_lock();
        prog = bpf_prog_ksym_find(ip);
+       rcu_read_unlock();
+       if (!prog)
+               return !ctx->cnt;
        ctx->cnt++;
        if (bpf_is_subprog(prog))
                return true;