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 |