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")
handle_kprobe(struct pt_regs * ctx)27 int handle_kprobe(struct pt_regs *ctx)
28 {
29 kprobe_res = 1;
30 return 0;
31 }
32
33 SEC("ksyscall/nanosleep")
BPF_KSYSCALL(handle_kprobe_auto,struct __kernel_timespec * req,struct __kernel_timespec * rem)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")
handle_kprobe_sleepable(struct pt_regs * ctx)45 int handle_kprobe_sleepable(struct pt_regs *ctx)
46 {
47 kprobe_res = 2;
48 return 0;
49 }
50
51 SEC("kretprobe")
handle_kretprobe(struct pt_regs * ctx)52 int handle_kretprobe(struct pt_regs *ctx)
53 {
54 kretprobe_res = 2;
55 return 0;
56 }
57
58 SEC("kretsyscall/nanosleep")
BPF_KRETPROBE(handle_kretprobe_auto,int ret)59 int BPF_KRETPROBE(handle_kretprobe_auto, int ret)
60 {
61 kretprobe2_res = 22;
62 return ret;
63 }
64
65 SEC("uprobe")
handle_uprobe(struct pt_regs * ctx)66 int handle_uprobe(struct pt_regs *ctx)
67 {
68 uprobe_res = 3;
69 return 0;
70 }
71
72 SEC("uretprobe")
handle_uretprobe(struct pt_regs * ctx)73 int handle_uretprobe(struct pt_regs *ctx)
74 {
75 uretprobe_res = 4;
76 return 0;
77 }
78
79 SEC("uprobe")
handle_uprobe_byname(struct pt_regs * ctx)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")
handle_uretprobe_byname(struct pt_regs * ctx)88 int handle_uretprobe_byname(struct pt_regs *ctx)
89 {
90 uretprobe_byname_res = 6;
91 return 0;
92 }
93
94 SEC("uprobe")
BPF_UPROBE(handle_uprobe_byname2,const char * pathname,const char * mode)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")
BPF_URETPROBE(handle_uretprobe_byname2,void * ret)107 int BPF_URETPROBE(handle_uretprobe_byname2, void *ret)
108 {
109 uretprobe_byname2_res = 8;
110 return 0;
111 }
112
verify_sleepable_user_copy(void)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")
handle_uprobe_byname3_sleepable(struct pt_regs * ctx)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")
handle_uprobe_byname3(struct pt_regs * ctx)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")
handle_uretprobe_byname3_sleepable(struct pt_regs * ctx)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")
handle_uretprobe_byname3(struct pt_regs * ctx)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