1 /* 2 * Copyright (C) 2014 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 #ifdef ART_TARGET_ANDROID 18 #include <android/log.h> 19 #else 20 #include <stdarg.h> 21 #include <iostream> 22 #endif 23 24 #include <dlfcn.h> 25 #include <errno.h> 26 #include <pthread.h> 27 #include <signal.h> 28 #include <stdio.h> 29 #include <stdlib.h> 30 #include <string.h> 31 32 #include <algorithm> 33 #include <initializer_list> 34 #include <mutex> 35 #include <type_traits> 36 #include <utility> 37 38 #include "sigchain.h" 39 40 #if defined(__APPLE__) 41 #define _NSIG NSIG 42 #define sighandler_t sig_t 43 44 // Darwin has an #error when ucontext.h is included without _XOPEN_SOURCE defined. 45 #define _XOPEN_SOURCE 46 #endif 47 48 #include <ucontext.h> 49 50 // libsigchain provides an interception layer for signal handlers, to allow ART and others to give 51 // their signal handlers the first stab at handling signals before passing them on to user code. 52 // 53 // It implements wrapper functions for signal, sigaction, and sigprocmask, and a handler that 54 // forwards signals appropriately. 55 // 56 // In our handler, we start off with all signals blocked, fetch the original signal mask from the 57 // passed in ucontext, and then adjust our signal mask appropriately for the user handler. 58 // 59 // It's somewhat tricky for us to properly handle some flag cases: 60 // SA_NOCLDSTOP and SA_NOCLDWAIT: shouldn't matter, we don't have special handlers for SIGCHLD. 61 // SA_NODEFER: unimplemented, we can manually change the signal mask appropriately. 62 // ~SA_ONSTACK: always silently enable this 63 // SA_RESETHAND: unimplemented, but we can probably do this? 64 // ~SA_RESTART: unimplemented, maybe we can reserve an RT signal, register an empty handler that 65 // doesn't have SA_RESTART, and raise the signal to avoid restarting syscalls that are 66 // expected to be interrupted? 67 68 static void log(const char* format, ...) { 69 char buf[256]; 70 va_list ap; 71 va_start(ap, format); 72 vsnprintf(buf, sizeof(buf), format, ap); 73 #ifdef ART_TARGET_ANDROID 74 __android_log_write(ANDROID_LOG_ERROR, "libsigchain", buf); 75 #else 76 std::cout << buf << "\n"; 77 #endif 78 va_end(ap); 79 } 80 81 #define fatal(...) log(__VA_ARGS__); abort() 82 83 #if defined(__BIONIC__) && !defined(__LP64__) 84 static int sigismember(const sigset64_t* sigset, int signum) { 85 return sigismember64(sigset, signum); 86 } 87 88 static int sigemptyset(sigset64_t* sigset) { 89 return sigemptyset64(sigset); 90 } 91 92 static int sigaddset(sigset64_t* sigset, int signum) { 93 return sigaddset64(sigset, signum); 94 } 95 96 static int sigdelset(sigset64_t* sigset, int signum) { 97 return sigdelset64(sigset, signum); 98 } 99 #endif 100 101 template<typename SigsetType> 102 static int sigorset(SigsetType* dest, SigsetType* left, SigsetType* right) { 103 sigemptyset(dest); 104 for (size_t i = 0; i < sizeof(SigsetType) * CHAR_BIT; ++i) { 105 if (sigismember(left, i) == 1 || sigismember(right, i) == 1) { 106 sigaddset(dest, i); 107 } 108 } 109 return 0; 110 } 111 112 namespace art { 113 114 static decltype(&sigaction) linked_sigaction; 115 static decltype(&sigprocmask) linked_sigprocmask; 116 117 #if defined(__BIONIC__) 118 static decltype(&sigaction64) linked_sigaction64; 119 static decltype(&sigprocmask64) linked_sigprocmask64; 120 #endif 121 122 template<typename T> 123 static void lookup_next_symbol(T* output, T wrapper, const char* name) { 124 void* sym = dlsym(RTLD_NEXT, name); 125 if (sym == nullptr) { 126 sym = dlsym(RTLD_DEFAULT, name); 127 if (sym == wrapper || sym == sigaction) { 128 fatal("Unable to find next %s in signal chain", name); 129 } 130 } 131 *output = reinterpret_cast<T>(sym); 132 } 133 134 __attribute__((constructor)) static void InitializeSignalChain() { 135 static std::once_flag once; 136 std::call_once(once, []() { 137 lookup_next_symbol(&linked_sigaction, sigaction, "sigaction"); 138 lookup_next_symbol(&linked_sigprocmask, sigprocmask, "sigprocmask"); 139 140 #if defined(__BIONIC__) 141 lookup_next_symbol(&linked_sigaction64, sigaction64, "sigaction64"); 142 lookup_next_symbol(&linked_sigprocmask64, sigprocmask64, "sigprocmask64"); 143 #endif 144 }); 145 } 146 147 static pthread_key_t GetHandlingSignalKey() { 148 static pthread_key_t key; 149 static std::once_flag once; 150 std::call_once(once, []() { 151 int rc = pthread_key_create(&key, nullptr); 152 if (rc != 0) { 153 fatal("failed to create sigchain pthread key: %s", strerror(rc)); 154 } 155 }); 156 return key; 157 } 158 159 static bool GetHandlingSignal() { 160 void* result = pthread_getspecific(GetHandlingSignalKey()); 161 return reinterpret_cast<uintptr_t>(result); 162 } 163 164 static void SetHandlingSignal(bool value) { 165 pthread_setspecific(GetHandlingSignalKey(), 166 reinterpret_cast<void*>(static_cast<uintptr_t>(value))); 167 } 168 169 class ScopedHandlingSignal { 170 public: 171 ScopedHandlingSignal() : original_value_(GetHandlingSignal()) { 172 } 173 174 ~ScopedHandlingSignal() { 175 SetHandlingSignal(original_value_); 176 } 177 178 private: 179 bool original_value_; 180 }; 181 182 class SignalChain { 183 public: 184 SignalChain() : claimed_(false) { 185 } 186 187 bool IsClaimed() { 188 return claimed_; 189 } 190 191 void Claim(int signo) { 192 if (!claimed_) { 193 Register(signo); 194 claimed_ = true; 195 } 196 } 197 198 // Register the signal chain with the kernel if needed. 199 void Register(int signo) { 200 #if defined(__BIONIC__) 201 struct sigaction64 handler_action = {}; 202 sigfillset64(&handler_action.sa_mask); 203 #else 204 struct sigaction handler_action = {}; 205 sigfillset(&handler_action.sa_mask); 206 #endif 207 208 handler_action.sa_sigaction = SignalChain::Handler; 209 handler_action.sa_flags = SA_RESTART | SA_SIGINFO | SA_ONSTACK; 210 211 #if defined(__BIONIC__) 212 linked_sigaction64(signo, &handler_action, &action_); 213 #else 214 linked_sigaction(signo, &handler_action, &action_); 215 #endif 216 } 217 218 template <typename SigactionType> 219 SigactionType GetAction() { 220 if constexpr (std::is_same_v<decltype(action_), SigactionType>) { 221 return action_; 222 } else { 223 SigactionType result; 224 result.sa_flags = action_.sa_flags; 225 result.sa_handler = action_.sa_handler; 226 result.sa_restorer = action_.sa_restorer; 227 memcpy(&result.sa_mask, &action_.sa_mask, 228 std::min(sizeof(action_.sa_mask), sizeof(result.sa_mask))); 229 return result; 230 } 231 } 232 233 template <typename SigactionType> 234 void SetAction(const SigactionType* new_action) { 235 if constexpr (std::is_same_v<decltype(action_), SigactionType>) { 236 action_ = *new_action; 237 } else { 238 action_.sa_flags = new_action->sa_flags; 239 action_.sa_handler = new_action->sa_handler; 240 action_.sa_restorer = new_action->sa_restorer; 241 sigemptyset(&action_.sa_mask); 242 memcpy(&action_.sa_mask, &new_action->sa_mask, 243 std::min(sizeof(action_.sa_mask), sizeof(new_action->sa_mask))); 244 } 245 } 246 247 void AddSpecialHandler(SigchainAction* sa) { 248 for (SigchainAction& slot : special_handlers_) { 249 if (slot.sc_sigaction == nullptr) { 250 slot = *sa; 251 return; 252 } 253 } 254 255 fatal("too many special signal handlers"); 256 } 257 258 void RemoveSpecialHandler(bool (*fn)(int, siginfo_t*, void*)) { 259 // This isn't thread safe, but it's unlikely to be a real problem. 260 size_t len = sizeof(special_handlers_)/sizeof(*special_handlers_); 261 for (size_t i = 0; i < len; ++i) { 262 if (special_handlers_[i].sc_sigaction == fn) { 263 for (size_t j = i; j < len - 1; ++j) { 264 special_handlers_[j] = special_handlers_[j + 1]; 265 } 266 special_handlers_[len - 1].sc_sigaction = nullptr; 267 return; 268 } 269 } 270 271 fatal("failed to find special handler to remove"); 272 } 273 274 275 static void Handler(int signo, siginfo_t* siginfo, void*); 276 277 private: 278 bool claimed_; 279 #if defined(__BIONIC__) 280 struct sigaction64 action_; 281 #else 282 struct sigaction action_; 283 #endif 284 SigchainAction special_handlers_[2]; 285 }; 286 287 // _NSIG is 1 greater than the highest valued signal, but signals start from 1. 288 // Leave an empty element at index 0 for convenience. 289 static SignalChain chains[_NSIG + 1]; 290 291 void SignalChain::Handler(int signo, siginfo_t* siginfo, void* ucontext_raw) { 292 // Try the special handlers first. 293 // If one of them crashes, we'll reenter this handler and pass that crash onto the user handler. 294 if (!GetHandlingSignal()) { 295 for (const auto& handler : chains[signo].special_handlers_) { 296 if (handler.sc_sigaction == nullptr) { 297 break; 298 } 299 300 // The native bridge signal handler might not return. 301 // Avoid setting the thread local flag in this case, since we'll never 302 // get a chance to restore it. 303 bool handler_noreturn = (handler.sc_flags & SIGCHAIN_ALLOW_NORETURN); 304 sigset_t previous_mask; 305 linked_sigprocmask(SIG_SETMASK, &handler.sc_mask, &previous_mask); 306 307 ScopedHandlingSignal restorer; 308 if (!handler_noreturn) { 309 SetHandlingSignal(true); 310 } 311 312 if (handler.sc_sigaction(signo, siginfo, ucontext_raw)) { 313 return; 314 } 315 316 linked_sigprocmask(SIG_SETMASK, &previous_mask, nullptr); 317 } 318 } 319 320 // Forward to the user's signal handler. 321 int handler_flags = chains[signo].action_.sa_flags; 322 ucontext_t* ucontext = static_cast<ucontext_t*>(ucontext_raw); 323 #if defined(__BIONIC__) 324 sigset64_t mask; 325 sigorset(&mask, &ucontext->uc_sigmask64, &chains[signo].action_.sa_mask); 326 #else 327 sigset_t mask; 328 sigorset(&mask, &ucontext->uc_sigmask, &chains[signo].action_.sa_mask); 329 #endif 330 if (!(handler_flags & SA_NODEFER)) { 331 sigaddset(&mask, signo); 332 } 333 334 #if defined(__BIONIC__) 335 linked_sigprocmask64(SIG_SETMASK, &mask, nullptr); 336 #else 337 linked_sigprocmask(SIG_SETMASK, &mask, nullptr); 338 #endif 339 340 if ((handler_flags & SA_SIGINFO)) { 341 chains[signo].action_.sa_sigaction(signo, siginfo, ucontext_raw); 342 } else { 343 auto handler = chains[signo].action_.sa_handler; 344 if (handler == SIG_IGN) { 345 return; 346 } else if (handler == SIG_DFL) { 347 fatal("exiting due to SIG_DFL handler for signal %d", signo); 348 } else { 349 handler(signo); 350 } 351 } 352 } 353 354 template <typename SigactionType> 355 static int __sigaction(int signal, const SigactionType* new_action, 356 SigactionType* old_action, 357 int (*linked)(int, const SigactionType*, 358 SigactionType*)) { 359 // If this signal has been claimed as a signal chain, record the user's 360 // action but don't pass it on to the kernel. 361 // Note that we check that the signal number is in range here. An out of range signal 362 // number should behave exactly as the libc sigaction. 363 if (signal <= 0 || signal >= _NSIG) { 364 errno = EINVAL; 365 return -1; 366 } 367 368 if (chains[signal].IsClaimed()) { 369 SigactionType saved_action = chains[signal].GetAction<SigactionType>(); 370 if (new_action != nullptr) { 371 chains[signal].SetAction(new_action); 372 } 373 if (old_action != nullptr) { 374 *old_action = saved_action; 375 } 376 return 0; 377 } 378 379 // Will only get here if the signal chain has not been claimed. We want 380 // to pass the sigaction on to the kernel via the real sigaction in libc. 381 return linked(signal, new_action, old_action); 382 } 383 384 extern "C" int sigaction(int signal, const struct sigaction* new_action, 385 struct sigaction* old_action) { 386 InitializeSignalChain(); 387 return __sigaction(signal, new_action, old_action, linked_sigaction); 388 } 389 390 #if defined(__BIONIC__) 391 extern "C" int sigaction64(int signal, const struct sigaction64* new_action, 392 struct sigaction64* old_action) { 393 InitializeSignalChain(); 394 return __sigaction(signal, new_action, old_action, linked_sigaction64); 395 } 396 #endif 397 398 extern "C" sighandler_t signal(int signo, sighandler_t handler) { 399 InitializeSignalChain(); 400 401 if (signo <= 0 || signo >= _NSIG) { 402 errno = EINVAL; 403 return SIG_ERR; 404 } 405 406 struct sigaction sa = {}; 407 sigemptyset(&sa.sa_mask); 408 sa.sa_handler = handler; 409 sa.sa_flags = SA_RESTART | SA_ONSTACK; 410 sighandler_t oldhandler; 411 412 // If this signal has been claimed as a signal chain, record the user's 413 // action but don't pass it on to the kernel. 414 if (chains[signo].IsClaimed()) { 415 oldhandler = reinterpret_cast<sighandler_t>( 416 chains[signo].GetAction<struct sigaction>().sa_handler); 417 chains[signo].SetAction(&sa); 418 return oldhandler; 419 } 420 421 // Will only get here if the signal chain has not been claimed. We want 422 // to pass the sigaction on to the kernel via the real sigaction in libc. 423 if (linked_sigaction(signo, &sa, &sa) == -1) { 424 return SIG_ERR; 425 } 426 427 return reinterpret_cast<sighandler_t>(sa.sa_handler); 428 } 429 430 #if !defined(__LP64__) 431 extern "C" sighandler_t bsd_signal(int signo, sighandler_t handler) { 432 InitializeSignalChain(); 433 434 return signal(signo, handler); 435 } 436 #endif 437 438 template <typename SigsetType> 439 int __sigprocmask(int how, const SigsetType* new_set, SigsetType* old_set, 440 int (*linked)(int, const SigsetType*, SigsetType*)) { 441 // When inside a signal handler, forward directly to the actual sigprocmask. 442 if (GetHandlingSignal()) { 443 return linked(how, new_set, old_set); 444 } 445 446 const SigsetType* new_set_ptr = new_set; 447 SigsetType tmpset; 448 if (new_set != nullptr) { 449 tmpset = *new_set; 450 451 if (how == SIG_BLOCK || how == SIG_SETMASK) { 452 // Don't allow claimed signals in the mask. If a signal chain has been claimed 453 // we can't allow the user to block that signal. 454 for (int i = 1; i < _NSIG; ++i) { 455 if (chains[i].IsClaimed() && sigismember(&tmpset, i)) { 456 sigdelset(&tmpset, i); 457 } 458 } 459 } 460 new_set_ptr = &tmpset; 461 } 462 463 return linked(how, new_set_ptr, old_set); 464 } 465 466 extern "C" int sigprocmask(int how, const sigset_t* new_set, 467 sigset_t* old_set) { 468 InitializeSignalChain(); 469 return __sigprocmask(how, new_set, old_set, linked_sigprocmask); 470 } 471 472 #if defined(__BIONIC__) 473 extern "C" int sigprocmask64(int how, const sigset64_t* new_set, 474 sigset64_t* old_set) { 475 InitializeSignalChain(); 476 return __sigprocmask(how, new_set, old_set, linked_sigprocmask64); 477 } 478 #endif 479 480 extern "C" void AddSpecialSignalHandlerFn(int signal, SigchainAction* sa) { 481 InitializeSignalChain(); 482 483 if (signal <= 0 || signal >= _NSIG) { 484 fatal("Invalid signal %d", signal); 485 } 486 487 // Set the managed_handler. 488 chains[signal].AddSpecialHandler(sa); 489 chains[signal].Claim(signal); 490 } 491 492 extern "C" void RemoveSpecialSignalHandlerFn(int signal, bool (*fn)(int, siginfo_t*, void*)) { 493 InitializeSignalChain(); 494 495 if (signal <= 0 || signal >= _NSIG) { 496 fatal("Invalid signal %d", signal); 497 } 498 499 chains[signal].RemoveSpecialHandler(fn); 500 } 501 502 extern "C" void EnsureFrontOfChain(int signal) { 503 InitializeSignalChain(); 504 505 if (signal <= 0 || signal >= _NSIG) { 506 fatal("Invalid signal %d", signal); 507 } 508 509 // Read the current action without looking at the chain, it should be the expected action. 510 struct sigaction current_action; 511 linked_sigaction(signal, nullptr, ¤t_action); 512 513 // If the sigactions don't match then we put the current action on the chain and make ourself as 514 // the main action. 515 if (current_action.sa_sigaction != SignalChain::Handler) { 516 log("Warning: Unexpected sigaction action found %p\n", current_action.sa_sigaction); 517 chains[signal].Register(signal); 518 } 519 } 520 521 } // namespace art 522 523