| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "sandbox/linux/seccomp-bpf/syscall.h" | 5 #include "sandbox/linux/seccomp-bpf/syscall.h" |
| 6 | 6 |
| 7 #include <errno.h> | 7 #include <errno.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| (...skipping 172 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 183 "2:ldmfd sp!, {fp, pc}\n" | 183 "2:ldmfd sp!, {fp, pc}\n" |
| 184 #endif | 184 #endif |
| 185 #if !defined(__native_client_nonsfi__) | 185 #if !defined(__native_client_nonsfi__) |
| 186 // Do not use .fnstart and .fnend for PNaCl toolchain. See above comment, | 186 // Do not use .fnstart and .fnend for PNaCl toolchain. See above comment, |
| 187 // for more details. | 187 // for more details. |
| 188 ".fnend\n" | 188 ".fnend\n" |
| 189 #endif | 189 #endif |
| 190 "9:.size SyscallAsm, 9b-SyscallAsm\n" | 190 "9:.size SyscallAsm, 9b-SyscallAsm\n" |
| 191 #elif defined(__mips__) | 191 #elif defined(__mips__) |
| 192 ".text\n" | 192 ".text\n" |
| 193 ".option pic2\n" |
| 193 ".align 4\n" | 194 ".align 4\n" |
| 195 ".global SyscallAsm\n" |
| 194 ".type SyscallAsm, @function\n" | 196 ".type SyscallAsm, @function\n" |
| 195 "SyscallAsm:.ent SyscallAsm\n" | 197 "SyscallAsm:.ent SyscallAsm\n" |
| 196 ".frame $sp, 40, $ra\n" | 198 ".frame $sp, 40, $ra\n" |
| 197 ".set push\n" | 199 ".set push\n" |
| 198 ".set noreorder\n" | 200 ".set noreorder\n" |
| 201 ".cpload $t9\n" |
| 199 "addiu $sp, $sp, -40\n" | 202 "addiu $sp, $sp, -40\n" |
| 200 "sw $ra, 36($sp)\n" | 203 "sw $ra, 36($sp)\n" |
| 201 // Check if "v0" is negative. If so, do not attempt to make a | 204 // Check if "v0" is negative. If so, do not attempt to make a |
| 202 // system call. Instead, compute the return address that is visible | 205 // system call. Instead, compute the return address that is visible |
| 203 // to the kernel after we execute "syscall". This address can be | 206 // to the kernel after we execute "syscall". This address can be |
| 204 // used as a marker that BPF code inspects. | 207 // used as a marker that BPF code inspects. |
| 205 "bgez $v0, 1f\n" | 208 "bgez $v0, 1f\n" |
| 206 " nop\n" | 209 " nop\n" |
| 207 "la $v0, 2f\n" | 210 // This is equivalent to "la $v0, 2f". |
| 211 // LA macro has to be avoided since LLVM-AS has issue with LA in PIC mode |
| 212 // https://llvm.org/bugs/show_bug.cgi?id=27644 |
| 213 "lw $v0, %got(2f)($gp)\n" |
| 214 "addiu $v0, $v0, %lo(2f)\n" |
| 208 "b 2f\n" | 215 "b 2f\n" |
| 209 " nop\n" | 216 " nop\n" |
| 210 // On MIPS first four arguments go to registers a0 - a3 and any | 217 // On MIPS first four arguments go to registers a0 - a3 and any |
| 211 // argument after that goes to stack. We can go ahead and directly | 218 // argument after that goes to stack. We can go ahead and directly |
| 212 // copy the entries from the arguments array into the appropriate | 219 // copy the entries from the arguments array into the appropriate |
| 213 // CPU registers and on the stack. | 220 // CPU registers and on the stack. |
| 214 "1:lw $a3, 28($a0)\n" | 221 "1:lw $a3, 28($a0)\n" |
| 215 "lw $a2, 24($a0)\n" | 222 "lw $a2, 24($a0)\n" |
| 216 "lw $a1, 20($a0)\n" | 223 "lw $a1, 20($a0)\n" |
| 217 "lw $t0, 16($a0)\n" | 224 "lw $t0, 16($a0)\n" |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 255 "2:ret\n" | 262 "2:ret\n" |
| 256 ".cfi_endproc\n" | 263 ".cfi_endproc\n" |
| 257 ".size SyscallAsm, .-SyscallAsm\n" | 264 ".size SyscallAsm, .-SyscallAsm\n" |
| 258 #endif | 265 #endif |
| 259 ); // asm | 266 ); // asm |
| 260 | 267 |
| 261 #if defined(__x86_64__) | 268 #if defined(__x86_64__) |
| 262 extern "C" { | 269 extern "C" { |
| 263 intptr_t SyscallAsm(intptr_t nr, const intptr_t args[6]); | 270 intptr_t SyscallAsm(intptr_t nr, const intptr_t args[6]); |
| 264 } | 271 } |
| 272 #elif defined(__mips__) |
| 273 extern "C" { |
| 274 intptr_t SyscallAsm(intptr_t nr, const intptr_t args[8]); |
| 275 } |
| 265 #endif | 276 #endif |
| 266 | 277 |
| 267 } // namespace | 278 } // namespace |
| 268 | 279 |
| 269 intptr_t Syscall::InvalidCall() { | 280 intptr_t Syscall::InvalidCall() { |
| 270 // Explicitly pass eight zero arguments just in case. | 281 // Explicitly pass eight zero arguments just in case. |
| 271 return Call(kInvalidSyscallNumber, 0, 0, 0, 0, 0, 0, 0, 0); | 282 return Call(kInvalidSyscallNumber, 0, 0, 0, 0, 0, 0, 0, 0); |
| 272 } | 283 } |
| 273 | 284 |
| 274 intptr_t Syscall::Call(int nr, | 285 intptr_t Syscall::Call(int nr, |
| (...skipping 113 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 388 SECCOMP_PARM4(ctx) = 0; | 399 SECCOMP_PARM4(ctx) = 0; |
| 389 #endif | 400 #endif |
| 390 SECCOMP_RESULT(ctx) = static_cast<greg_t>(ret_val); | 401 SECCOMP_RESULT(ctx) = static_cast<greg_t>(ret_val); |
| 391 } | 402 } |
| 392 | 403 |
| 393 #if defined(__mips__) | 404 #if defined(__mips__) |
| 394 intptr_t Syscall::SandboxSyscallRaw(int nr, | 405 intptr_t Syscall::SandboxSyscallRaw(int nr, |
| 395 const intptr_t* args, | 406 const intptr_t* args, |
| 396 intptr_t* err_ret) { | 407 intptr_t* err_ret) { |
| 397 register intptr_t ret __asm__("v0") = nr; | 408 register intptr_t ret __asm__("v0") = nr; |
| 409 register intptr_t syscallasm __asm__("t9") = (intptr_t) &SyscallAsm; |
| 398 // a3 register becomes non zero on error. | 410 // a3 register becomes non zero on error. |
| 399 register intptr_t err_stat __asm__("a3") = 0; | 411 register intptr_t err_stat __asm__("a3") = 0; |
| 400 { | 412 { |
| 401 register const intptr_t* data __asm__("a0") = args; | 413 register const intptr_t* data __asm__("a0") = args; |
| 402 asm volatile( | 414 asm volatile( |
| 403 "la $t9, SyscallAsm\n" | |
| 404 "jalr $t9\n" | 415 "jalr $t9\n" |
| 405 " nop\n" | 416 " nop\n" |
| 406 : "=r"(ret), "=r"(err_stat) | 417 : "=r"(ret), "=r"(err_stat) |
| 407 : "0"(ret), | 418 : "0"(ret), |
| 408 "r"(data) | 419 "r"(data), |
| 420 "r"(syscallasm) |
| 409 // a2 is in the clober list so inline assembly can not change its | 421 // a2 is in the clober list so inline assembly can not change its |
| 410 // value. | 422 // value. |
| 411 : "memory", "ra", "t9", "a2"); | 423 : "memory", "ra", "a2"); |
| 412 } | 424 } |
| 413 | 425 |
| 414 // Set an error status so it can be used outside of this function | 426 // Set an error status so it can be used outside of this function |
| 415 *err_ret = err_stat; | 427 *err_ret = err_stat; |
| 416 | 428 |
| 417 return ret; | 429 return ret; |
| 418 } | 430 } |
| 419 #endif // defined(__mips__) | 431 #endif // defined(__mips__) |
| 420 | 432 |
| 421 } // namespace sandbox | 433 } // namespace sandbox |
| OLD | NEW |