diff options
author | Jamie Liu <jamieliu@google.com> | 2019-02-19 15:48:39 -0800 |
---|---|---|
committer | Shentubot <shentubot@google.com> | 2019-02-19 15:49:37 -0800 |
commit | bed6f8534b1bedaad031682fe052b5a46d9cb3ee (patch) | |
tree | 2afde5a57295904c0a89e7a7de7e8be847939c41 | |
parent | fd50504a3a7e5747c7ef459ef316b43dfc866841 (diff) |
Set rax to syscall number on SECCOMP_RET_TRAP.
PiperOrigin-RevId: 234690475
Change-Id: I1cbfb5aecd4697a4a26ec8524354aa8656cc3ba1
-rw-r--r-- | pkg/sentry/kernel/seccomp.go | 3 | ||||
-rw-r--r-- | test/syscalls/linux/seccomp.cc | 53 |
2 files changed, 36 insertions, 20 deletions
diff --git a/pkg/sentry/kernel/seccomp.go b/pkg/sentry/kernel/seccomp.go index cec179246..4bed4d373 100644 --- a/pkg/sentry/kernel/seccomp.go +++ b/pkg/sentry/kernel/seccomp.go @@ -75,6 +75,9 @@ func (t *Task) checkSeccompSyscall(sysno int32, args arch.SyscallArguments, ip u // portion of the return value will be passed as si_errno." - // Documentation/prctl/seccomp_filter.txt t.SendSignal(seccompSiginfo(t, int32(result.Data()), sysno, ip)) + // "The return value register will contain an arch-dependent value." In + // practice, it's ~always the syscall number. + t.Arch().SetReturn(uintptr(sysno)) case linux.SECCOMP_RET_ERRNO: // "Results in the lower 16-bits of the return value being passed to diff --git a/test/syscalls/linux/seccomp.cc b/test/syscalls/linux/seccomp.cc index ac416b75f..27740d7ef 100644 --- a/test/syscalls/linux/seccomp.cc +++ b/test/syscalls/linux/seccomp.cc @@ -23,6 +23,7 @@ #include <sys/prctl.h> #include <sys/syscall.h> #include <time.h> +#include <ucontext.h> #include <unistd.h> #include <atomic> @@ -161,16 +162,21 @@ TEST(SeccompTest, RetTrapCausesSIGSYS) { pid_t const pid = fork(); if (pid == 0) { constexpr uint16_t kTrapValue = 0xdead; - RegisterSignalHandler(SIGSYS, +[](int signo, siginfo_t* info, void*) { - // This is a signal handler, so we must stay async-signal-safe. - TEST_CHECK(info->si_signo == SIGSYS); - TEST_CHECK(info->si_code == SYS_SECCOMP); - TEST_CHECK(info->si_errno == kTrapValue); - TEST_CHECK(info->si_call_addr != nullptr); - TEST_CHECK(info->si_syscall == kFilteredSyscall); - TEST_CHECK(info->si_arch == AUDIT_ARCH_X86_64); - _exit(0); - }); + RegisterSignalHandler( + SIGSYS, +[](int signo, siginfo_t* info, void* ucv) { + ucontext_t* uc = static_cast<ucontext_t*>(ucv); + // This is a signal handler, so we must stay async-signal-safe. + TEST_CHECK(info->si_signo == SIGSYS); + TEST_CHECK(info->si_code == SYS_SECCOMP); + TEST_CHECK(info->si_errno == kTrapValue); + TEST_CHECK(info->si_call_addr != nullptr); + TEST_CHECK(info->si_syscall == kFilteredSyscall); +#ifdef __x86_64__ + TEST_CHECK(info->si_arch == AUDIT_ARCH_X86_64); + TEST_CHECK(uc->uc_mcontext.gregs[REG_RAX] == kFilteredSyscall); +#endif // defined(__x86_64__) + _exit(0); + }); ApplySeccompFilter(kFilteredSyscall, SECCOMP_RET_TRAP | kTrapValue); syscall(kFilteredSyscall); TEST_CHECK_MSG(false, "Survived invocation of test syscall"); @@ -182,6 +188,8 @@ TEST(SeccompTest, RetTrapCausesSIGSYS) { << "status " << status; } +#ifdef __x86_64__ + constexpr uint64_t kVsyscallTimeEntry = 0xffffffffff600400; time_t vsyscall_time(time_t* t) { @@ -194,16 +202,19 @@ TEST(SeccompTest, SeccompAppliesToVsyscall) { pid_t const pid = fork(); if (pid == 0) { constexpr uint16_t kTrapValue = 0xdead; - RegisterSignalHandler(SIGSYS, +[](int signo, siginfo_t* info, void*) { - // This is a signal handler, so we must stay async-signal-safe. - TEST_CHECK(info->si_signo == SIGSYS); - TEST_CHECK(info->si_code == SYS_SECCOMP); - TEST_CHECK(info->si_errno == kTrapValue); - TEST_CHECK(info->si_call_addr != nullptr); - TEST_CHECK(info->si_syscall == SYS_time); - TEST_CHECK(info->si_arch == AUDIT_ARCH_X86_64); - _exit(0); - }); + RegisterSignalHandler( + SIGSYS, +[](int signo, siginfo_t* info, void* ucv) { + ucontext_t* uc = static_cast<ucontext_t*>(ucv); + // This is a signal handler, so we must stay async-signal-safe. + TEST_CHECK(info->si_signo == SIGSYS); + TEST_CHECK(info->si_code == SYS_SECCOMP); + TEST_CHECK(info->si_errno == kTrapValue); + TEST_CHECK(info->si_call_addr != nullptr); + TEST_CHECK(info->si_syscall == SYS_time); + TEST_CHECK(info->si_arch == AUDIT_ARCH_X86_64); + TEST_CHECK(uc->uc_mcontext.gregs[REG_RAX] == SYS_time); + _exit(0); + }); ApplySeccompFilter(SYS_time, SECCOMP_RET_TRAP | kTrapValue); vsyscall_time(nullptr); // Should result in death. TEST_CHECK_MSG(false, "Survived invocation of test syscall"); @@ -234,6 +245,8 @@ TEST(SeccompTest, RetKillVsyscallCausesDeathBySIGSYS) { << "status " << status; } +#endif // defined(__x86_64__) + TEST(SeccompTest, RetTraceWithoutPtracerReturnsENOSYS) { pid_t const pid = fork(); if (pid == 0) { |