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 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
141 | 141 |
142 int sys_sigprocmask(int how, const sigset_t* set, decltype(nullptr) oldset) { | 142 int sys_sigprocmask(int how, const sigset_t* set, decltype(nullptr) oldset) { |
143 // In some toolchain (in particular Android and PNaCl toolchain), | 143 // In some toolchain (in particular Android and PNaCl toolchain), |
144 // sigset_t is 32 bits, but Linux ABI requires 64 bits. | 144 // sigset_t is 32 bits, but Linux ABI requires 64 bits. |
145 uint64_t linux_value = 0; | 145 uint64_t linux_value = 0; |
146 std::memcpy(&linux_value, set, std::min(sizeof(sigset_t), sizeof(uint64_t))); | 146 std::memcpy(&linux_value, set, std::min(sizeof(sigset_t), sizeof(uint64_t))); |
147 return syscall(__NR_rt_sigprocmask, how, &linux_value, nullptr, | 147 return syscall(__NR_rt_sigprocmask, how, &linux_value, nullptr, |
148 sizeof(linux_value)); | 148 sizeof(linux_value)); |
149 } | 149 } |
150 | 150 |
151 #if defined(MEMORY_SANITIZER) || \ | 151 #if (defined(MEMORY_SANITIZER) || defined(THREAD_SANITIZER) || \ |
152 (defined(ARCH_CPU_X86_64) && defined(__GNUC__) && !defined(__clang__)) | 152 (defined(ARCH_CPU_X86_64) && !defined(__clang__))) && \ |
153 // If MEMORY_SANITIZER is enabled, it is necessary to call sigaction() here, | 153 !defined(OS_NACL_NONSFI) |
154 // rather than the direct syscall (sys_sigaction() defined by ourselves). | 154 // If MEMORY_SANITIZER or THREAD_SANITIZER is enabled, it is necessary to call |
155 // It is because, if MEMORY_SANITIZER is enabled, sigaction is wrapped, and | 155 // sigaction() here, rather than the direct syscall (sys_sigaction() defined |
156 // |act->sa_handler| is injected in order to unpoisonize the memory passed via | 156 // by ourselves). |
157 // callback's arguments. Please see msan_interceptors.cc for more details. | 157 // It is because, if MEMORY_SANITIZER or THREAD_SANITIZER is enabled, sigaction |
158 // So, if the direct syscall is used, as MEMORY_SANITIZER does not know about | 158 // is wrapped, and |act->sa_handler| is injected in order to unpoisonize the |
159 // it, sigaction() invocation in other places would be broken (in more precise, | 159 // memory passed via callback's arguments for MEMORY_SANITIZER, or handle |
160 // returned |oldact| would have a broken |sa_handler| callback). | 160 // signals to check thread consistency for THREAD_SANITIZER. Please see |
| 161 // msan_interceptors.cc and tsan_interceptors.cc for more details. |
| 162 // So, specifically, if MEMORY_SANITIZER is enabled while the direct syscall is |
| 163 // used, as MEMORY_SANITIZER does not know about it, sigaction() invocation in |
| 164 // other places would be broken (in more precise, returned |oldact| would have |
| 165 // a broken |sa_handler| callback). |
161 // Practically, it would break NaCl's signal handler installation. | 166 // Practically, it would break NaCl's signal handler installation. |
162 // cf) native_client/src/trusted/service_runtime/linux/nacl_signal.c. | 167 // cf) native_client/src/trusted/service_runtime/linux/nacl_signal.c. |
| 168 // As for THREAD_SANITIZER, the intercepted signal handlers are processed more |
| 169 // in other libc functions' interceptors (such as for raise()), so that it |
| 170 // would not work properly. |
163 // | 171 // |
164 // Also on x86_64 architecture, we need naked function for rt_sigreturn. | 172 // Also on x86_64 architecture, we need naked function for rt_sigreturn. |
165 // However, there is no simple way to define it with GCC. Note that the body | 173 // However, there is no simple way to define it with GCC. Note that the body |
166 // of function is actually very small (only two instructions), but we need to | 174 // of function is actually very small (only two instructions), but we need to |
167 // define much debug information in addition, otherwise backtrace() used by | 175 // define much debug information in addition, otherwise backtrace() used by |
168 // base::StackTrace would not work so that some tests would fail. | 176 // base::StackTrace would not work so that some tests would fail. |
| 177 // |
| 178 // When this is built with PNaCl toolchain, we should always use sys_sigaction |
| 179 // below, because sigaction() provided by the toolchain is incompatible with |
| 180 // Linux's ABI. So, otherwise, it would just fail. Note that it is not |
| 181 // necessary to think about sigaction() invocation in other places even with |
| 182 // MEMORY_SANITIZER or THREAD_SANITIZER, because it would just fail there. |
169 int sys_sigaction(int signum, | 183 int sys_sigaction(int signum, |
170 const struct sigaction* act, | 184 const struct sigaction* act, |
171 struct sigaction* oldact) { | 185 struct sigaction* oldact) { |
172 return sigaction(signum, act, oldact); | 186 return sigaction(signum, act, oldact); |
173 } | 187 } |
174 #else | 188 #else |
175 // struct sigaction is different ABI from the Linux's. | 189 // struct sigaction is different ABI from the Linux's. |
176 struct KernelSigAction { | 190 struct KernelSigAction { |
177 void (*kernel_handler)(int); | 191 void (*kernel_handler)(int); |
178 uint32_t sa_flags; | 192 uint32_t sa_flags; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
223 std::memcpy(&oldact->sa_mask, &kernel_oldact.sa_mask, | 237 std::memcpy(&oldact->sa_mask, &kernel_oldact.sa_mask, |
224 std::min(sizeof(kernel_act.sa_mask), sizeof(act->sa_mask))); | 238 std::min(sizeof(kernel_act.sa_mask), sizeof(act->sa_mask))); |
225 oldact->sa_flags = kernel_oldact.sa_flags; | 239 oldact->sa_flags = kernel_oldact.sa_flags; |
226 } | 240 } |
227 return result; | 241 return result; |
228 } | 242 } |
229 | 243 |
230 #endif // defined(MEMORY_SANITIZER) | 244 #endif // defined(MEMORY_SANITIZER) |
231 | 245 |
232 } // namespace sandbox | 246 } // namespace sandbox |
OLD | NEW |