github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/gadgets/trace/signal/tracer/bpf/sigsnoop.bpf.c (about) 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_core_read.h> 5 #include <bpf/bpf_helpers.h> 6 #include "sigsnoop.h" 7 #include <gadget/mntns_filter.h> 8 9 #define MAX_ENTRIES 10240 10 11 const volatile pid_t filtered_pid = 0; 12 const volatile int target_signal = 0; 13 const volatile bool failed_only = false; 14 15 // we need this to make sure the compiler doesn't remove our struct 16 const struct event *unusedevent __attribute__((unused)); 17 18 struct { 19 __uint(type, BPF_MAP_TYPE_HASH); 20 __uint(max_entries, MAX_ENTRIES); 21 __type(key, __u32); 22 __type(value, struct event); 23 } values SEC(".maps"); 24 25 struct { 26 __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); 27 __uint(key_size, sizeof(__u32)); 28 __uint(value_size, sizeof(__u32)); 29 } events SEC(".maps"); 30 31 static int probe_entry(pid_t tpid, int sig) 32 { 33 struct event event = {}; 34 __u64 pid_tgid; 35 __u32 pid, tid; 36 u64 mntns_id; 37 38 mntns_id = gadget_get_mntns_id(); 39 40 if (gadget_should_discard_mntns_id(mntns_id)) 41 return 0; 42 43 if (target_signal && sig != target_signal) 44 return 0; 45 46 pid_tgid = bpf_get_current_pid_tgid(); 47 pid = pid_tgid >> 32; 48 tid = (__u32)pid_tgid; 49 if (filtered_pid && pid != filtered_pid) 50 return 0; 51 52 event.pid = pid; 53 event.tpid = tpid; 54 event.sig = sig; 55 event.mntns_id = mntns_id; 56 bpf_get_current_comm(event.comm, sizeof(event.comm)); 57 bpf_map_update_elem(&values, &tid, &event, BPF_ANY); 58 return 0; 59 } 60 61 static int probe_exit(void *ctx, int ret) 62 { 63 __u64 pid_tgid = bpf_get_current_pid_tgid(); 64 __u64 uid_gid = bpf_get_current_uid_gid(); 65 __u32 tid = (__u32)pid_tgid; 66 struct event *eventp; 67 68 eventp = bpf_map_lookup_elem(&values, &tid); 69 if (!eventp) 70 return 0; 71 72 if (failed_only && ret >= 0) 73 goto cleanup; 74 75 eventp->ret = ret; 76 eventp->timestamp = bpf_ktime_get_boot_ns(); 77 eventp->uid = (u32)uid_gid; 78 eventp->gid = (u32)(uid_gid >> 32); 79 bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, eventp, 80 sizeof(*eventp)); 81 82 cleanup: 83 bpf_map_delete_elem(&values, &tid); 84 return 0; 85 } 86 87 SEC("tracepoint/syscalls/sys_enter_kill") 88 int ig_sig_kill_e(struct syscall_trace_enter *ctx) 89 { 90 pid_t tpid = (pid_t)ctx->args[0]; 91 int sig = (int)ctx->args[1]; 92 93 return probe_entry(tpid, sig); 94 } 95 96 SEC("tracepoint/syscalls/sys_exit_kill") 97 int ig_sig_kill_x(struct syscall_trace_exit *ctx) 98 { 99 return probe_exit(ctx, ctx->ret); 100 } 101 102 SEC("tracepoint/syscalls/sys_enter_tkill") 103 int ig_sig_tkill_e(struct syscall_trace_enter *ctx) 104 { 105 pid_t tpid = (pid_t)ctx->args[0]; 106 int sig = (int)ctx->args[1]; 107 108 return probe_entry(tpid, sig); 109 } 110 111 SEC("tracepoint/syscalls/sys_exit_tkill") 112 int ig_sig_tkill_x(struct syscall_trace_exit *ctx) 113 { 114 return probe_exit(ctx, ctx->ret); 115 } 116 117 SEC("tracepoint/syscalls/sys_enter_tgkill") 118 int ig_sig_tgkill_e(struct syscall_trace_enter *ctx) 119 { 120 pid_t tpid = (pid_t)ctx->args[1]; 121 int sig = (int)ctx->args[2]; 122 123 return probe_entry(tpid, sig); 124 } 125 126 SEC("tracepoint/syscalls/sys_exit_tgkill") 127 int ig_sig_tgkill_x(struct syscall_trace_exit *ctx) 128 { 129 return probe_exit(ctx, ctx->ret); 130 } 131 132 SEC("tracepoint/signal/signal_generate") 133 int ig_sig_generate(struct trace_event_raw_signal_generate *ctx) 134 { 135 struct event event = {}; 136 pid_t tpid = ctx->pid; 137 int ret = ctx->errno; 138 int sig = ctx->sig; 139 __u64 pid_tgid; 140 __u32 pid; 141 u64 mntns_id; 142 __u64 uid_gid = bpf_get_current_uid_gid(); 143 144 mntns_id = gadget_get_mntns_id(); 145 146 if (gadget_should_discard_mntns_id(mntns_id)) 147 return 0; 148 149 if (failed_only && ret == 0) 150 return 0; 151 152 if (target_signal && sig != target_signal) 153 return 0; 154 155 pid_tgid = bpf_get_current_pid_tgid(); 156 pid = pid_tgid >> 32; 157 if (filtered_pid && pid != filtered_pid) 158 return 0; 159 160 event.pid = pid; 161 event.tpid = tpid; 162 event.mntns_id = mntns_id; 163 event.sig = sig; 164 event.ret = ret; 165 event.uid = (u32)uid_gid; 166 event.gid = (u32)(uid_gid >> 32); 167 bpf_get_current_comm(event.comm, sizeof(event.comm)); 168 event.timestamp = bpf_ktime_get_boot_ns(); 169 bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, 170 sizeof(event)); 171 return 0; 172 } 173 174 char LICENSE[] SEC("license") = "Dual BSD/GPL";