// SPDX-License-Identifier: (LGPL-2.1 OR BSD-2-Clause) /* Copyright (c) 2021~2022 Hengqi Chen */ #include #include #include "sigsnoop.h" #define MAX_ENTRIES 10240 const volatile pid_t filtered_pid = 0; const volatile int target_signal = 0; const volatile bool failed_only = false; struct { __uint(type, BPF_MAP_TYPE_HASH); __uint(max_entries, MAX_ENTRIES); __type(key, __u32); __type(value, struct event); } values SEC(".maps"); struct { __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); __uint(key_size, sizeof(__u32)); __uint(value_size, sizeof(__u32)); } events SEC(".maps"); static int probe_entry(pid_t tpid, int sig) { struct event event = {}; __u64 pid_tgid; __u32 pid, tid; if (target_signal && sig != target_signal) return 0; pid_tgid = bpf_get_current_pid_tgid(); pid = pid_tgid >> 32; tid = (__u32)pid_tgid; if (filtered_pid && pid != filtered_pid) return 0; event.pid = pid; event.tpid = tpid; event.sig = sig; bpf_get_current_comm(event.comm, sizeof(event.comm)); bpf_map_update_elem(&values, &tid, &event, BPF_ANY); return 0; } static int probe_exit(void *ctx, int ret) { __u64 pid_tgid = bpf_get_current_pid_tgid(); __u32 tid = (__u32)pid_tgid; struct event *eventp; eventp = bpf_map_lookup_elem(&values, &tid); if (!eventp) return 0; if (failed_only && ret >= 0) goto cleanup; eventp->ret = ret; bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, eventp, sizeof(*eventp)); cleanup: bpf_map_delete_elem(&values, &tid); return 0; } SEC("tracepoint/syscalls/sys_enter_kill") int kill_entry(struct trace_event_raw_sys_enter *ctx) { pid_t tpid = (pid_t)ctx->args[0]; int sig = (int)ctx->args[1]; return probe_entry(tpid, sig); } SEC("tracepoint/syscalls/sys_exit_kill") int kill_exit(struct trace_event_raw_sys_exit *ctx) { return probe_exit(ctx, ctx->ret); } SEC("tracepoint/syscalls/sys_enter_tkill") int tkill_entry(struct trace_event_raw_sys_enter *ctx) { pid_t tpid = (pid_t)ctx->args[0]; int sig = (int)ctx->args[1]; return probe_entry(tpid, sig); } SEC("tracepoint/syscalls/sys_exit_tkill") int tkill_exit(struct trace_event_raw_sys_exit *ctx) { return probe_exit(ctx, ctx->ret); } SEC("tracepoint/syscalls/sys_enter_tgkill") int tgkill_entry(struct trace_event_raw_sys_enter *ctx) { pid_t tpid = (pid_t)ctx->args[1]; int sig = (int)ctx->args[2]; return probe_entry(tpid, sig); } SEC("tracepoint/syscalls/sys_exit_tgkill") int tgkill_exit(struct trace_event_raw_sys_exit *ctx) { return probe_exit(ctx, ctx->ret); } SEC("tracepoint/signal/signal_generate") int sig_trace(struct trace_event_raw_signal_generate *ctx) { struct event event = {}; pid_t tpid = ctx->pid; int ret = ctx->errno; int sig = ctx->sig; __u64 pid_tgid; __u32 pid; if (failed_only && ret == 0) return 0; if (target_signal && sig != target_signal) return 0; pid_tgid = bpf_get_current_pid_tgid(); pid = pid_tgid >> 32; if (filtered_pid && pid != filtered_pid) return 0; event.pid = pid; event.tpid = tpid; event.sig = sig; event.ret = ret; bpf_get_current_comm(event.comm, sizeof(event.comm)); bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(event)); return 0; } char LICENSE[] SEC("license") = "Dual BSD/GPL";