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 BPF_UPROBE(handle_uprobe_byname2, const char *pathname, const char *mode)
96 {
97 	char mode_buf[2] = {};
98 
99 	/* verify fopen mode */
100 	bpf_probe_read_user(mode_buf, sizeof(mode_buf), mode);
101 	if (mode_buf[0] == 'r' && mode_buf[1] == 0)
102 		uprobe_byname2_res = 7;
103 	return 0;
104 }
105 
106 SEC("uretprobe")
107 int BPF_URETPROBE(handle_uretprobe_byname2, void *ret)
108 {
109 	uretprobe_byname2_res = 8;
110 	return 0;
111 }
112 
113 static __always_inline bool verify_sleepable_user_copy(void)
114 {
115 	char data[9];
116 
117 	bpf_copy_from_user(data, sizeof(data), user_ptr);
118 	return bpf_strncmp(data, sizeof(data), "test_data") == 0;
119 }
120 
121 SEC("uprobe.s//proc/self/exe:trigger_func3")
122 int handle_uprobe_byname3_sleepable(struct pt_regs *ctx)
123 {
124 	if (verify_sleepable_user_copy())
125 		uprobe_byname3_sleepable_res = 9;
126 	return 0;
127 }
128 
129 /**
130  * same target as the uprobe.s above to force sleepable and non-sleepable
131  * programs in the same bpf_prog_array
132  */
133 SEC("uprobe//proc/self/exe:trigger_func3")
134 int handle_uprobe_byname3(struct pt_regs *ctx)
135 {
136 	uprobe_byname3_res = 10;
137 	return 0;
138 }
139 
140 SEC("uretprobe.s//proc/self/exe:trigger_func3")
141 int handle_uretprobe_byname3_sleepable(struct pt_regs *ctx)
142 {
143 	if (verify_sleepable_user_copy())
144 		uretprobe_byname3_sleepable_res = 11;
145 	return 0;
146 }
147 
148 SEC("uretprobe//proc/self/exe:trigger_func3")
149 int handle_uretprobe_byname3(struct pt_regs *ctx)
150 {
151 	uretprobe_byname3_res = 12;
152 	return 0;
153 }
154 
155 
156 char _license[] SEC("license") = "GPL";
157