Bug 1036286 - Make sure libraries loaded by faulty.lib use its own sigaction. r=nfroyd
authorMike Hommey <mh+mozilla@glandium.org>
Thu, 24 Jul 2014 13:43:56 +0900
changeset 217448 34235900c3a0e300afb1911489fa6e0c8d67df76
parent 217447 9345f94814621b287c734d60d07c14988bb56b2d
child 217449 d7335ab12a1fcd25f54e8862fd58a228b6a39ca7
push id3979
push userraliiev@mozilla.com
push dateMon, 13 Oct 2014 16:35:44 +0000
treeherdermozilla-beta@30f2cc610691 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersnfroyd
bugs1036286, 874708
milestone34.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1036286 - Make sure libraries loaded by faulty.lib use its own sigaction. r=nfroyd Android L added a libsigchain library it LD_PRELOADs. That library exposes a different sigaction than libc's. It's used for ART. faulty.lib gets its sigaction from libsigchain, but after bug 874708, the libraries it loads simply use libc's sigaction, assuming it would be the hooked one. In turn, this means libraries loaded by faulty.lib may override faulty.lib's handler, which is definitely not the intent. This essentially restores some of the code that bug 874708 removed. An alternative fix would be to add support for LD_PRELOAD, but that has more implications and feels more risky. This could be done, if necessary, as a followup.
mozglue/linker/CustomElf.cpp
mozglue/linker/ElfLoader.cpp
mozglue/linker/ElfLoader.h
--- a/mozglue/linker/CustomElf.cpp
+++ b/mozglue/linker/CustomElf.cpp
@@ -348,16 +348,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(SEGVHandler::__wrap_signal);
+    if (strcmp(symbol + 2, "gaction") == 0)
+      return FunctionPtr(SEGVHandler::__wrap_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
+++ b/mozglue/linker/ElfLoader.cpp
@@ -1118,9 +1118,35 @@ SEGVHandler::__wrap_sigaction(int signum
 
   if (oldact)
     *oldact = that.action;
   if (act)
     that.action = *act;
   return 0;
 }
 
+sighandler_t
+SEGVHandler::__wrap_signal(int signum, sighandler_t handler)
+{
+  /* Use system signal() function for all but SIGSEGV signals. */
+  if (signum != SIGSEGV)
+    return signal(signum, handler);
+
+  SEGVHandler &that = ElfLoader::Singleton;
+  union {
+    sighandler_t signal;
+    void (*sigaction)(int, siginfo_t *, void *);
+  } oldHandler;
+
+  /* Keep the previous handler to return its value */
+  if (that.action.sa_flags & SA_SIGINFO) {
+    oldHandler.sigaction = that.action.sa_sigaction;
+  } else {
+    oldHandler.signal = that.action.sa_handler;
+  }
+  /* Set the new handler */
+  that.action.sa_handler = handler;
+  that.action.sa_flags = 0;
+
+  return oldHandler.signal;
+}
+
 Logging Logging::Singleton;
--- a/mozglue/linker/ElfLoader.h
+++ b/mozglue/linker/ElfLoader.h
@@ -314,24 +314,26 @@ public:
   bool hasRegisteredHandler() {
     return registeredHandler;
   }
 
   bool isSignalHandlingBroken() {
     return signalHandlingBroken;
   }
 
+  static int __wrap_sigaction(int signum, const struct sigaction *act,
+                              struct sigaction *oldact);
+
+  static sighandler_t __wrap_signal(int signum, sighandler_t handler);
+
 protected:
   SEGVHandler();
   ~SEGVHandler();
 
 private:
-  static int __wrap_sigaction(int signum, const struct sigaction *act,
-                              struct sigaction *oldact);
-
   /**
    * SIGSEGV handler registered with __wrap_signal or __wrap_sigaction.
    */
   struct sigaction action;
   
   /**
    * ElfLoader SIGSEGV handler.
    */