1 #include <vmlinux.h>
2 #include <bpf/bpf_tracing.h>
3 #include "../test_kmods/bpf_testmod.h"
4 #include "bpf_misc.h"
5 
6 char _license[] SEC("license") = "GPL";
7 
8 extern void bpf_task_release(struct task_struct *p) __ksym;
9 
subprog_release(__u64 * ctx __arg_ctx)10 __noinline int subprog_release(__u64 *ctx __arg_ctx)
11 {
12 	struct task_struct *task = (struct task_struct *)ctx[1];
13 	int dummy = (int)ctx[0];
14 
15 	bpf_task_release(task);
16 
17 	return dummy + 1;
18 }
19 
20 /* Test that the verifier rejects a program that contains a global
21  * subprogram with referenced kptr arguments
22  */
23 SEC("struct_ops/test_refcounted")
24 __failure __log_level(2)
25 __msg("Validating subprog_release() func#1...")
26 __msg("invalid bpf_context access off=8. Reference may already be released")
refcounted_fail__global_subprog(unsigned long long * ctx)27 int refcounted_fail__global_subprog(unsigned long long *ctx)
28 {
29 	struct task_struct *task = (struct task_struct *)ctx[1];
30 
31 	bpf_task_release(task);
32 
33 	return subprog_release(ctx);
34 }
35 
36 SEC(".struct_ops.link")
37 struct bpf_testmod_ops testmod_ref_acquire = {
38 	.test_refcounted = (void *)refcounted_fail__global_subprog,
39 };
40