| 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 <asm/unistd.h> | 7 #include <asm/unistd.h> |
| 8 #include <errno.h> | 8 #include <errno.h> |
| 9 | 9 |
| 10 #include "base/basictypes.h" | 10 #include "base/basictypes.h" |
| (...skipping 71 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 82 "pop %edi; .cfi_restore edi; .cfi_adjust_cfa_offset -4\n" | 82 "pop %edi; .cfi_restore edi; .cfi_adjust_cfa_offset -4\n" |
| 83 "pop %esi; .cfi_restore esi; .cfi_adjust_cfa_offset -4\n" | 83 "pop %esi; .cfi_restore esi; .cfi_adjust_cfa_offset -4\n" |
| 84 "ret\n" | 84 "ret\n" |
| 85 ".cfi_endproc\n" | 85 ".cfi_endproc\n" |
| 86 "9:.size SyscallAsm, 9b-SyscallAsm\n" | 86 "9:.size SyscallAsm, 9b-SyscallAsm\n" |
| 87 #elif defined(__x86_64__) | 87 #elif defined(__x86_64__) |
| 88 ".text\n" | 88 ".text\n" |
| 89 ".align 16, 0x90\n" | 89 ".align 16, 0x90\n" |
| 90 ".type SyscallAsm, @function\n" | 90 ".type SyscallAsm, @function\n" |
| 91 "SyscallAsm:.cfi_startproc\n" | 91 "SyscallAsm:.cfi_startproc\n" |
| 92 // Check if "%rax" is negative. If so, do not attempt to make a | 92 // Check if "%rdi" is negative. If so, do not attempt to make a |
| 93 // system call. Instead, compute the return address that is visible | 93 // system call. Instead, compute the return address that is visible |
| 94 // to the kernel after we execute "syscall". This address can be | 94 // to the kernel after we execute "syscall". This address can be |
| 95 // used as a marker that BPF code inspects. | 95 // used as a marker that BPF code inspects. |
| 96 "test %rax, %rax\n" | 96 "test %rdi, %rdi\n" |
| 97 "jge 1f\n" | 97 "jge 1f\n" |
| 98 // Always make sure that our code is position-independent, or the | 98 // Always make sure that our code is position-independent, or the |
| 99 // linker will throw a hissy fit on x86-64. | 99 // linker will throw a hissy fit on x86-64. |
| 100 "call 0f; .cfi_adjust_cfa_offset 8\n" | 100 "lea 2f(%rip), %rax\n" |
| 101 "0:pop %rax; .cfi_adjust_cfa_offset -8\n" | |
| 102 "addq $2f-0b, %rax\n" | |
| 103 "ret\n" | 101 "ret\n" |
| 104 // We declared all clobbered registers to the compiler. On x86-64, | 102 // Now we load the registers used to pass arguments to the system |
| 105 // there really isn't much of a problem with register pressure. So, | 103 // call: system call number in %rax, and arguments in %rdi, %rsi, |
| 106 // we can go ahead and directly copy the entries from the arguments | 104 // %rdx, %r10, %r8, %r9. Note: These are all caller-save registers |
| 107 // array into the appropriate CPU registers. | 105 // (only %rbx, %rbp, %rsp, and %r12-%r15 are callee-save), so no |
| 108 "1:movq 0(%r12), %rdi\n" | 106 // need to worry here about spilling registers or CFI directives. |
| 109 "movq 8(%r12), %rsi\n" | 107 "1:movq %rdi, %rax\n" |
| 110 "movq 16(%r12), %rdx\n" | 108 "movq 0(%rsi), %rdi\n" |
| 111 "movq 24(%r12), %r10\n" | 109 "movq 16(%rsi), %rdx\n" |
| 112 "movq 32(%r12), %r8\n" | 110 "movq 24(%rsi), %r10\n" |
| 113 "movq 40(%r12), %r9\n" | 111 "movq 32(%rsi), %r8\n" |
| 112 "movq 40(%rsi), %r9\n" |
| 113 "movq 8(%rsi), %rsi\n" |
| 114 // Enter the kernel. | 114 // Enter the kernel. |
| 115 "syscall\n" | 115 "syscall\n" |
| 116 // This is our "magic" return address that the BPF filter sees. | 116 // This is our "magic" return address that the BPF filter sees. |
| 117 "2:ret\n" | 117 "2:ret\n" |
| 118 ".cfi_endproc\n" | 118 ".cfi_endproc\n" |
| 119 "9:.size SyscallAsm, 9b-SyscallAsm\n" | 119 "9:.size SyscallAsm, 9b-SyscallAsm\n" |
| 120 #elif defined(__arm__) | 120 #elif defined(__arm__) |
| 121 // Throughout this file, we use the same mode (ARM vs. thumb) | 121 // Throughout this file, we use the same mode (ARM vs. thumb) |
| 122 // that the C++ compiler uses. This means, when transfering control | 122 // that the C++ compiler uses. This means, when transfering control |
| 123 // from C++ to assembly code, we do not need to switch modes (e.g. | 123 // from C++ to assembly code, we do not need to switch modes (e.g. |
| (...skipping 119 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 243 "mov x8, x0\n" | 243 "mov x8, x0\n" |
| 244 "ldr x0, [x6, #0]\n" | 244 "ldr x0, [x6, #0]\n" |
| 245 // Enter the kernel | 245 // Enter the kernel |
| 246 "svc 0\n" | 246 "svc 0\n" |
| 247 "2:ret\n" | 247 "2:ret\n" |
| 248 ".cfi_endproc\n" | 248 ".cfi_endproc\n" |
| 249 ".size SyscallAsm, .-SyscallAsm\n" | 249 ".size SyscallAsm, .-SyscallAsm\n" |
| 250 #endif | 250 #endif |
| 251 ); // asm | 251 ); // asm |
| 252 | 252 |
| 253 #if defined(__x86_64__) |
| 254 extern "C" { |
| 255 intptr_t SyscallAsm(intptr_t nr, const intptr_t args[6]); |
| 256 } |
| 257 #endif |
| 258 |
| 253 } // namespace | 259 } // namespace |
| 254 | 260 |
| 255 intptr_t Syscall::InvalidCall() { | 261 intptr_t Syscall::InvalidCall() { |
| 256 // Explicitly pass eight zero arguments just in case. | 262 // Explicitly pass eight zero arguments just in case. |
| 257 return Call(kInvalidSyscallNumber, 0, 0, 0, 0, 0, 0, 0, 0); | 263 return Call(kInvalidSyscallNumber, 0, 0, 0, 0, 0, 0, 0, 0); |
| 258 } | 264 } |
| 259 | 265 |
| 260 intptr_t Syscall::Call(int nr, | 266 intptr_t Syscall::Call(int nr, |
| 261 intptr_t p0, | 267 intptr_t p0, |
| 262 intptr_t p1, | 268 intptr_t p1, |
| (...skipping 30 matching lines...) Expand all Loading... |
| 293 // output, and clobbered registers. | 299 // output, and clobbered registers. |
| 294 #if defined(__i386__) | 300 #if defined(__i386__) |
| 295 intptr_t ret = nr; | 301 intptr_t ret = nr; |
| 296 asm volatile( | 302 asm volatile( |
| 297 "call SyscallAsm\n" | 303 "call SyscallAsm\n" |
| 298 // N.B. These are not the calling conventions normally used by the ABI. | 304 // N.B. These are not the calling conventions normally used by the ABI. |
| 299 : "=a"(ret) | 305 : "=a"(ret) |
| 300 : "0"(ret), "D"(args) | 306 : "0"(ret), "D"(args) |
| 301 : "cc", "esp", "memory", "ecx", "edx"); | 307 : "cc", "esp", "memory", "ecx", "edx"); |
| 302 #elif defined(__x86_64__) | 308 #elif defined(__x86_64__) |
| 303 intptr_t ret = nr; | 309 intptr_t ret = SyscallAsm(nr, args); |
| 304 { | |
| 305 register const intptr_t* data __asm__("r12") = args; | |
| 306 asm volatile( | |
| 307 "lea -128(%%rsp), %%rsp\n" // Avoid red zone. | |
| 308 "call SyscallAsm\n" | |
| 309 "lea 128(%%rsp), %%rsp\n" | |
| 310 // N.B. These are not the calling conventions normally used by the ABI. | |
| 311 : "=a"(ret) | |
| 312 : "0"(ret), "r"(data) | |
| 313 : "cc", | |
| 314 "rsp", | |
| 315 "memory", | |
| 316 "rcx", | |
| 317 "rdi", | |
| 318 "rsi", | |
| 319 "rdx", | |
| 320 "r8", | |
| 321 "r9", | |
| 322 "r10", | |
| 323 "r11"); | |
| 324 } | |
| 325 #elif defined(__arm__) | 310 #elif defined(__arm__) |
| 326 intptr_t ret; | 311 intptr_t ret; |
| 327 { | 312 { |
| 328 register intptr_t inout __asm__("r0") = nr; | 313 register intptr_t inout __asm__("r0") = nr; |
| 329 register const intptr_t* data __asm__("r6") = args; | 314 register const intptr_t* data __asm__("r6") = args; |
| 330 asm volatile( | 315 asm volatile( |
| 331 "bl SyscallAsm\n" | 316 "bl SyscallAsm\n" |
| 332 // N.B. These are not the calling conventions normally used by the ABI. | 317 // N.B. These are not the calling conventions normally used by the ABI. |
| 333 : "=r"(inout) | 318 : "=r"(inout) |
| 334 : "0"(inout), "r"(data) | 319 : "0"(inout), "r"(data) |
| (...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 419 } | 404 } |
| 420 | 405 |
| 421 // Set an error status so it can be used outside of this function | 406 // Set an error status so it can be used outside of this function |
| 422 *err_ret = err_stat; | 407 *err_ret = err_stat; |
| 423 | 408 |
| 424 return ret; | 409 return ret; |
| 425 } | 410 } |
| 426 #endif // defined(__mips__) | 411 #endif // defined(__mips__) |
| 427 | 412 |
| 428 } // namespace sandbox | 413 } // namespace sandbox |
| OLD | NEW |