OLD | NEW |
1 // Copyright 2014 The Chromium Authors. All rights reserved. | 1 // Copyright 2014 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/services/syscall_wrappers.h" | 5 #include "sandbox/linux/services/syscall_wrappers.h" |
6 | 6 |
7 #include <pthread.h> | 7 #include <pthread.h> |
8 #include <sched.h> | 8 #include <sched.h> |
9 #include <setjmp.h> | 9 #include <setjmp.h> |
10 #include <sys/resource.h> | 10 #include <sys/resource.h> |
(...skipping 133 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
144 // sigset_t is 32 bits, but the Linux ABI uses more. | 144 // sigset_t is 32 bits, but the Linux ABI uses more. |
145 LinuxSigSet linux_value; | 145 LinuxSigSet linux_value; |
146 std::memset(&linux_value, 0, sizeof(LinuxSigSet)); | 146 std::memset(&linux_value, 0, sizeof(LinuxSigSet)); |
147 std::memcpy(&linux_value, set, std::min(sizeof(sigset_t), | 147 std::memcpy(&linux_value, set, std::min(sizeof(sigset_t), |
148 sizeof(LinuxSigSet))); | 148 sizeof(LinuxSigSet))); |
149 | 149 |
150 return syscall(__NR_rt_sigprocmask, how, &linux_value, nullptr, | 150 return syscall(__NR_rt_sigprocmask, how, &linux_value, nullptr, |
151 sizeof(linux_value)); | 151 sizeof(linux_value)); |
152 } | 152 } |
153 | 153 |
154 #if (defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \ | |
155 (defined(ARCH_CPU_X86_FAMILY) && !defined(__clang__))) && \ | |
156 !defined(OS_NACL_NONSFI) | |
157 // If MEMORY_SANITIZER or THREAD_SANITIZER is enabled, it is necessary to call | |
158 // sigaction() here, rather than the direct syscall (sys_sigaction() defined | |
159 // by ourselves). | |
160 // It is because, if MEMORY_SANITIZER or THREAD_SANITIZER is enabled, sigaction | |
161 // is wrapped, and |act->sa_handler| is injected in order to unpoisonize the | |
162 // memory passed via callback's arguments for MEMORY_SANITIZER, or handle | |
163 // signals to check thread consistency for THREAD_SANITIZER. Please see | |
164 // msan_interceptors.cc and tsan_interceptors.cc for more details. | |
165 // So, specifically, if MEMORY_SANITIZER is enabled while the direct syscall is | |
166 // used, as MEMORY_SANITIZER does not know about it, sigaction() invocation in | |
167 // other places would be broken (in more precise, returned |oldact| would have | |
168 // a broken |sa_handler| callback). | |
169 // Practically, it would break NaCl's signal handler installation. | |
170 // cf) native_client/src/trusted/service_runtime/linux/nacl_signal.c. | |
171 // As for THREAD_SANITIZER, the intercepted signal handlers are processed more | |
172 // in other libc functions' interceptors (such as for raise()), so that it | |
173 // would not work properly. | |
174 // | |
175 // Also on x86 architectures, we need naked function for rt_sigreturn. | |
176 // However, there is no simple way to define it with GCC. Note that the body | |
177 // of function is actually very small (only two instructions), but we need to | |
178 // define much debug information in addition, otherwise backtrace() used by | |
179 // base::StackTrace would not work so that some tests would fail. | |
180 // | |
181 // When this is built with PNaCl toolchain, we should always use sys_sigaction | 154 // When this is built with PNaCl toolchain, we should always use sys_sigaction |
182 // below, because sigaction() provided by the toolchain is incompatible with | 155 // below, because sigaction() provided by the toolchain is incompatible with |
183 // Linux's ABI. So, otherwise, it would just fail. Note that it is not | 156 // Linux's ABI. |
184 // necessary to think about sigaction() invocation in other places even with | 157 #if !defined(OS_NACL_NONSFI) |
185 // MEMORY_SANITIZER or THREAD_SANITIZER, because it would just fail there. | |
186 int sys_sigaction(int signum, | 158 int sys_sigaction(int signum, |
187 const struct sigaction* act, | 159 const struct sigaction* act, |
188 struct sigaction* oldact) { | 160 struct sigaction* oldact) { |
189 return sigaction(signum, act, oldact); | 161 return sigaction(signum, act, oldact); |
190 } | 162 } |
191 #else | 163 #else |
192 // On X86_64, sa_restorer is required. We specify it on x86 as well in order to | |
193 // support kernels with VDSO disabled. | |
194 #if defined(ARCH_CPU_X86_FAMILY) | 164 #if defined(ARCH_CPU_X86_FAMILY) |
195 | 165 |
| 166 // On x86_64, sa_restorer is required. We specify it on x86 as well in order to |
| 167 // support kernels with VDSO disabled. |
196 #if !defined(SA_RESTORER) | 168 #if !defined(SA_RESTORER) |
197 #define SA_RESTORER 0x04000000 | 169 #define SA_RESTORER 0x04000000 |
198 #endif | 170 #endif |
199 | 171 |
200 // XSTR(__NR_foo) expands to a string literal containing the value value of | 172 // XSTR(__NR_foo) expands to a string literal containing the value value of |
201 // __NR_foo. | 173 // __NR_foo. |
202 #define STR(x) #x | 174 #define STR(x) #x |
203 #define XSTR(x) STR(x) | 175 #define XSTR(x) STR(x) |
204 | 176 |
205 // rt_sigreturn is a special system call that interacts with the user land | 177 // rt_sigreturn is a special system call that interacts with the user land |
206 // stack. Thus, here prologue must not be created, which implies syscall() | 178 // stack. Thus, here prologue must not be created, which implies syscall() |
207 // does not work properly, too. Note that rt_sigreturn does not return. | 179 // does not work properly, too. Note that rt_sigreturn does not return. |
| 180 // TODO(rickyz): These assembly functions may still break stack unwinding on |
| 181 // nonsfi NaCl builds. |
208 #if defined(ARCH_CPU_X86_64) | 182 #if defined(ARCH_CPU_X86_64) |
209 | 183 |
210 extern "C" { | 184 extern "C" { |
211 void sys_rt_sigreturn(); | 185 void sys_rt_sigreturn(); |
212 } | 186 } |
213 | 187 |
214 asm( | 188 asm( |
215 ".text\n" | 189 ".text\n" |
216 "sys_rt_sigreturn:\n" | 190 "sys_rt_sigreturn:\n" |
217 "mov $" XSTR(__NR_rt_sigreturn) ", %eax\n" | 191 "mov $" XSTR(__NR_rt_sigreturn) ", %eax\n" |
(...skipping 60 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
278 std::memcpy(&oldact->sa_mask, &linux_oldact.sa_mask, | 252 std::memcpy(&oldact->sa_mask, &linux_oldact.sa_mask, |
279 std::min(sizeof(linux_act.sa_mask), sizeof(act->sa_mask))); | 253 std::min(sizeof(linux_act.sa_mask), sizeof(act->sa_mask))); |
280 oldact->sa_flags = linux_oldact.sa_flags; | 254 oldact->sa_flags = linux_oldact.sa_flags; |
281 } | 255 } |
282 return result; | 256 return result; |
283 } | 257 } |
284 | 258 |
285 #endif // defined(MEMORY_SANITIZER) | 259 #endif // defined(MEMORY_SANITIZER) |
286 | 260 |
287 } // namespace sandbox | 261 } // namespace sandbox |
OLD | NEW |