84 lines
3 KiB
C
84 lines
3 KiB
C
// 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";
|