]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
selftests/bpf: Exercise unsafe obj drops from tracing progs
authorKumar Kartikeya Dwivedi <memxor@gmail.com>
Tue, 9 Jun 2026 20:25:45 +0000 (22:25 +0200)
committerAlexei Starovoitov <ast@kernel.org>
Wed, 10 Jun 2026 04:23:11 +0000 (21:23 -0700)
Add task_kfunc failure cases for bpf_obj_drop() on local objects with
referenced kptr fields from tracing and NMI tracing programs. These programs
must be rejected because dropping the object would run full special-field
destruction synchronously in an unsafe context.

Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260609202548.3571690-4-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
tools/testing/selftests/bpf/progs/task_kfunc_failure.c

index 8e947d445f8e889ae018fbfabe7bfeaf548d5443..8942b547812917c26827511a21a38d70b73559a3 100644 (file)
@@ -5,6 +5,7 @@
 #include <bpf/bpf_tracing.h>
 #include <bpf/bpf_helpers.h>
 
+#include "../bpf_experimental.h"
 #include "bpf_misc.h"
 #include "task_kfunc_common.h"
 
@@ -233,6 +234,45 @@ int BPF_PROG(task_kfunc_release_unacquired, struct task_struct *task, u64 clone_
        return 0;
 }
 
+SEC("tp_btf/task_newtask")
+__failure __msg("bpf_obj_drop cannot be used in tracing programs on types with NMI unsafe fields")
+int BPF_PROG(task_kfunc_obj_drop_with_kptr, struct task_struct *task, u64 clone_flags)
+{
+       struct __tasks_kfunc_map_value *local;
+
+       local = bpf_obj_new(typeof(*local));
+       if (!local)
+               return 0;
+
+       bpf_obj_drop(local);
+       return 0;
+}
+
+SEC("tp_btf/task_newtask")
+__failure __msg("bpf_obj_drop cannot be used in tracing programs on types with NMI unsafe fields")
+int BPF_PROG(task_kfunc_obj_drop_nmi_with_kptr, struct task_struct *task,
+            u64 clone_flags)
+{
+       struct __tasks_kfunc_map_value *local;
+       struct task_struct *acquired, *old;
+
+       (void)clone_flags;
+
+       local = bpf_obj_new(typeof(*local));
+       if (!local)
+               return 0;
+
+       acquired = bpf_task_acquire(task);
+       if (acquired) {
+               old = bpf_kptr_xchg(&local->task, acquired);
+               if (old)
+                       bpf_task_release(old);
+       }
+
+       bpf_obj_drop(local);
+       return 0;
+}
+
 SEC("tp_btf/task_newtask")
 __failure __msg("Possibly NULL pointer passed to trusted R1")
 int BPF_PROG(task_kfunc_from_pid_no_null_check, struct task_struct *task, u64 clone_flags)