Chromium Code Reviews| Index: sandbox/linux/seccomp-bpf/syscall.cc |
| diff --git a/sandbox/linux/seccomp-bpf/syscall.cc b/sandbox/linux/seccomp-bpf/syscall.cc |
| index fd599e893b2b7d3b3fdefe81dfcfeb8dd17717d4..40882fffe26e79b0b0fd58bf8f5a303e27e7d344 100644 |
| --- a/sandbox/linux/seccomp-bpf/syscall.cc |
| +++ b/sandbox/linux/seccomp-bpf/syscall.cc |
| @@ -168,6 +168,54 @@ namespace sandbox { |
| #endif |
| ".fnend\n" |
| "9:.size SyscallAsm, 9b-SyscallAsm\n" |
| +#elif defined(__mips__) |
| + ".text\n" |
| + ".align 4\n" |
| + ".type SyscallAsm, @function\n" |
| + "SyscallAsm:.ent SyscallAsm\n" |
| + ".frame $sp, 32, $ra\n" |
| + ".set push\n" |
| + ".set noreorder\n" |
| + "addiu $sp, $sp, -32\n" |
| + "sw $ra, 28($sp)\n" |
| + // Check if "v0" is negative. If so, do not attempt to make a |
| + // system call. Instead, compute the return address that is visible |
| + // to the kernel after we execute "syscall". This address can be |
| + // used as a marker that BPF code inspects. |
| + "bgez $v0, 1f\n" |
| + " nop\n" |
| + "la $v0, 2f\n" |
| + "b 2f\n" |
| + " addiu $v0, -12\n" |
| + // On MIPS first four arguments go to registers a0 - a3 and any |
| + // argument after that goes to stack. We can go ahead and directly |
| + // copy the entries from the arguments array into the appropriate |
| + // CPU registers and on the stack. |
| + "1:lw $t0, 20($a0)\n" |
| + "sw $t0, 20($sp)\n" |
| + "lw $t0, 16($a0)\n" |
| + "sw $t0, 16($sp)\n" |
| + "lw $a3, 12($a0)\n" |
| + "lw $a2, 8($a0)\n" |
| + "lw $a1, 4($a0)\n" |
| + "lw $a0, 0($a0)\n" |
| + // Enter the kernel |
| + "syscall\n" |
| + // Return value is in v0 instead of syscall number. |
| + "beqz $a3, 2f\n" |
| + " nop\n" |
| + // On error, MIPS returns errno from syscall instead of -errno. |
| + // The purpose of this negation is for SyscallAsm to behave |
| + // more like it would on other architectures. |
| + "subu $v0, $zero, $v0\n" |
|
jln (very slow on Chromium)
2014/05/28 00:06:57
How about doing this negation in C, later.
We cou
nedeljko
2014/05/29 14:06:45
I created SandboxSyscallRaw() as you suggested, bu
nedeljko
2014/05/29 14:06:45
Done.
|
| + // This is our "magic" return address that the BPF filter sees. |
| + // Restore the return address from the stack. |
| + "2:lw $ra, 28($sp)\n" |
| + "jr $ra\n" |
| + " addiu $sp, $sp, 32\n" |
| + ".set pop\n" |
| + ".end SyscallAsm\n" |
| + ".size SyscallAsm,.-SyscallAsm\n" |
| #endif |
| ); // asm |
| @@ -233,6 +281,21 @@ intptr_t SandboxSyscall(int nr, |
| ); |
| ret = inout; |
| } |
| +#elif defined(__mips__) |
| + // In register v0 is syscall number before the call and |
| + // return value from SyscallAsm after the call |
| + register intptr_t ret __asm__("v0") = nr; |
| + { |
| + register const intptr_t *data __asm__("a0") = args; |
| + asm volatile( |
| + "la $t9, SyscallAsm\n" |
| + "jalr $t9\n" |
| + " nop\n" |
| + : "=r"(ret) |
| + : "0"(ret), "r"(data) |
| + : "memory", "ra", "t9" |
| + ); |
| + } |
| #else |
| errno = ENOSYS; |
| intptr_t ret = -1; |