diff --git a/src/GNUmakefile b/src/GNUmakefile index b74b3a3e..bdbcf5ad 100644 --- a/src/GNUmakefile +++ b/src/GNUmakefile @@ -48,6 +48,7 @@ OBJECTS += \ tracee/mem.o \ tracee/reg.o \ tracee/event.o \ + tracee/seccomp.o \ ptrace/ptrace.o \ ptrace/user.o \ ptrace/wait.o \ diff --git a/src/tracee/event.c b/src/tracee/event.c index f419a81e..f8afa761 100644 --- a/src/tracee/event.c +++ b/src/tracee/event.c @@ -36,6 +36,7 @@ #include /* PRI*, */ #include "tracee/event.h" +#include "tracee/seccomp.h" #include "cli/note.h" #include "path/path.h" #include "path/binding.h" @@ -596,23 +597,7 @@ int handle_tracee_event(Tracee *tracee, int tracee_status) siginfo_t siginfo = {}; ptrace(PTRACE_GETSIGINFO, tracee->pid, NULL, &siginfo); if (siginfo.si_code == SYS_SECCOMP) { - /* Set errno to -ENOSYS */ - int sigsys_fetch_status = fetch_regs(tracee); - if (sigsys_fetch_status != 0) { - VERBOSE(tracee, 1, "Couldn't fetch regs on seccomp SIGSYS"); - break; - } - print_current_regs(tracee, 3, "seccomp SIGSYS"); - poke_reg(tracee, SYSARG_RESULT, -ENOSYS); - tracee->restore_original_regs = false; - push_specific_regs(tracee, false); - - /* Swallow signal */ - signal = 0; - - /* Reset status so next SIGTRAP | 0x80 is - * recognized as syscall entry */ - tracee->status = 0; + signal = handle_seccomp_event(tracee); } else { VERBOSE(tracee, 1, "non-seccomp SIGSYS"); } diff --git a/src/tracee/seccomp.c b/src/tracee/seccomp.c new file mode 100644 index 00000000..d9aa8186 --- /dev/null +++ b/src/tracee/seccomp.c @@ -0,0 +1,59 @@ +#include /* E*, */ +#include /* SIGSYS, */ + +#include "cli/note.h" +#include "syscall/chain.h" +#include "tracee/seccomp.h" + + +int handle_seccomp_event(Tracee* tracee) { + + word_t sysnum; + int signal; + word_t instr_pointer; + + signal = SIGSYS; + + int sigsys_fetch_status = fetch_regs(tracee); + if (sigsys_fetch_status != 0) { + VERBOSE(tracee, 1, "Couldn't fetch regs on seccomp SIGSYS"); + return signal; + } + print_current_regs(tracee, 3, "seccomp SIGSYS"); + tracee->restore_original_regs = false; + + sysnum = get_sysnum(tracee, CURRENT); + + switch (sysnum) { + case PR_accept: + set_sysnum(tracee, PR_accept4); + poke_reg(tracee, SYSARG_4, 0); + + /* Move the instruction pointer back to the original trap */ + instr_pointer = peek_reg(tracee, CURRENT, INSTR_POINTER); + poke_reg(tracee, INSTR_POINTER, instr_pointer - SYSTRAP_SIZE); + /* Break as usual on entry to syscall */ + tracee->restart_how = PTRACE_SYSCALL; + push_specific_regs(tracee, true); + + /* Swallow signal */ + signal = 0; + break; + + case PR_set_robust_list: + default: + /* Set errno to -ENOSYS */ + poke_reg(tracee, SYSARG_RESULT, -ENOSYS); + push_specific_regs(tracee, false); + + /* Swallow signal */ + signal = 0; + break; + } + + /* Reset status so next SIGTRAP | 0x80 is + * recognized as syscall entry */ + tracee->status = 0; + + return signal; +} diff --git a/src/tracee/seccomp.h b/src/tracee/seccomp.h new file mode 100644 index 00000000..8796ede2 --- /dev/null +++ b/src/tracee/seccomp.h @@ -0,0 +1,3 @@ +#include "tracee/tracee.h" + +int handle_seccomp_event(Tracee* tracee);