1// SPDX-License-Identifier: GPL-2.0
2/* Copyright (c) 2021 Facebook */
3
4#include "vmlinux.h"
5#include <bpf/bpf_helpers.h>
6#include <bpf/bpf_tracing.h>
7#include <errno.h>
8
9int my_tid;
10
11__u64 kprobe_res;
12__u64 kprobe_multi_res;
13__u64 kretprobe_res;
14__u64 uprobe_res;
15__u64 uretprobe_res;
16__u64 tp_res;
17__u64 pe_res;
18__u64 fentry_res;
19__u64 fexit_res;
20__u64 fmod_ret_res;
21__u64 lsm_res;
22
23static void update(void *ctx, __u64 *res)
24{
25	if (my_tid != (u32)bpf_get_current_pid_tgid())
26		return;
27
28	*res |= bpf_get_attach_cookie(ctx);
29}
30
31SEC("kprobe")
32int handle_kprobe(struct pt_regs *ctx)
33{
34	update(ctx, &kprobe_res);
35	return 0;
36}
37
38SEC("kretprobe")
39int handle_kretprobe(struct pt_regs *ctx)
40{
41	update(ctx, &kretprobe_res);
42	return 0;
43}
44
45SEC("uprobe")
46int handle_uprobe(struct pt_regs *ctx)
47{
48	update(ctx, &uprobe_res);
49	return 0;
50}
51
52SEC("uretprobe")
53int handle_uretprobe(struct pt_regs *ctx)
54{
55	update(ctx, &uretprobe_res);
56	return 0;
57}
58
59/* bpf_prog_array, used by kernel internally to keep track of attached BPF
60 * programs to a given BPF hook (e.g., for tracepoints) doesn't allow the same
61 * BPF program to be attached multiple times. So have three identical copies
62 * ready to attach to the same tracepoint.
63 */
64SEC("tp/syscalls/sys_enter_nanosleep")
65int handle_tp1(struct pt_regs *ctx)
66{
67	update(ctx, &tp_res);
68	return 0;
69}
70SEC("tp/syscalls/sys_enter_nanosleep")
71int handle_tp2(struct pt_regs *ctx)
72{
73	update(ctx, &tp_res);
74	return 0;
75}
76SEC("tp/syscalls/sys_enter_nanosleep")
77int handle_tp3(void *ctx)
78{
79	update(ctx, &tp_res);
80	return 1;
81}
82
83SEC("perf_event")
84int handle_pe(struct pt_regs *ctx)
85{
86	update(ctx, &pe_res);
87	return 0;
88}
89
90SEC("fentry/bpf_fentry_test1")
91int BPF_PROG(fentry_test1, int a)
92{
93	update(ctx, &fentry_res);
94	return 0;
95}
96
97SEC("fexit/bpf_fentry_test1")
98int BPF_PROG(fexit_test1, int a, int ret)
99{
100	update(ctx, &fexit_res);
101	return 0;
102}
103
104SEC("fmod_ret/bpf_modify_return_test")
105int BPF_PROG(fmod_ret_test, int _a, int *_b, int _ret)
106{
107	update(ctx, &fmod_ret_res);
108	return 1234;
109}
110
111SEC("lsm/file_mprotect")
112int BPF_PROG(test_int_hook, struct vm_area_struct *vma,
113	     unsigned long reqprot, unsigned long prot, int ret)
114{
115	if (my_tid != (u32)bpf_get_current_pid_tgid())
116		return ret;
117	update(ctx, &lsm_res);
118	return -EPERM;
119}
120
121char _license[] SEC("license") = "GPL";
122