Skip to content

Instantly share code, notes, and snippets.

@pchaigno
Created June 19, 2019 11:55
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save pchaigno/59c6044fd3753022c6248c1ba7ad9cbd to your computer and use it in GitHub Desktop.
Save pchaigno/59c6044fd3753022c6248c1ba7ad9cbd to your computer and use it in GitHub Desktop.
Trace seccomp filtering using bcc
#!/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