-
-
Save pchaigno/59c6044fd3753022c6248c1ba7ad9cbd to your computer and use it in GitHub Desktop.
Trace seccomp filtering using bcc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/usr/bin/python | |
# Copyright (c) PLUMgrid, Inc. | |
# Licensed under the Apache License, Version 2.0 (the "License") | |
# run in project examples directory with: | |
# sudo ./hello_world.py" | |
# see trace_fields.py for a longer example | |
from bcc import BPF | |
# This may not work for 4.17 on x64, you need replace kprobe__sys_clone with kprobe____x64_sys_clone | |
BPF(text=""" | |
#include <linux/ptrace.h> | |
/** | |
* ptrace_event_enabled - test whether a ptrace event is enabled | |
* @task: ptracee of interest | |
* @event: %PTRACE_EVENT_* to test | |
* | |
* Test whether @event is enabled for ptracee @task. | |
* | |
* Returns %true if @event is enabled, %false otherwise. | |
*/ | |
static inline bool __ptrace_event_enabled(struct task_struct *task, int event) | |
{ | |
return task->ptrace & PT_EVENT_FLAG(event); | |
} | |
struct seccomp_t { | |
int ret_trace; | |
int log; | |
int syscall; | |
int recursive_call; | |
}; | |
BPF_HASH(in_seccomp_filter, u32, struct seccomp_t); | |
int kprobe____seccomp_filter(struct pt_regs *ctx, int this_syscall) { | |
u32 pid = bpf_get_current_pid_tgid(); | |
struct seccomp_t *seccomp = in_seccomp_filter.lookup(&pid); | |
if (seccomp) { | |
seccomp->recursive_call = 2; | |
} else { | |
struct seccomp_t new_seccomp = {0}; | |
new_seccomp.syscall = this_syscall; | |
in_seccomp_filter.update(&pid, &new_seccomp); | |
/* | |
struct task_struct *t = (struct task_struct *)bpf_get_current_task(); | |
bool tracer = __ptrace_event_enabled(t, PTRACE_EVENT_SECCOMP); | |
if (tracer) | |
bpf_trace_printk("__seccomp_filter(...; syscall=%d\\n", this_syscall);*/ | |
} | |
return 0; | |
} | |
int kretprobe____seccomp_filter(struct pt_regs *ctx) { | |
u32 pid = bpf_get_current_pid_tgid(); | |
// if (pid != FILTER_PID) | |
// return 0; | |
struct task_struct *t = (struct task_struct *)bpf_get_current_task(); | |
bool tracer = __ptrace_event_enabled(t, PTRACE_EVENT_SECCOMP); | |
int ret = PT_REGS_RC(ctx); | |
struct seccomp_t *seccomp = in_seccomp_filter.lookup(&pid); | |
if (!seccomp) { | |
bpf_trace_printk("second exit!\\n"); | |
return 0; | |
} | |
if (seccomp->recursive_call == 2) { | |
seccomp->recursive_call = 1; | |
return 0; | |
} | |
if (tracer || ret) | |
bpf_trace_printk("__seccomp_filter(); recurs=%d, log=%d, syscall=%d\\n", seccomp->recursive_call, seccomp->log, seccomp->syscall); | |
in_seccomp_filter.delete(&pid); | |
return 0; | |
} | |
int kprobe__ptrace_notify(struct pt_regs *ctx, int exit_code) { | |
u32 pid = bpf_get_current_pid_tgid(); | |
struct seccomp_t *seccomp = in_seccomp_filter.lookup(&pid); | |
if (seccomp) { | |
int expected_code = (PTRACE_EVENT_SECCOMP << 8) | SIGTRAP; | |
if (expected_code == exit_code) { | |
bpf_trace_printk("ptrace_notify((PTRACE_EVENT_SECCOMP << 8) | SIGTRAP)\\n"); | |
seccomp->ret_trace = 1; | |
} else { | |
bpf_trace_printk("ptrace_notify(%d)\\n", exit_code); | |
} | |
} | |
return 0; | |
} | |
int kprobe__audit_seccomp(struct pt_regs *ctx, unsigned long syscall, long signr, int code) { | |
u32 pid = bpf_get_current_pid_tgid(); | |
struct seccomp_t *seccomp = in_seccomp_filter.lookup(&pid); | |
if (seccomp) { | |
if (syscall == seccomp->syscall) { | |
bpf_trace_printk("audit_seccomp(%d)\\n", code); | |
seccomp->log = 1; | |
} | |
} | |
return 0; | |
} | |
""", debug=0).trace_print() |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment