Backed out changeset 62646bfa1f95 (bug 1274873)
authorCarsten "Tomcat" Book <cbook@mozilla.com>
Tue, 07 Jun 2016 12:06:51 +0200
changeset 300874 b070f6f0ace20cba6b74f269af0c3a5b0bbe229b
parent 300873 87b9aa4a22e9e5dab4d1dea3babaa9c8524c96a0
child 300875 25cf270ae8c54aae735d5657cb5118a277eeef0a
push id19599
push usercbook@mozilla.com
push dateWed, 08 Jun 2016 10:16:21 +0000
treeherderfx-team@81f4cc3f6f4c [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
bugs1274873
milestone50.0a1
backs out62646bfa1f953b5e89aef58e9879dd2f139610f0
Backed out changeset 62646bfa1f95 (bug 1274873)
security/sandbox/linux/Sandbox.cpp
security/sandbox/linux/SandboxHooks.cpp
--- a/security/sandbox/linux/Sandbox.cpp
+++ b/security/sandbox/linux/Sandbox.cpp
@@ -60,19 +60,16 @@ typedef struct {
   unsigned int coverage_max_block_size;
 } __sanitizer_sandbox_arguments;
 
 MOZ_IMPORT_API void
 __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args);
 } // extern "C"
 #endif // MOZ_ASAN
 
-// Signal number used to enable seccomp on each thread.
-int gSeccompTsyncBroadcastSignum = 0;
-
 namespace mozilla {
 
 #ifdef ANDROID
 SandboxCrashFunc gSandboxCrashFunc;
 #endif
 
 #ifdef MOZ_GMP_SANDBOX
 // For media plugins, we can start the sandbox before we dlopen the
@@ -305,16 +302,17 @@ EnterChroot()
     gChrootHelper->Invoke();
     gChrootHelper = nullptr;
   }
 }
 
 static void
 BroadcastSetThreadSandbox(const sock_fprog* aFilter)
 {
+  int signum;
   pid_t pid, tid, myTid;
   DIR *taskdp;
   struct dirent *de;
 
   // This function does not own *aFilter, so this global needs to
   // always be zeroed before returning.
   gSetSandboxFilter = aFilter;
 
@@ -325,16 +323,29 @@ BroadcastSetThreadSandbox(const sock_fpr
   taskdp = opendir("/proc/self/task");
   if (taskdp == nullptr) {
     SANDBOX_LOG_ERROR("opendir /proc/self/task: %s\n", strerror(errno));
     MOZ_CRASH();
   }
 
   EnterChroot();
 
+  signum = FindFreeSignalNumber();
+  if (signum == 0) {
+    SANDBOX_LOG_ERROR("No available signal numbers!");
+    MOZ_CRASH();
+  }
+  void (*oldHandler)(int);
+  oldHandler = signal(signum, SetThreadSandboxHandler);
+  if (oldHandler != SIG_DFL) {
+    // See the comment on FindFreeSignalNumber about race conditions.
+    SANDBOX_LOG_ERROR("signal %d in use by handler %p!\n", signum, oldHandler);
+    MOZ_CRASH();
+  }
+
   // In case this races with a not-yet-deprivileged thread cloning
   // itself, repeat iterating over all threads until we find none
   // that are still privileged.
   bool sandboxProgress;
   do {
     sandboxProgress = false;
     // For each thread...
     while ((de = readdir(taskdp))) {
@@ -344,22 +355,19 @@ BroadcastSetThreadSandbox(const sock_fpr
         // Not a task ID.
         continue;
       }
       if (tid == myTid) {
         // Drop this thread's privileges last, below, so we can
         // continue to signal other threads.
         continue;
       }
-
-      MOZ_RELEASE_ASSERT(gSeccompTsyncBroadcastSignum != 0);
-
       // Reset the futex cell and signal.
       gSetSandboxDone = 0;
-      if (syscall(__NR_tgkill, pid, tid, gSeccompTsyncBroadcastSignum) != 0) {
+      if (syscall(__NR_tgkill, pid, tid, signum) != 0) {
         if (errno == ESRCH) {
           SANDBOX_LOG_ERROR("Thread %d unexpectedly exited.", tid);
           // Rescan threads, in case it forked before exiting.
           sandboxProgress = true;
           continue;
         }
         SANDBOX_LOG_ERROR("tgkill(%d,%d): %s\n", pid, tid, strerror(errno));
         MOZ_CRASH();
@@ -419,24 +427,21 @@ BroadcastSetThreadSandbox(const sock_fpr
                             "  Killing process.",
                             tid, crashDelay);
           MOZ_CRASH();
         }
       }
     }
     rewinddir(taskdp);
   } while (sandboxProgress);
-
-  void (*oldHandler)(int);
-  oldHandler = signal(gSeccompTsyncBroadcastSignum, SIG_DFL);
-  gSeccompTsyncBroadcastSignum = 0;
+  oldHandler = signal(signum, SIG_DFL);
   if (oldHandler != SetThreadSandboxHandler) {
     // See the comment on FindFreeSignalNumber about race conditions.
     SANDBOX_LOG_ERROR("handler for signal %d was changed to %p!",
-                      gSeccompTsyncBroadcastSignum, oldHandler);
+                      signum, oldHandler);
     MOZ_CRASH();
   }
   Unused << closedir(taskdp);
   // And now, deprivilege the main thread:
   SetThreadSandbox();
   gSetSandboxFilter = nullptr;
 }
 
@@ -548,35 +553,16 @@ SandboxEarlyInit(GeckoProcessType aType,
 #endif
     // In the future, content processes will be able to use some of
     // these.
   default:
     // Other cases intentionally left blank.
     break;
   }
 
-  // If TSYNC is not supported, set up signal handler
-  // used to enable seccomp on each thread.
-  if (!info.Test(SandboxInfo::kHasSeccompTSync)) {
-    gSeccompTsyncBroadcastSignum = FindFreeSignalNumber();
-    if (gSeccompTsyncBroadcastSignum == 0) {
-      SANDBOX_LOG_ERROR("No available signal numbers!");
-      MOZ_CRASH();
-    }
-
-    void (*oldHandler)(int);
-    oldHandler = signal(gSeccompTsyncBroadcastSignum, SetThreadSandboxHandler);
-    if (oldHandler != SIG_DFL) {
-      // See the comment on FindFreeSignalNumber about race conditions.
-      SANDBOX_LOG_ERROR("signal %d in use by handler %p!\n",
-        gSeccompTsyncBroadcastSignum, oldHandler);
-      MOZ_CRASH();
-    }
-  }
-
   // If there's nothing to do, then we're done.
   if (!canChroot && !canUnshareNet && !canUnshareIPC) {
     return;
   }
 
   {
     LinuxCapabilities existingCaps;
     if (existingCaps.GetCurrent() && existingCaps.AnyEffective()) {
--- a/security/sandbox/linux/SandboxHooks.cpp
+++ b/security/sandbox/linux/SandboxHooks.cpp
@@ -7,19 +7,16 @@
 #include <signal.h>
 #include <errno.h>
 
 #include "mozilla/Types.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 
-// Signal number used to enable seccomp on each thread.
-extern int gSeccompTsyncBroadcastSignum;
-
 // This file defines a hook for sigprocmask() and pthread_sigmask().
 // Bug 1176099: some threads block SIGSYS signal which breaks our seccomp-bpf
 // sandbox. To avoid this, we intercept the call and remove SIGSYS.
 //
 // ENOSYS indicates an error within the hook function itself.
 static int HandleSigset(int (*aRealFunc)(int, const sigset_t*, sigset_t*),
                         int aHow, const sigset_t* aSet,
                         sigset_t* aOldSet, bool aUseErrno)
@@ -29,24 +26,21 @@ static int HandleSigset(int (*aRealFunc)
       errno = ENOSYS;
       return -1;
     }
 
     return ENOSYS;
   }
 
   // Avoid unnecessary work
-  if (aSet == NULL || aHow == SIG_UNBLOCK) {
+  if (aSet == NULL || aHow == SIG_UNBLOCK || !sigismember(aSet, SIGSYS))
     return aRealFunc(aHow, aSet, aOldSet);
-  }
 
   sigset_t newSet = *aSet;
-  if (sigdelset(&newSet, SIGSYS) != 0 ||
-     (gSeccompTsyncBroadcastSignum &&
-      sigdelset(&newSet, gSeccompTsyncBroadcastSignum) != 0)) {
+  if (sigdelset(&newSet, SIGSYS) != 0) {
     if (aUseErrno) {
       errno = ENOSYS;
       return -1;
     }
 
     return ENOSYS;
   }