| OLD | NEW |
| (Empty) |
| 1 // Copyright (c) 2010 The Chromium Authors. All rights reserved. | |
| 2 // Use of this source code is governed by a BSD-style license that can be | |
| 3 // found in the LICENSE file. | |
| 4 | |
| 5 #include "debug.h" | |
| 6 #include "sandbox_impl.h" | |
| 7 | |
| 8 namespace playground { | |
| 9 | |
| 10 // If the sandboxed process tries to mask SIGSEGV, there is a good chance | |
| 11 // the process will eventually get terminated. If this is really ever a | |
| 12 // problem, we can hide the fact that SIGSEGV is unmasked. But I don't think | |
| 13 // we really need this. Masking of synchronous signals is rarely necessary. | |
| 14 | |
| 15 #if defined(__NR_sigprocmask) | |
| 16 long Sandbox::sandbox_sigprocmask(int how, const void* set, void* old_set) { | |
| 17 long long tm; | |
| 18 Debug::syscall(&tm, __NR_sigprocmask, "Executing handler"); | |
| 19 | |
| 20 // Access the signal mask by triggering a SEGV and modifying the signal state | |
| 21 // prior to calling rt_sigreturn(). | |
| 22 long res = -ENOSYS; | |
| 23 #if defined(__x86_64__) | |
| 24 #error x86-64 does not support sigprocmask(); use rt_sigprocmask() instead | |
| 25 #elif defined(__i386__) | |
| 26 asm volatile( | |
| 27 "push %%ebx\n" | |
| 28 "movl %2, %%ebx\n" | |
| 29 "int $0\n" | |
| 30 "pop %%ebx\n" | |
| 31 : "=a"(res) | |
| 32 : "0"(__NR_sigprocmask), "ri"((long)how), | |
| 33 "c"((long)set), "d"((long)old_set) | |
| 34 : "esp", "memory"); | |
| 35 #else | |
| 36 #error Unsupported target platform | |
| 37 #endif | |
| 38 | |
| 39 // Update our shadow signal mask, so that we can copy it upon creation of | |
| 40 // new threads. | |
| 41 if (res == 0 && set != NULL) { | |
| 42 SecureMem::Args* args = getSecureMem(); | |
| 43 switch (how) { | |
| 44 case SIG_BLOCK: | |
| 45 *(unsigned long long *)&args->signalMask |= *(unsigned long long *)set; | |
| 46 break; | |
| 47 case SIG_UNBLOCK: | |
| 48 *(unsigned long long *)&args->signalMask &= ~*(unsigned long long *)set; | |
| 49 break; | |
| 50 case SIG_SETMASK: | |
| 51 *(unsigned long long *)&args->signalMask = *(unsigned long long *)set; | |
| 52 break; | |
| 53 default: | |
| 54 break; | |
| 55 } | |
| 56 } | |
| 57 | |
| 58 Debug::elapsed(tm, __NR_sigprocmask); | |
| 59 | |
| 60 return res; | |
| 61 } | |
| 62 #endif | |
| 63 | |
| 64 #if defined(__NR_rt_sigprocmask) | |
| 65 long Sandbox::sandbox_rt_sigprocmask(int how, const void* set, void* old_set, | |
| 66 size_t bytes) { | |
| 67 long long tm; | |
| 68 Debug::syscall(&tm, __NR_rt_sigprocmask, "Executing handler"); | |
| 69 | |
| 70 // Access the signal mask by triggering a SEGV and modifying the signal state | |
| 71 // prior to calling rt_sigreturn(). | |
| 72 long res = -ENOSYS; | |
| 73 #if defined(__x86_64__) | |
| 74 asm volatile( | |
| 75 "movq %5, %%r10\n" | |
| 76 "int $0\n" | |
| 77 : "=a"(res) | |
| 78 : "0"(__NR_rt_sigprocmask), "D"((long)how), | |
| 79 "S"((long)set), "d"((long)old_set), "r"((long)bytes) | |
| 80 : "r10", "r11", "rcx", "memory"); | |
| 81 #elif defined(__i386__) | |
| 82 asm volatile( | |
| 83 "push %%ebx\n" | |
| 84 "movl %2, %%ebx\n" | |
| 85 "int $0\n" | |
| 86 "pop %%ebx\n" | |
| 87 : "=a"(res) | |
| 88 : "0"(__NR_rt_sigprocmask), "ri"((long)how), | |
| 89 "c"((long)set), "d"((long)old_set), "S"((long)bytes) | |
| 90 : "esp", "memory"); | |
| 91 #else | |
| 92 #error Unsupported target platform | |
| 93 #endif | |
| 94 | |
| 95 // Update our shadow signal mask, so that we can copy it upon creation of | |
| 96 // new threads. | |
| 97 if (res == 0 && set != NULL && bytes >= 8) { | |
| 98 SecureMem::Args* args = getSecureMem(); | |
| 99 switch (how) { | |
| 100 case SIG_BLOCK: | |
| 101 *(unsigned long long *)&args->signalMask |= *(unsigned long long *)set; | |
| 102 break; | |
| 103 case SIG_UNBLOCK: | |
| 104 *(unsigned long long *)&args->signalMask &= ~*(unsigned long long *)set; | |
| 105 break; | |
| 106 case SIG_SETMASK: | |
| 107 *(unsigned long long *)&args->signalMask = *(unsigned long long *)set; | |
| 108 break; | |
| 109 default: | |
| 110 break; | |
| 111 } | |
| 112 } | |
| 113 | |
| 114 Debug::elapsed(tm, __NR_rt_sigprocmask); | |
| 115 | |
| 116 return res; | |
| 117 } | |
| 118 #endif | |
| 119 | |
| 120 } // namespace | |
| OLD | NEW |