diff options
author | Pale Moon <git-repo@palemoon.org> | 2014-11-26 09:19:45 +0100 |
---|---|---|
committer | Pale Moon <git-repo@palemoon.org> | 2014-11-26 09:19:45 +0100 |
commit | 2aac0d443c54a558ae1d0d8f1833a2e8fe2f1ba4 (patch) | |
tree | c7ca6e126ee87ebba49acc8c908899197bcc3856 /mozglue/linker | |
parent | ebc46421d18d9e0eb0b7b406a6f5b0603174f330 (diff) | |
download | palemoon-gre-2aac0d443c54a558ae1d0d8f1833a2e8fe2f1ba4.tar.gz |
Revert "Detect broken signal handlers and be more resilient if so."
This reverts commit ebc46421d18d9e0eb0b7b406a6f5b0603174f330.
Diffstat (limited to 'mozglue/linker')
-rw-r--r-- | mozglue/linker/ElfLoader.cpp | 85 | ||||
-rw-r--r-- | mozglue/linker/ElfLoader.h | 13 |
2 files changed, 15 insertions, 83 deletions
diff --git a/mozglue/linker/ElfLoader.cpp b/mozglue/linker/ElfLoader.cpp index 67e23f010..806a89a43 100644 --- a/mozglue/linker/ElfLoader.cpp +++ b/mozglue/linker/ElfLoader.cpp @@ -160,12 +160,6 @@ __dl_munmap(void *handle, void *addr, size_t length) return reinterpret_cast<LibHandle *>(handle)->MappableMUnmap(addr, length); } -MFBT_API bool -IsSignalHandlingBroken() -{ - return ElfLoader::Singleton.isSignalHandlingBroken(); -} - namespace { /** @@ -908,87 +902,38 @@ Divert(T func, T new_func) #endif SEGVHandler::SEGVHandler() -: registeredHandler(false), signalHandlingBroken(false) +: registeredHandler(false) { - /* Initialize oldStack.ss_flags to an invalid value when used to set - * an alternative stack, meaning we haven't got information about the - * original alternative stack and thus don't mean to restore it */ - oldStack.ss_flags = SS_ONSTACK; if (!Divert(sigaction, __wrap_sigaction)) return; - - /* Get the current segfault signal handler. */ - sys_sigaction(SIGSEGV, NULL, &this->action); - - /* Some devices don't provide useful information to their SIGSEGV handlers, - * making it impossible for on-demand decompression to work. To check if - * we're on such a device, setup a temporary handler and deliberately - * trigger a segfault. The handler will set signalHandlingBroken if the - * provided information is bogus. */ - struct sigaction action; - action.sa_sigaction = &SEGVHandler::test_handler; - sigemptyset(&action.sa_mask); - action.sa_flags = SA_SIGINFO | SA_NODEFER; - action.sa_restorer = NULL; - if (sys_sigaction(SIGSEGV, &action, NULL)) - return; - stackPtr.Assign(MemoryRange::mmap(NULL, PageSize(), PROT_NONE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); - if (stackPtr.get() == MAP_FAILED) - return; - - *((volatile int*)stackPtr.get()) = 123; - stackPtr.Assign(MAP_FAILED, 0); - if (signalHandlingBroken) { - /* Restore the original segfault signal handler. */ - sys_sigaction(SIGSEGV, &this->action, NULL); - return; - } - /* Setup an alternative stack if the already existing one is not big * enough, or if there is none. */ - if (sigaltstack(NULL, &oldStack) == 0) { - if (oldStack.ss_flags == SS_ONSTACK) - oldStack.ss_flags = 0; - if (!oldStack.ss_sp || oldStack.ss_size < stackSize) { - stackPtr.Assign(MemoryRange::mmap(NULL, stackSize, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANONYMOUS, -1, 0)); - if (stackPtr.get() == MAP_FAILED) - return; - stack_t stack; - stack.ss_sp = stackPtr; - stack.ss_size = stackSize; - stack.ss_flags = 0; - if (sigaltstack(&stack, NULL) != 0) - return; - } + if (sigaltstack(NULL, &oldStack) == -1 || !oldStack.ss_sp || + oldStack.ss_size < stackSize) { + stackPtr.Assign(mmap(NULL, stackSize, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANONYMOUS, -1, 0), stackSize); + stack_t stack; + stack.ss_sp = stackPtr; + stack.ss_size = stackSize; + stack.ss_flags = 0; + sigaltstack(&stack, NULL); } /* Register our own handler, and store the already registered one in * SEGVHandler's struct sigaction member */ + struct sigaction action; action.sa_sigaction = &SEGVHandler::handler; + sigemptyset(&action.sa_mask); action.sa_flags = SA_SIGINFO | SA_NODEFER | SA_ONSTACK; - registeredHandler = !sys_sigaction(SIGSEGV, &action, NULL); + action.sa_restorer = NULL; + registeredHandler = !sys_sigaction(SIGSEGV, &action, &this->action); } SEGVHandler::~SEGVHandler() { /* Restore alternative stack for signals */ - if (oldStack.ss_flags != SS_ONSTACK) sigaltstack(&oldStack, NULL); /* Restore original signal handler */ - if (registeredHandler) - sys_sigaction(SIGSEGV, &this->action, NULL); -} - -/* Test handler for a deliberately triggered SIGSEGV that determines whether - * useful information is provided to signal handlers, particularly whether - * si_addr is filled in properly. */ -void SEGVHandler::test_handler(int signum, siginfo_t *info, void *context) -{ - SEGVHandler &that = ElfLoader::Singleton; - if (signum != SIGSEGV || info == NULL || info->si_addr != that.stackPtr.get()) - that.signalHandlingBroken = true; - mprotect(that.stackPtr, that.stackPtr.GetLength(), PROT_READ | PROT_WRITE); + sys_sigaction(SIGSEGV, &this->action, NULL); } /* TODO: "properly" handle signal masks and flags */ diff --git a/mozglue/linker/ElfLoader.h b/mozglue/linker/ElfLoader.h index 9cec6b914..6fc21b154 100644 --- a/mozglue/linker/ElfLoader.h +++ b/mozglue/linker/ElfLoader.h @@ -53,9 +53,6 @@ __dl_mmap(void *handle, void *addr, size_t length, off_t offset); MFBT_API void __dl_munmap(void *handle, void *addr, size_t length); -MFBT_API bool -IsSignalHandlingBroken(); - } /** @@ -300,10 +297,6 @@ public: return registeredHandler; } - bool isSignalHandlingBroken() { - return signalHandlingBroken; - } - static int __wrap_sigaction(int signum, const struct sigaction *act, struct sigaction *oldact); @@ -326,11 +319,6 @@ private: static void handler(int signum, siginfo_t *info, void *context); /** - * Temporary test handler. - */ - static void test_handler(int signum, siginfo_t *info, void *context); - - /** * Size of the alternative stack. The printf family requires more than 8KB * of stack, and our signal handler may print a few things. */ @@ -348,7 +336,6 @@ private: MappedPtr stackPtr; bool registeredHandler; - bool signalHandlingBroken; }; /** |