summaryrefslogtreecommitdiff
path: root/data/patches/gnuzilla-bug-1036286-2.patch
diff options
context:
space:
mode:
Diffstat (limited to 'data/patches/gnuzilla-bug-1036286-2.patch')
-rw-r--r--data/patches/gnuzilla-bug-1036286-2.patch105
1 files changed, 105 insertions, 0 deletions
diff --git a/data/patches/gnuzilla-bug-1036286-2.patch b/data/patches/gnuzilla-bug-1036286-2.patch
new file mode 100644
index 0000000..6708062
--- /dev/null
+++ b/data/patches/gnuzilla-bug-1036286-2.patch
@@ -0,0 +1,105 @@
+--- a/mozglue/linker/CustomElf.cpp
++++ a/mozglue/linker/CustomElf.cpp
+@@ -1,16 +1,17 @@
+ /* This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this file,
+ * You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+ #include <cstring>
+ #include <sys/mman.h>
+ #include <vector>
+ #include <dlfcn.h>
++#include <signal.h>
+ #include "CustomElf.h"
+ #include "Mappable.h"
+ #include "Logging.h"
+
+ using namespace Elf;
+ using namespace mozilla;
+
+ /* TODO: Fill ElfLoader::Singleton.lastError on errors. */
+@@ -348,16 +349,21 @@ CustomElf::GetSymbolPtrInDeps(const char
+ if (strcmp(symbol + 2, "dso_handle") == 0)
+ return const_cast<CustomElf *>(this);
+ if (strcmp(symbol + 2, "moz_linker_stats") == 0)
+ return FunctionPtr(&ElfLoader::stats);
+ #ifdef __ARM_EABI__
+ if (strcmp(symbol + 2, "gnu_Unwind_Find_exidx") == 0)
+ return FunctionPtr(__wrap___gnu_Unwind_Find_exidx);
+ #endif
++ } else if (symbol[0] == 's' && symbol[1] == 'i') {
++ if (strcmp(symbol + 2, "gnal") == 0)
++ return FunctionPtr(signal);
++ if (strcmp(symbol + 2, "gaction") == 0)
++ return FunctionPtr(sigaction);
+ }
+
+ #define MISSING_FLASH_SYMNAME_START "_ZN7android10VectorImpl19reservedVectorImpl"
+
+ // Android changed some symbols that Flash depended on in 4.4,
+ // so stub those out here
+ if (strncmp(symbol,
+ MISSING_FLASH_SYMNAME_START,
+--- a/mozglue/linker/ElfLoader.cpp
++++ a/mozglue/linker/ElfLoader.cpp
+@@ -1014,17 +1014,59 @@ SEGVHandler::FinishInitialization()
+ {
+ /* Ideally, we'd need some locking here, but in practice, we're not
+ * going to race with another thread. */
+ initialized = true;
+
+ if (signalHandlingBroken || signalHandlingSlow)
+ return;
+
+- if (!Divert(sigaction, __wrap_sigaction))
++ typedef int (*sigaction_func)(int, const struct sigaction *,
++ struct sigaction *);
++
++ sigaction_func libc_sigaction;
++
++#if defined(ANDROID)
++ /* Android > 4.4 comes with a sigaction wrapper in a LD_PRELOADed library
++ * (libsigchain) for ART. That wrapper kind of does the same trick as we
++ * do, so we need extra care in handling it.
++ * - Divert the libc's sigaction, assuming the LD_PRELOADed library uses
++ * it under the hood (which is more or less true according to the source
++ * of that library, since it's doing a lookup in RTLD_NEXT)
++ * - With the LD_PRELOADed library in place, all calls to sigaction from
++ * from system libraries will go to the LD_PRELOADed library.
++ * - The LD_PRELOADed library calls to sigaction go to our __wrap_sigaction.
++ * - The calls to sigaction from libraries faulty.lib loads are sent to
++ * the LD_PRELOADed library.
++ * In practice, for signal handling, this means:
++ * - The signal handler registered to the kernel is ours.
++ * - Our handler redispatches to the LD_PRELOADed library's if there's a
++ * segfault we don't handle.
++ * - The LD_PRELOADed library redispatches according to whatever system
++ * library or faulty.lib-loaded library set with sigaction.
++ *
++ * When there is no sigaction wrapper in place:
++ * - Divert the libc's sigaction.
++ * - Calls to sigaction from system library and faulty.lib-loaded libraries
++ * all go to the libc's sigaction, which end up in our __wrap_sigaction.
++ * - The signal handler registered to the kernel is ours.
++ * - Our handler redispatches according to whatever system library or
++ * faulty.lib-loaded library set with sigaction.
++ */
++ void *libc = dlopen("libc.so", RTLD_GLOBAL | RTLD_LAZY);
++ if (libc) {
++ libc_sigaction =
++ reinterpret_cast<sigaction_func>(dlsym(libc, "sigaction"));
++ } else
++#endif
++ {
++ libc_sigaction = sigaction;
++ }
++
++ if (!Divert(libc_sigaction, __wrap_sigaction))
+ return;
+
+ /* Setup an alternative stack if the already existing one is not big
+ * enough, or if there is none. */
+ if (sigaltstack(nullptr, &oldStack) == 0) {
+ if (oldStack.ss_flags == SS_ONSTACK)
+ oldStack.ss_flags = 0;
+ if (!oldStack.ss_sp || oldStack.ss_size < stackSize) {