Chromium Code Reviews| 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..8f710d033f1ea174f0487886ad3f0264a585804f 100644 |
| --- a/sandbox/linux/seccomp-bpf/trap.cc |
| +++ b/sandbox/linux/seccomp-bpf/trap.cc |
| @@ -15,6 +15,7 @@ |
| #include "base/logging.h" |
| #include "sandbox/linux/seccomp-bpf/codegen.h" |
| #include "sandbox/linux/seccomp-bpf/die.h" |
| +#include "sandbox/linux/seccomp-bpf/kernel_return_value_helpers.h" |
| #include "sandbox/linux/seccomp-bpf/syscall.h" |
| // Android's signal.h doesn't define ucontext etc. |
| @@ -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, the |
| + // number in register SECCOMP_SYSCALL(ctx) is always __NR_syscall and the |
| + // real 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,7 @@ 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); |
| + PutValueInUcontext(static_cast<int>(rc), ctx); |
|
jln (very slow on Chromium)
2014/06/03 01:00:33
You're silently truncating |rc|. This is not corre
nedeljko
2014/06/03 15:32:18
I changed this.
|
| errno = old_errno; |
| return; |