feat(go): advance validation sidecar toward production

This commit is contained in:
Luna 2026-07-22 01:52:19 -07:00
parent 6a06eba255
commit f85c2e831a
No known key found for this signature in database
92 changed files with 8881 additions and 91 deletions

View file

@ -0,0 +1,212 @@
// 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 short u16;
typedef unsigned long long u64;
#define BPF_MAP_TYPE_HASH 1
#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];
};
struct trace_event_raw_sys_exit {
u64 _common;
long id;
long ret;
};
struct task_struct {
int tgid;
struct task_struct *real_parent;
} __attribute__((preserve_access_index));
struct syscall_event {
u32 pid;
u32 ppid;
u32 uid;
u32 syscall_id;
char comm[16];
u64 args[6];
char text[80];
};
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(key_size, sizeof(u64));
__uint(value_size, sizeof(u32));
__uint(max_entries, 64);
} monitored_syscalls SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(key_size, 16);
__uint(value_size, sizeof(u32));
__uint(max_entries, 64);
} monitored_host_comms SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_HASH);
__uint(key_size, sizeof(u64));
__uint(value_size, sizeof(struct syscall_event));
__uint(max_entries, 4096);
} pending_returns SEC(".maps");
struct {
__uint(type, BPF_MAP_TYPE_PERF_EVENT_ARRAY);
__uint(key_size, sizeof(u32));
__uint(value_size, sizeof(u32));
} syscall_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 void *(*bpf_map_lookup_elem)(void *map, const void *key) = (void *)1;
static long (*bpf_map_update_elem)(void *map, const void *key, const void *value, u64 flags) = (void *)2;
static long (*bpf_map_delete_elem)(void *map, const void *key) = (void *)3;
static long (*bpf_probe_read_user_str)(void *dst, u32 size, const void *unsafe_ptr) = (void *)114;
static long (*bpf_probe_read_user)(void *dst, u32 size, const void *unsafe_ptr) = (void *)112;
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/raw_syscalls/sys_enter")
int trace_sys_enter(struct trace_event_raw_sys_enter *ctx)
{
u64 syscall_number = ctx->id;
u32 *syscall_id = bpf_map_lookup_elem(&monitored_syscalls, &syscall_number);
struct syscall_event event = {};
struct task_struct *task;
struct task_struct *parent = 0;
if (!syscall_id)
return 0;
task = (struct task_struct *)bpf_get_current_task();
event.pid = bpf_get_current_pid_tgid() >> 32;
event.uid = bpf_get_current_uid_gid();
event.syscall_id = *syscall_id;
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.comm, sizeof(event.comm));
// Canonical ID 21 covers write/writev/pwrite variants. Keep the hot path
// in-kernel and emit only for process names that can satisfy the
// persistence-write host rule.
if (*syscall_id >= 21 && *syscall_id <= 26 &&
!bpf_map_lookup_elem(&monitored_host_comms, event.comm))
return 0;
// Match the Python BCC transport's semantic argument layout rather than
// exposing pointer-only raw ABI slots in alert keys and details.
if (*syscall_id == 3) { // memfd_create(name, flags)
event.args[0] = ctx->args[1];
bpf_probe_read_user_str(event.text, sizeof(event.text),
(const void *)ctx->args[0]);
} else if (*syscall_id == 7 || *syscall_id == 8) { // process_vm_{readv,writev}
event.args[0] = ctx->args[0]; // target pid
event.args[1] = ctx->args[2]; // local iovec count
event.args[2] = ctx->args[4]; // remote iovec count
event.args[3] = ctx->args[5]; // flags
} else if (*syscall_id == 14) { // chmod(path, mode)
event.args[0] = ctx->args[1];
event.args[2] = (u64)-100; // AT_FDCWD
bpf_probe_read_user_str(event.text, sizeof(event.text),
(const void *)ctx->args[0]);
} else if (*syscall_id == 15) { // fchmodat(dirfd, path, mode)
event.args[0] = ctx->args[2];
event.args[2] = ctx->args[0];
bpf_probe_read_user_str(event.text, sizeof(event.text),
(const void *)ctx->args[1]);
} else if (*syscall_id == 16 || *syscall_id == 17) { // chown/lchown(path, uid, gid)
event.args[0] = ctx->args[1];
event.args[1] = ctx->args[2];
event.args[2] = (u64)-100; // AT_FDCWD
bpf_probe_read_user_str(event.text, sizeof(event.text),
(const void *)ctx->args[0]);
} else if (*syscall_id == 18) { // fchownat(dirfd, path, uid, gid)
event.args[0] = ctx->args[2];
event.args[1] = ctx->args[3];
event.args[2] = ctx->args[0];
bpf_probe_read_user_str(event.text, sizeof(event.text),
(const void *)ctx->args[1]);
} else if (*syscall_id == 19) { // capset(header, data[2])
u32 effective_low = 0;
u32 effective_high = 0;
const char *data = (const char *)ctx->args[1];
bpf_probe_read_user(&effective_low, sizeof(effective_low), data);
bpf_probe_read_user(&effective_high, sizeof(effective_high), data + 12);
event.args[0] = effective_low | ((u64)effective_high << 32);
} else if (*syscall_id == 22 || *syscall_id == 23) { // connect/bind(fd, sockaddr, len)
const char *address = (const char *)ctx->args[1];
u16 family = 0;
u16 port = 0;
u32 ipv4 = 0;
bpf_probe_read_user(&family, sizeof(family), address);
bpf_probe_read_user(&port, sizeof(port), address + 2);
event.args[0] = family;
event.args[3] = ctx->args[0];
#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
event.args[1] = __builtin_bswap16(port);
#else
event.args[1] = port;
#endif
if (family == 2) {
bpf_probe_read_user(&ipv4, sizeof(ipv4), address + 4);
event.args[2] = ipv4;
} else if (family == 10) {
bpf_probe_read_user(event.text, 16, address + 8);
}
} else if (*syscall_id >= 24 && *syscall_id <= 26) { // listen/accept/accept4
event.args[3] = ctx->args[0];
} else {
#pragma unroll
for (int i = 0; i < 6; i++)
event.args[i] = ctx->args[i];
}
if (*syscall_id >= 21 && *syscall_id <= 26) {
u64 pid_tgid = bpf_get_current_pid_tgid();
bpf_map_update_elem(&pending_returns, &pid_tgid, &event, 0);
return 0;
}
bpf_perf_event_output(ctx, &syscall_events, BPF_F_CURRENT_CPU, &event, sizeof(event));
return 0;
}
SEC("tracepoint/raw_syscalls/sys_exit")
int trace_sys_exit(struct trace_event_raw_sys_exit *ctx)
{
u64 pid_tgid = bpf_get_current_pid_tgid();
struct syscall_event *event = bpf_map_lookup_elem(&pending_returns, &pid_tgid);
if (!event)
return 0;
if (event->syscall_id == 25 || event->syscall_id == 26)
event->args[3] = ctx->ret;
// Every write-family syscall returns its byte count, so the shared
// canonical event is confirmed only when at least one byte was written.
if ((event->syscall_id == 21 && ctx->ret > 0) ||
(event->syscall_id >= 22 && event->syscall_id <= 24 && ctx->ret == 0) ||
((event->syscall_id == 25 || event->syscall_id == 26) && ctx->ret >= 0))
bpf_perf_event_output(ctx, &syscall_events, BPF_F_CURRENT_CPU,
event, sizeof(*event));
bpf_map_delete_elem(&pending_returns, &pid_tgid);
return 0;
}
char LICENSE[] SEC("license") = "GPL";