11e8611bbSAndrii Nakryiko // SPDX-License-Identifier: GPL-2.0
21e8611bbSAndrii Nakryiko // Copyright (c) 2017 Facebook
31e8611bbSAndrii Nakryiko 
41e8611bbSAndrii Nakryiko #include <linux/ptrace.h>
51e8611bbSAndrii Nakryiko #include <linux/bpf.h>
63e689141SToke Høiland-Jørgensen #include <bpf/bpf_helpers.h>
7df8ff353SAndrii Nakryiko #include <bpf/bpf_tracing.h>
8*cb3f4a4aSDelyan Kratunov #include <stdbool.h>
932c03c49SAndrii Nakryiko #include "bpf_misc.h"
101e8611bbSAndrii Nakryiko 
11f3c926a4SAndrii Nakryiko int kprobe_res = 0;
1232c03c49SAndrii Nakryiko int kprobe2_res = 0;
13f3c926a4SAndrii Nakryiko int kretprobe_res = 0;
1432c03c49SAndrii Nakryiko int kretprobe2_res = 0;
15f3c926a4SAndrii Nakryiko int uprobe_res = 0;
16f3c926a4SAndrii Nakryiko int uretprobe_res = 0;
17ba7499bcSAlan Maguire int uprobe_byname_res = 0;
18ba7499bcSAlan Maguire int uretprobe_byname_res = 0;
19ba7499bcSAlan Maguire int uprobe_byname2_res = 0;
20ba7499bcSAlan Maguire int uretprobe_byname2_res = 0;
21*cb3f4a4aSDelyan Kratunov int uprobe_byname3_sleepable_res = 0;
22*cb3f4a4aSDelyan Kratunov int uprobe_byname3_res = 0;
23*cb3f4a4aSDelyan Kratunov int uretprobe_byname3_sleepable_res = 0;
24*cb3f4a4aSDelyan Kratunov int uretprobe_byname3_res = 0;
25*cb3f4a4aSDelyan Kratunov void *user_ptr = 0;
261e8611bbSAndrii Nakryiko 
2732c03c49SAndrii Nakryiko SEC("kprobe")
28f3c926a4SAndrii Nakryiko int handle_kprobe(struct pt_regs *ctx)
291e8611bbSAndrii Nakryiko {
30f3c926a4SAndrii Nakryiko 	kprobe_res = 1;
311e8611bbSAndrii Nakryiko 	return 0;
321e8611bbSAndrii Nakryiko }
331e8611bbSAndrii Nakryiko 
3432c03c49SAndrii Nakryiko SEC("kprobe/" SYS_PREFIX "sys_nanosleep")
3532c03c49SAndrii Nakryiko int BPF_KPROBE(handle_kprobe_auto)
3632c03c49SAndrii Nakryiko {
3732c03c49SAndrii Nakryiko 	kprobe2_res = 11;
3832c03c49SAndrii Nakryiko 	return 0;
3932c03c49SAndrii Nakryiko }
4032c03c49SAndrii Nakryiko 
41*cb3f4a4aSDelyan Kratunov /**
42*cb3f4a4aSDelyan Kratunov  * This program will be manually made sleepable on the userspace side
43*cb3f4a4aSDelyan Kratunov  * and should thus be unattachable.
44*cb3f4a4aSDelyan Kratunov  */
45*cb3f4a4aSDelyan Kratunov SEC("kprobe/" SYS_PREFIX "sys_nanosleep")
46*cb3f4a4aSDelyan Kratunov int handle_kprobe_sleepable(struct pt_regs *ctx)
47*cb3f4a4aSDelyan Kratunov {
48*cb3f4a4aSDelyan Kratunov 	kprobe_res = 2;
49*cb3f4a4aSDelyan Kratunov 	return 0;
50*cb3f4a4aSDelyan Kratunov }
51*cb3f4a4aSDelyan Kratunov 
5232c03c49SAndrii Nakryiko SEC("kretprobe")
5332c03c49SAndrii Nakryiko int handle_kretprobe(struct pt_regs *ctx)
541e8611bbSAndrii Nakryiko {
55f3c926a4SAndrii Nakryiko 	kretprobe_res = 2;
561e8611bbSAndrii Nakryiko 	return 0;
571e8611bbSAndrii Nakryiko }
581e8611bbSAndrii Nakryiko 
5932c03c49SAndrii Nakryiko SEC("kretprobe/" SYS_PREFIX "sys_nanosleep")
6032c03c49SAndrii Nakryiko int BPF_KRETPROBE(handle_kretprobe_auto)
6132c03c49SAndrii Nakryiko {
6232c03c49SAndrii Nakryiko 	kretprobe2_res = 22;
6332c03c49SAndrii Nakryiko 	return 0;
6432c03c49SAndrii Nakryiko }
6532c03c49SAndrii Nakryiko 
66ba7499bcSAlan Maguire SEC("uprobe")
67f3c926a4SAndrii Nakryiko int handle_uprobe(struct pt_regs *ctx)
681e8611bbSAndrii Nakryiko {
69f3c926a4SAndrii Nakryiko 	uprobe_res = 3;
701e8611bbSAndrii Nakryiko 	return 0;
711e8611bbSAndrii Nakryiko }
721e8611bbSAndrii Nakryiko 
73ba7499bcSAlan Maguire SEC("uretprobe")
74f3c926a4SAndrii Nakryiko int handle_uretprobe(struct pt_regs *ctx)
751e8611bbSAndrii Nakryiko {
76f3c926a4SAndrii Nakryiko 	uretprobe_res = 4;
771e8611bbSAndrii Nakryiko 	return 0;
781e8611bbSAndrii Nakryiko }
791e8611bbSAndrii Nakryiko 
80ba7499bcSAlan Maguire SEC("uprobe")
81ba7499bcSAlan Maguire int handle_uprobe_byname(struct pt_regs *ctx)
82ba7499bcSAlan Maguire {
83ba7499bcSAlan Maguire 	uprobe_byname_res = 5;
84ba7499bcSAlan Maguire 	return 0;
85ba7499bcSAlan Maguire }
86ba7499bcSAlan Maguire 
87ba7499bcSAlan Maguire /* use auto-attach format for section definition. */
88ba7499bcSAlan Maguire SEC("uretprobe//proc/self/exe:trigger_func2")
89ba7499bcSAlan Maguire int handle_uretprobe_byname(struct pt_regs *ctx)
90ba7499bcSAlan Maguire {
91ba7499bcSAlan Maguire 	uretprobe_byname_res = 6;
92ba7499bcSAlan Maguire 	return 0;
93ba7499bcSAlan Maguire }
94ba7499bcSAlan Maguire 
95ba7499bcSAlan Maguire SEC("uprobe")
96ba7499bcSAlan Maguire int handle_uprobe_byname2(struct pt_regs *ctx)
97ba7499bcSAlan Maguire {
98ba7499bcSAlan Maguire 	unsigned int size = PT_REGS_PARM1(ctx);
99ba7499bcSAlan Maguire 
100ba7499bcSAlan Maguire 	/* verify malloc size */
101ba7499bcSAlan Maguire 	if (size == 1)
102ba7499bcSAlan Maguire 		uprobe_byname2_res = 7;
103ba7499bcSAlan Maguire 	return 0;
104ba7499bcSAlan Maguire }
105ba7499bcSAlan Maguire 
106ba7499bcSAlan Maguire SEC("uretprobe")
107ba7499bcSAlan Maguire int handle_uretprobe_byname2(struct pt_regs *ctx)
108ba7499bcSAlan Maguire {
109ba7499bcSAlan Maguire 	uretprobe_byname2_res = 8;
110ba7499bcSAlan Maguire 	return 0;
111ba7499bcSAlan Maguire }
112ba7499bcSAlan Maguire 
113*cb3f4a4aSDelyan Kratunov static __always_inline bool verify_sleepable_user_copy(void)
114*cb3f4a4aSDelyan Kratunov {
115*cb3f4a4aSDelyan Kratunov 	char data[9];
116*cb3f4a4aSDelyan Kratunov 
117*cb3f4a4aSDelyan Kratunov 	bpf_copy_from_user(data, sizeof(data), user_ptr);
118*cb3f4a4aSDelyan Kratunov 	return bpf_strncmp(data, sizeof(data), "test_data") == 0;
119*cb3f4a4aSDelyan Kratunov }
120*cb3f4a4aSDelyan Kratunov 
121*cb3f4a4aSDelyan Kratunov SEC("uprobe.s//proc/self/exe:trigger_func3")
122*cb3f4a4aSDelyan Kratunov int handle_uprobe_byname3_sleepable(struct pt_regs *ctx)
123*cb3f4a4aSDelyan Kratunov {
124*cb3f4a4aSDelyan Kratunov 	if (verify_sleepable_user_copy())
125*cb3f4a4aSDelyan Kratunov 		uprobe_byname3_sleepable_res = 9;
126*cb3f4a4aSDelyan Kratunov 	return 0;
127*cb3f4a4aSDelyan Kratunov }
128*cb3f4a4aSDelyan Kratunov 
129*cb3f4a4aSDelyan Kratunov /**
130*cb3f4a4aSDelyan Kratunov  * same target as the uprobe.s above to force sleepable and non-sleepable
131*cb3f4a4aSDelyan Kratunov  * programs in the same bpf_prog_array
132*cb3f4a4aSDelyan Kratunov  */
133*cb3f4a4aSDelyan Kratunov SEC("uprobe//proc/self/exe:trigger_func3")
134*cb3f4a4aSDelyan Kratunov int handle_uprobe_byname3(struct pt_regs *ctx)
135*cb3f4a4aSDelyan Kratunov {
136*cb3f4a4aSDelyan Kratunov 	uprobe_byname3_res = 10;
137*cb3f4a4aSDelyan Kratunov 	return 0;
138*cb3f4a4aSDelyan Kratunov }
139*cb3f4a4aSDelyan Kratunov 
140*cb3f4a4aSDelyan Kratunov SEC("uretprobe.s//proc/self/exe:trigger_func3")
141*cb3f4a4aSDelyan Kratunov int handle_uretprobe_byname3_sleepable(struct pt_regs *ctx)
142*cb3f4a4aSDelyan Kratunov {
143*cb3f4a4aSDelyan Kratunov 	if (verify_sleepable_user_copy())
144*cb3f4a4aSDelyan Kratunov 		uretprobe_byname3_sleepable_res = 11;
145*cb3f4a4aSDelyan Kratunov 	return 0;
146*cb3f4a4aSDelyan Kratunov }
147*cb3f4a4aSDelyan Kratunov 
148*cb3f4a4aSDelyan Kratunov SEC("uretprobe//proc/self/exe:trigger_func3")
149*cb3f4a4aSDelyan Kratunov int handle_uretprobe_byname3(struct pt_regs *ctx)
150*cb3f4a4aSDelyan Kratunov {
151*cb3f4a4aSDelyan Kratunov 	uretprobe_byname3_res = 12;
152*cb3f4a4aSDelyan Kratunov 	return 0;
153*cb3f4a4aSDelyan Kratunov }
154*cb3f4a4aSDelyan Kratunov 
155*cb3f4a4aSDelyan Kratunov 
1561e8611bbSAndrii Nakryiko char _license[] SEC("license") = "GPL";
157