enodia-sentinal/go-agent/internal/ebpfsource/bpf/exec.bpf.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";