// SPDX-License-Identifier: GPL-3.0-or-later #define SEC(name) __attribute__((section(name), used)) #define __uint(name, value) int (*name)[value] typedef unsigned int u32; typedef unsigned long long u64; #define BPF_MAP_TYPE_PERF_EVENT_ARRAY 4 #define BPF_F_CURRENT_CPU 0xffffffffULL struct trace_event_raw_sys_enter { u64 _common; long id; unsigned long args[6]; }; // Minimal CO-RE flavor of task_struct. The loader relocates these two fields // against the running kernel's BTF, avoiding a generated vmlinux.h dependency. struct task_struct { int tgid; struct task_struct *real_parent; } __attribute__((preserve_access_index)); struct exec_event { u32 pid; u32 ppid; u32 uid; char parent_comm[16]; char filename[128]; char arg1[128]; char arg2[128]; }; struct { __uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY); __uint(key_size, sizeof(u32)); __uint(value_size, sizeof(u32)); } events SEC(".maps"); static u64 (*bpf_get_current_pid_tgid)(void) = (void *)14; static u64 (*bpf_get_current_uid_gid)(void) = (void *)15; static long (*bpf_get_current_comm)(void *buf, u32 size) = (void *)16; static long (*bpf_probe_read_user)(void *dst, u32 size, const void *unsafe_ptr) = (void *)112; static long (*bpf_probe_read_user_str)(void *dst, u32 size, const void *unsafe_ptr) = (void *)114; static long (*bpf_probe_read_kernel)(void *dst, u32 size, const void *unsafe_ptr) = (void *)113; static long (*bpf_perf_event_output)(void *ctx, void *map, u64 flags, void *data, u64 size) = (void *)25; static u64 (*bpf_get_current_task)(void) = (void *)35; #define bpf_core_read(dst, size, src) \ bpf_probe_read_kernel((dst), (size), \ (const void *)__builtin_preserve_access_index(src)) SEC("tracepoint/syscalls/sys_enter_execve") int trace_execve(struct trace_event_raw_sys_enter *ctx) { struct exec_event event = {}; struct task_struct *task = (struct task_struct *)bpf_get_current_task(); struct task_struct *parent = 0; const char *const *argv = (const char *const *)ctx->args[1]; const char *argument = 0; event.pid = bpf_get_current_pid_tgid() >> 32; event.uid = bpf_get_current_uid_gid(); bpf_core_read(&parent, sizeof(parent), &task->real_parent); if (parent) bpf_core_read(&event.ppid, sizeof(event.ppid), &parent->tgid); bpf_get_current_comm(event.parent_comm, sizeof(event.parent_comm)); bpf_probe_read_user_str(event.filename, sizeof(event.filename), (const void *)ctx->args[0]); bpf_probe_read_user(&argument, sizeof(argument), &argv[1]); if (argument) bpf_probe_read_user_str(event.arg1, sizeof(event.arg1), argument); argument = 0; bpf_probe_read_user(&argument, sizeof(argument), &argv[2]); if (argument) bpf_probe_read_user_str(event.arg2, sizeof(event.arg2), argument); bpf_perf_event_output(ctx, &events, BPF_F_CURRENT_CPU, &event, sizeof(event)); return 0; } char LICENSE[] SEC("license") = "GPL";