xref: /aosp_15_r20/external/bcc/libbpf-tools/sigsnoop.bpf.c (revision 387f9dfdfa2baef462e92476d413c7bc2470293e)
1 // SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause)
2 /* Copyright (c) 2021~2022 Hengqi Chen */
3 #include <vmlinux.h>
4 #include <bpf/bpf_helpers.h>
5 #include "sigsnoop.h"
6 
7 #define MAX_ENTRIES	10240
8 
9 const volatile pid_t filtered_pid = 0;
10 const volatile int target_signal = 0;
11 const volatile bool failed_only = false;
12 
13 struct {
14 	__uint(type, BPF_MAP_TYPE_HASH);
15 	__uint(max_entries, MAX_ENTRIES);
16 	__type(key, __u32);
17 	__type(value, struct event);
18 } values SEC(".maps");
19 
20 struct {
21 	__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
22 	__uint(key_size, sizeof(__u32));
23 	__uint(value_size, sizeof(__u32));
24 } events SEC(".maps");
25 
probe_entry(pid_t tpid,int sig)26 static int probe_entry(pid_t tpid, int sig)
27 {
28 	struct event event = {};
29 	__u64 pid_tgid;
30 	__u32 pid, tid;
31 
32 	if (target_signal && sig != target_signal)
33 		return 0;
34 
35 	pid_tgid = bpf_get_current_pid_tgid();
36 	pid = pid_tgid >> 32;
37 	tid = (__u32)pid_tgid;
38 	if (filtered_pid && pid != filtered_pid)
39 		return 0;
40 
41 	event.pid = pid;
42 	event.tpid = tpid;
43 	event.sig = sig;
44 	bpf_get_current_comm(event.comm, sizeof(event.comm));
45 	bpf_map_update_elem(&values, &tid, &event, BPF_ANY);
46 	return 0;
47 }
48 
probe_exit(void * ctx,int ret)49 static int probe_exit(void *ctx, int ret)
50 {
51 	__u64 pid_tgid = bpf_get_current_pid_tgid();
52 	__u32 tid = (__u32)pid_tgid;
53 	struct event *eventp;
54 
55 	eventp = bpf_map_lookup_elem(&values, &tid);
56 	if (!eventp)
57 		return 0;
58 
59 	if (failed_only && ret >= 0)
60 		goto cleanup;
61 
62 	eventp->ret = ret;
63 	bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, eventp, sizeof(*eventp));
64 
65 cleanup:
66 	bpf_map_delete_elem(&values, &tid);
67 	return 0;
68 }
69 
70 SEC("tracepoint/syscalls/sys_enter_kill")
kill_entry(struct trace_event_raw_sys_enter * ctx)71 int kill_entry(struct trace_event_raw_sys_enter *ctx)
72 {
73 	pid_t tpid = (pid_t)ctx->args[0];
74 	int sig = (int)ctx->args[1];
75 
76 	return probe_entry(tpid, sig);
77 }
78 
79 SEC("tracepoint/syscalls/sys_exit_kill")
kill_exit(struct trace_event_raw_sys_exit * ctx)80 int kill_exit(struct trace_event_raw_sys_exit *ctx)
81 {
82 	return probe_exit(ctx, ctx->ret);
83 }
84 
85 SEC("tracepoint/syscalls/sys_enter_tkill")
tkill_entry(struct trace_event_raw_sys_enter * ctx)86 int tkill_entry(struct trace_event_raw_sys_enter *ctx)
87 {
88 	pid_t tpid = (pid_t)ctx->args[0];
89 	int sig = (int)ctx->args[1];
90 
91 	return probe_entry(tpid, sig);
92 }
93 
94 SEC("tracepoint/syscalls/sys_exit_tkill")
tkill_exit(struct trace_event_raw_sys_exit * ctx)95 int tkill_exit(struct trace_event_raw_sys_exit *ctx)
96 {
97 	return probe_exit(ctx, ctx->ret);
98 }
99 
100 SEC("tracepoint/syscalls/sys_enter_tgkill")
tgkill_entry(struct trace_event_raw_sys_enter * ctx)101 int tgkill_entry(struct trace_event_raw_sys_enter *ctx)
102 {
103 	pid_t tpid = (pid_t)ctx->args[1];
104 	int sig = (int)ctx->args[2];
105 
106 	return probe_entry(tpid, sig);
107 }
108 
109 SEC("tracepoint/syscalls/sys_exit_tgkill")
tgkill_exit(struct trace_event_raw_sys_exit * ctx)110 int tgkill_exit(struct trace_event_raw_sys_exit *ctx)
111 {
112 	return probe_exit(ctx, ctx->ret);
113 }
114 
115 SEC("tracepoint/signal/signal_generate")
sig_trace(struct trace_event_raw_signal_generate * ctx)116 int sig_trace(struct trace_event_raw_signal_generate *ctx)
117 {
118 	struct event event = {};
119 	pid_t tpid = ctx->pid;
120 	int ret = ctx->errno;
121 	int sig = ctx->sig;
122 	__u64 pid_tgid;
123 	__u32 pid;
124 
125 	if (failed_only && ret == 0)
126 		return 0;
127 
128 	if (target_signal && sig != target_signal)
129 		return 0;
130 
131 	pid_tgid = bpf_get_current_pid_tgid();
132 	pid = pid_tgid >> 32;
133 	if (filtered_pid && pid != filtered_pid)
134 		return 0;
135 
136 	event.pid = pid;
137 	event.tpid = tpid;
138 	event.sig = sig;
139 	event.ret = ret;
140 	bpf_get_current_comm(event.comm, sizeof(event.comm));
141 	bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(event));
142 	return 0;
143 }
144 
145 char LICENSE[] SEC("license") = "Dual BSD/GPL";
146