Index: sandbox/linux/seccomp-bpf/trap.cc |
diff --git a/sandbox/linux/seccomp-bpf/trap.cc b/sandbox/linux/seccomp-bpf/trap.cc |
index f8b64c991b0f591c4d82bbb196e22acba7e96ece..690a4f14939eade78b8f7fb287fb91b00fd62088 100644 |
--- a/sandbox/linux/seccomp-bpf/trap.cc |
+++ b/sandbox/linux/seccomp-bpf/trap.cc |
@@ -16,6 +16,7 @@ |
#include "sandbox/linux/seccomp-bpf/codegen.h" |
#include "sandbox/linux/seccomp-bpf/die.h" |
#include "sandbox/linux/seccomp-bpf/syscall.h" |
+#include "sandbox/linux/services/kernel_to_errno.h" |
// Android's signal.h doesn't define ucontext etc. |
#if defined(OS_ANDROID) |
@@ -150,9 +151,20 @@ void Trap::SigSys(int nr, siginfo_t* info, void* void_context) { |
struct arch_sigsys sigsys; |
memcpy(&sigsys, &info->_sifields, sizeof(sigsys)); |
+ bool sigsys_nr_is_bad = true; |
+#if defined(__mips__) |
+ // When indirect syscall (syscall(__NR_foo, ...)) is made on Mips, number |
jln (very slow on Chromium)
2014/05/16 19:30:17
"number" -> "the number"
nedeljko
2014/05/22 17:38:55
Done.
|
+ // in register SECCOMP_SYSCALL(ctx) is always __NR_syscall and real |
jln (very slow on Chromium)
2014/05/16 19:30:17
"real number" -> "the real number"
nedeljko
2014/05/22 17:38:55
Done.
|
+ // number of a syscall (__NR_foo) is in SECCOMP_PARM1(ctx) |
+ sigsys_nr_is_bad = sigsys.nr != static_cast<int>(SECCOMP_SYSCALL(ctx)) && |
+ sigsys.nr != static_cast<int>(SECCOMP_PARM1(ctx)); |
+#else |
+ sigsys_nr_is_bad = sigsys.nr != static_cast<int>(SECCOMP_SYSCALL(ctx)); |
+#endif |
+ |
// Some more sanity checks. |
if (sigsys.ip != reinterpret_cast<void*>(SECCOMP_IP(ctx)) || |
- sigsys.nr != static_cast<int>(SECCOMP_SYSCALL(ctx)) || |
+ sigsys_nr_is_bad || |
sigsys.arch != SECCOMP_ARCH) { |
// TODO(markus): |
// SANDBOX_DIE() can call LOG(FATAL). This is not normally async-signal |
@@ -168,7 +180,7 @@ void Trap::SigSys(int nr, siginfo_t* info, void* void_context) { |
if (sigsys.nr == __NR_clone) { |
RAW_SANDBOX_DIE("Cannot call clone() from an UnsafeTrap() handler."); |
} |
- rc = SandboxSyscall(sigsys.nr, |
+ rc = SandboxSyscall(SECCOMP_SYSCALL(ctx), |
SECCOMP_PARM1(ctx), |
SECCOMP_PARM2(ctx), |
SECCOMP_PARM3(ctx), |
@@ -185,7 +197,8 @@ void Trap::SigSys(int nr, siginfo_t* info, void* void_context) { |
// is what we are showing to TrapFnc callbacks that the system call |
// evaluator registered with the sandbox. |
struct arch_seccomp_data data = { |
- sigsys.nr, SECCOMP_ARCH, reinterpret_cast<uint64_t>(sigsys.ip), |
+ static_cast<int>SECCOMP_SYSCALL(ctx), SECCOMP_ARCH, |
+ reinterpret_cast<uint64_t>(sigsys.ip), |
{static_cast<uint64_t>(SECCOMP_PARM1(ctx)), |
static_cast<uint64_t>(SECCOMP_PARM2(ctx)), |
static_cast<uint64_t>(SECCOMP_PARM3(ctx)), |
@@ -201,7 +214,8 @@ void Trap::SigSys(int nr, siginfo_t* info, void* void_context) { |
// Update the CPU register that stores the return code of the system call |
// that we just handled, and restore "errno" to the value that it had |
// before entering the signal handler. |
- SECCOMP_RESULT(ctx) = static_cast<greg_t>(rc); |
+ SECCOMP_RESULT(ctx) = |
+ static_cast<greg_t>(RetValToKernelRet(static_cast<int>(rc), ctx)); |
jln (very slow on Chromium)
2014/05/16 19:30:17
This is too commplicated. Let's have a function th
nedeljko
2014/05/22 17:38:55
Done.
|
errno = old_errno; |
return; |