summaryrefslogtreecommitdiff
path: root/mozglue/linker
diff options
context:
space:
mode:
authorPale Moon <git-repo@palemoon.org>2014-11-26 09:19:45 +0100
committerPale Moon <git-repo@palemoon.org>2014-11-26 09:19:45 +0100
commit2aac0d443c54a558ae1d0d8f1833a2e8fe2f1ba4 (patch)
treec7ca6e126ee87ebba49acc8c908899197bcc3856 /mozglue/linker
parentebc46421d18d9e0eb0b7b406a6f5b0603174f330 (diff)
downloadpalemoon-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.cpp85
-rw-r--r--mozglue/linker/ElfLoader.h13
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;
};
/**