11e8611bbSAndrii Nakryiko // SPDX-License-Identifier: GPL-2.0
21e8611bbSAndrii Nakryiko // Copyright (c) 2017 Facebook
31e8611bbSAndrii Nakryiko 
4d814ed62SAndrii Nakryiko #include "vmlinux.h"
53e689141SToke Høiland-Jørgensen #include <bpf/bpf_helpers.h>
6df8ff353SAndrii Nakryiko #include <bpf/bpf_tracing.h>
7d814ed62SAndrii Nakryiko #include <bpf/bpf_core_read.h>
832c03c49SAndrii Nakryiko #include "bpf_misc.h"
91e8611bbSAndrii Nakryiko 
10f3c926a4SAndrii Nakryiko int kprobe_res = 0;
1132c03c49SAndrii Nakryiko int kprobe2_res = 0;
12f3c926a4SAndrii Nakryiko int kretprobe_res = 0;
1332c03c49SAndrii Nakryiko int kretprobe2_res = 0;
14f3c926a4SAndrii Nakryiko int uprobe_res = 0;
15f3c926a4SAndrii Nakryiko int uretprobe_res = 0;
16ba7499bcSAlan Maguire int uprobe_byname_res = 0;
17ba7499bcSAlan Maguire int uretprobe_byname_res = 0;
18ba7499bcSAlan Maguire int uprobe_byname2_res = 0;
19ba7499bcSAlan Maguire int uretprobe_byname2_res = 0;
20cb3f4a4aSDelyan Kratunov int uprobe_byname3_sleepable_res = 0;
21cb3f4a4aSDelyan Kratunov int uprobe_byname3_res = 0;
22cb3f4a4aSDelyan Kratunov int uretprobe_byname3_sleepable_res = 0;
23cb3f4a4aSDelyan Kratunov int uretprobe_byname3_res = 0;
24cb3f4a4aSDelyan Kratunov void *user_ptr = 0;
251e8611bbSAndrii Nakryiko 
2632c03c49SAndrii Nakryiko SEC("kprobe")
27f3c926a4SAndrii Nakryiko int handle_kprobe(struct pt_regs *ctx)
281e8611bbSAndrii Nakryiko {
29f3c926a4SAndrii Nakryiko 	kprobe_res = 1;
301e8611bbSAndrii Nakryiko 	return 0;
311e8611bbSAndrii Nakryiko }
321e8611bbSAndrii Nakryiko 
33d814ed62SAndrii Nakryiko SEC("ksyscall/nanosleep")
34d814ed62SAndrii Nakryiko int BPF_KSYSCALL(handle_kprobe_auto, struct __kernel_timespec *req, struct __kernel_timespec *rem)
3532c03c49SAndrii Nakryiko {
3632c03c49SAndrii Nakryiko 	kprobe2_res = 11;
3732c03c49SAndrii Nakryiko 	return 0;
3832c03c49SAndrii Nakryiko }
3932c03c49SAndrii Nakryiko 
40cb3f4a4aSDelyan Kratunov /**
41cb3f4a4aSDelyan Kratunov  * This program will be manually made sleepable on the userspace side
42cb3f4a4aSDelyan Kratunov  * and should thus be unattachable.
43cb3f4a4aSDelyan Kratunov  */
44cb3f4a4aSDelyan Kratunov SEC("kprobe/" SYS_PREFIX "sys_nanosleep")
45cb3f4a4aSDelyan Kratunov int handle_kprobe_sleepable(struct pt_regs *ctx)
46cb3f4a4aSDelyan Kratunov {
47cb3f4a4aSDelyan Kratunov 	kprobe_res = 2;
48cb3f4a4aSDelyan Kratunov 	return 0;
49cb3f4a4aSDelyan Kratunov }
50cb3f4a4aSDelyan Kratunov 
5132c03c49SAndrii Nakryiko SEC("kretprobe")
5232c03c49SAndrii Nakryiko int handle_kretprobe(struct pt_regs *ctx)
531e8611bbSAndrii Nakryiko {
54f3c926a4SAndrii Nakryiko 	kretprobe_res = 2;
551e8611bbSAndrii Nakryiko 	return 0;
561e8611bbSAndrii Nakryiko }
571e8611bbSAndrii Nakryiko 
58d814ed62SAndrii Nakryiko SEC("kretsyscall/nanosleep")
59d814ed62SAndrii Nakryiko int BPF_KRETPROBE(handle_kretprobe_auto, int ret)
6032c03c49SAndrii Nakryiko {
6132c03c49SAndrii Nakryiko 	kretprobe2_res = 22;
62d814ed62SAndrii Nakryiko 	return ret;
6332c03c49SAndrii Nakryiko }
6432c03c49SAndrii Nakryiko 
65ba7499bcSAlan Maguire SEC("uprobe")
66f3c926a4SAndrii Nakryiko int handle_uprobe(struct pt_regs *ctx)
671e8611bbSAndrii Nakryiko {
68f3c926a4SAndrii Nakryiko 	uprobe_res = 3;
691e8611bbSAndrii Nakryiko 	return 0;
701e8611bbSAndrii Nakryiko }
711e8611bbSAndrii Nakryiko 
72ba7499bcSAlan Maguire SEC("uretprobe")
73f3c926a4SAndrii Nakryiko int handle_uretprobe(struct pt_regs *ctx)
741e8611bbSAndrii Nakryiko {
75f3c926a4SAndrii Nakryiko 	uretprobe_res = 4;
761e8611bbSAndrii Nakryiko 	return 0;
771e8611bbSAndrii Nakryiko }
781e8611bbSAndrii Nakryiko 
79ba7499bcSAlan Maguire SEC("uprobe")
80ba7499bcSAlan Maguire int handle_uprobe_byname(struct pt_regs *ctx)
81ba7499bcSAlan Maguire {
82ba7499bcSAlan Maguire 	uprobe_byname_res = 5;
83ba7499bcSAlan Maguire 	return 0;
84ba7499bcSAlan Maguire }
85ba7499bcSAlan Maguire 
86ba7499bcSAlan Maguire /* use auto-attach format for section definition. */
87ba7499bcSAlan Maguire SEC("uretprobe//proc/self/exe:trigger_func2")
88ba7499bcSAlan Maguire int handle_uretprobe_byname(struct pt_regs *ctx)
89ba7499bcSAlan Maguire {
90ba7499bcSAlan Maguire 	uretprobe_byname_res = 6;
91ba7499bcSAlan Maguire 	return 0;
92ba7499bcSAlan Maguire }
93ba7499bcSAlan Maguire 
94ba7499bcSAlan Maguire SEC("uprobe")
95*202702e8SIlya Leoshkevich int BPF_UPROBE(handle_uprobe_byname2, const char *pathname, const char *mode)
96ba7499bcSAlan Maguire {
97*202702e8SIlya Leoshkevich 	char mode_buf[2] = {};
98ba7499bcSAlan Maguire 
99*202702e8SIlya Leoshkevich 	/* verify fopen mode */
100*202702e8SIlya Leoshkevich 	bpf_probe_read_user(mode_buf, sizeof(mode_buf), mode);
101*202702e8SIlya Leoshkevich 	if (mode_buf[0] == 'r' && mode_buf[1] == 0)
102ba7499bcSAlan Maguire 		uprobe_byname2_res = 7;
103ba7499bcSAlan Maguire 	return 0;
104ba7499bcSAlan Maguire }
105ba7499bcSAlan Maguire 
106ba7499bcSAlan Maguire SEC("uretprobe")
107*202702e8SIlya Leoshkevich int BPF_URETPROBE(handle_uretprobe_byname2, void *ret)
108ba7499bcSAlan Maguire {
109ba7499bcSAlan Maguire 	uretprobe_byname2_res = 8;
110ba7499bcSAlan Maguire 	return 0;
111ba7499bcSAlan Maguire }
112ba7499bcSAlan Maguire 
113cb3f4a4aSDelyan Kratunov static __always_inline bool verify_sleepable_user_copy(void)
114cb3f4a4aSDelyan Kratunov {
115cb3f4a4aSDelyan Kratunov 	char data[9];
116cb3f4a4aSDelyan Kratunov 
117cb3f4a4aSDelyan Kratunov 	bpf_copy_from_user(data, sizeof(data), user_ptr);
118cb3f4a4aSDelyan Kratunov 	return bpf_strncmp(data, sizeof(data), "test_data") == 0;
119cb3f4a4aSDelyan Kratunov }
120cb3f4a4aSDelyan Kratunov 
121cb3f4a4aSDelyan Kratunov SEC("uprobe.s//proc/self/exe:trigger_func3")
122cb3f4a4aSDelyan Kratunov int handle_uprobe_byname3_sleepable(struct pt_regs *ctx)
123cb3f4a4aSDelyan Kratunov {
124cb3f4a4aSDelyan Kratunov 	if (verify_sleepable_user_copy())
125cb3f4a4aSDelyan Kratunov 		uprobe_byname3_sleepable_res = 9;
126cb3f4a4aSDelyan Kratunov 	return 0;
127cb3f4a4aSDelyan Kratunov }
128cb3f4a4aSDelyan Kratunov 
129cb3f4a4aSDelyan Kratunov /**
130cb3f4a4aSDelyan Kratunov  * same target as the uprobe.s above to force sleepable and non-sleepable
131cb3f4a4aSDelyan Kratunov  * programs in the same bpf_prog_array
132cb3f4a4aSDelyan Kratunov  */
133cb3f4a4aSDelyan Kratunov SEC("uprobe//proc/self/exe:trigger_func3")
134cb3f4a4aSDelyan Kratunov int handle_uprobe_byname3(struct pt_regs *ctx)
135cb3f4a4aSDelyan Kratunov {
136cb3f4a4aSDelyan Kratunov 	uprobe_byname3_res = 10;
137cb3f4a4aSDelyan Kratunov 	return 0;
138cb3f4a4aSDelyan Kratunov }
139cb3f4a4aSDelyan Kratunov 
140cb3f4a4aSDelyan Kratunov SEC("uretprobe.s//proc/self/exe:trigger_func3")
141cb3f4a4aSDelyan Kratunov int handle_uretprobe_byname3_sleepable(struct pt_regs *ctx)
142cb3f4a4aSDelyan Kratunov {
143cb3f4a4aSDelyan Kratunov 	if (verify_sleepable_user_copy())
144cb3f4a4aSDelyan Kratunov 		uretprobe_byname3_sleepable_res = 11;
145cb3f4a4aSDelyan Kratunov 	return 0;
146cb3f4a4aSDelyan Kratunov }
147cb3f4a4aSDelyan Kratunov 
148cb3f4a4aSDelyan Kratunov SEC("uretprobe//proc/self/exe:trigger_func3")
149cb3f4a4aSDelyan Kratunov int handle_uretprobe_byname3(struct pt_regs *ctx)
150cb3f4a4aSDelyan Kratunov {
151cb3f4a4aSDelyan Kratunov 	uretprobe_byname3_res = 12;
152cb3f4a4aSDelyan Kratunov 	return 0;
153cb3f4a4aSDelyan Kratunov }
154cb3f4a4aSDelyan Kratunov 
155cb3f4a4aSDelyan Kratunov 
1561e8611bbSAndrii Nakryiko char _license[] SEC("license") = "GPL";
157