1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2017 Facebook
3 
4 #include "vmlinux.h"
5 #include <bpf/bpf_helpers.h>
6 #include <bpf/bpf_tracing.h>
7 #include <bpf/bpf_core_read.h>
8 #include "bpf_misc.h"
9 
10 int kprobe_res = 0;
11 int kprobe2_res = 0;
12 int kretprobe_res = 0;
13 int kretprobe2_res = 0;
14 int uprobe_res = 0;
15 int uretprobe_res = 0;
16 int uprobe_byname_res = 0;
17 int uretprobe_byname_res = 0;
18 int uprobe_byname2_res = 0;
19 int uretprobe_byname2_res = 0;
20 int uprobe_byname3_sleepable_res = 0;
21 int uprobe_byname3_res = 0;
22 int uretprobe_byname3_sleepable_res = 0;
23 int uretprobe_byname3_res = 0;
24 void *user_ptr = 0;
25 
26 SEC("kprobe")
27 int handle_kprobe(struct pt_regs *ctx)
28 {
29 	kprobe_res = 1;
30 	return 0;
31 }
32 
33 SEC("ksyscall/nanosleep")
34 int BPF_KSYSCALL(handle_kprobe_auto, struct __kernel_timespec *req, struct __kernel_timespec *rem)
35 {
36 	kprobe2_res = 11;
37 	return 0;
38 }
39 
40 /**
41  * This program will be manually made sleepable on the userspace side
42  * and should thus be unattachable.
43  */
44 SEC("kprobe/" SYS_PREFIX "sys_nanosleep")
45 int handle_kprobe_sleepable(struct pt_regs *ctx)
46 {
47 	kprobe_res = 2;
48 	return 0;
49 }
50 
51 SEC("kretprobe")
52 int handle_kretprobe(struct pt_regs *ctx)
53 {
54 	kretprobe_res = 2;
55 	return 0;
56 }
57 
58 SEC("kretsyscall/nanosleep")
59 int BPF_KRETPROBE(handle_kretprobe_auto, int ret)
60 {
61 	kretprobe2_res = 22;
62 	return ret;
63 }
64 
65 SEC("uprobe")
66 int handle_uprobe(struct pt_regs *ctx)
67 {
68 	uprobe_res = 3;
69 	return 0;
70 }
71 
72 SEC("uretprobe")
73 int handle_uretprobe(struct pt_regs *ctx)
74 {
75 	uretprobe_res = 4;
76 	return 0;
77 }
78 
79 SEC("uprobe")
80 int handle_uprobe_byname(struct pt_regs *ctx)
81 {
82 	uprobe_byname_res = 5;
83 	return 0;
84 }
85 
86 /* use auto-attach format for section definition. */
87 SEC("uretprobe//proc/self/exe:trigger_func2")
88 int handle_uretprobe_byname(struct pt_regs *ctx)
89 {
90 	uretprobe_byname_res = 6;
91 	return 0;
92 }
93 
94 SEC("uprobe")
95 int handle_uprobe_byname2(struct pt_regs *ctx)
96 {
97 	unsigned int size = PT_REGS_PARM1(ctx);
98 
99 	/* verify malloc size */
100 	if (size == 1)
101 		uprobe_byname2_res = 7;
102 	return 0;
103 }
104 
105 SEC("uretprobe")
106 int handle_uretprobe_byname2(struct pt_regs *ctx)
107 {
108 	uretprobe_byname2_res = 8;
109 	return 0;
110 }
111 
112 static __always_inline bool verify_sleepable_user_copy(void)
113 {
114 	char data[9];
115 
116 	bpf_copy_from_user(data, sizeof(data), user_ptr);
117 	return bpf_strncmp(data, sizeof(data), "test_data") == 0;
118 }
119 
120 SEC("uprobe.s//proc/self/exe:trigger_func3")
121 int handle_uprobe_byname3_sleepable(struct pt_regs *ctx)
122 {
123 	if (verify_sleepable_user_copy())
124 		uprobe_byname3_sleepable_res = 9;
125 	return 0;
126 }
127 
128 /**
129  * same target as the uprobe.s above to force sleepable and non-sleepable
130  * programs in the same bpf_prog_array
131  */
132 SEC("uprobe//proc/self/exe:trigger_func3")
133 int handle_uprobe_byname3(struct pt_regs *ctx)
134 {
135 	uprobe_byname3_res = 10;
136 	return 0;
137 }
138 
139 SEC("uretprobe.s//proc/self/exe:trigger_func3")
140 int handle_uretprobe_byname3_sleepable(struct pt_regs *ctx)
141 {
142 	if (verify_sleepable_user_copy())
143 		uretprobe_byname3_sleepable_res = 11;
144 	return 0;
145 }
146 
147 SEC("uretprobe//proc/self/exe:trigger_func3")
148 int handle_uretprobe_byname3(struct pt_regs *ctx)
149 {
150 	uretprobe_byname3_res = 12;
151 	return 0;
152 }
153 
154 
155 char _license[] SEC("license") = "GPL";
156