Bug 1313218 - Preload libmozsandbox.so in child processes on Linux. r=tedd r=billm r=glandium
authorJed Davis <jld@mozilla.com>
Fri, 04 Nov 2016 18:16:05 -0600
changeset 351285 97bf9717631977f76a43fadd51c99dea1df770c6
parent 351284 231272fa95c5c156601c2a121f050b3ad62d74a3
child 351286 c04f84afb1bd6b3ea372164012735de6c8f2d582
push id6795
push userjlund@mozilla.com
push dateMon, 23 Jan 2017 14:19:46 +0000
treeherdermozilla-esr52@76101b503191 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstedd, billm, glandium
bugs1313218
milestone52.0a1
Bug 1313218 - Preload libmozsandbox.so in child processes on Linux. r=tedd r=billm r=glandium Preloading libmozsandbox allows the symbol interpositions used by sandboxing to be defined there instead of statically linked into the executable; this patch also does that. MozReview-Commit-ID: FL1QWLSKA0S
ipc/app/moz.build
ipc/glue/GeckoChildProcessHost.cpp
security/sandbox/linux/Sandbox.cpp
security/sandbox/linux/SandboxHooks.cpp
security/sandbox/linux/interpose/SandboxHooks.cpp
security/sandbox/linux/interpose/moz.build
security/sandbox/linux/moz.build
--- a/ipc/app/moz.build
+++ b/ipc/app/moz.build
@@ -61,17 +61,16 @@ if CONFIG['OS_ARCH'] == 'WINNT':
 
     DELAYLOAD_DLLS += [
         'xul.dll',
     ]
 
 if CONFIG['MOZ_SANDBOX'] and CONFIG['OS_TARGET'] in ('Linux', 'Android'):
     USE_LIBS += [
         'mozsandbox',
-        'mozsandbox_interpose',
     ]
 
     # gcc lto likes to put the top level asm in syscall.cc in a different partition
     # from the function using it which breaks the build.  Work around that by
     # forcing there to be only one partition.
     if '-flto' in CONFIG['OS_CXXFLAGS'] and not CONFIG['CLANG_CXX']:
         LDFLAGS += ['--param lto-partitions=1']
 
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -836,16 +836,37 @@ GeckoChildProcessHost::PerformAsyncLaunc
 #endif  // ANDROID
 
 #ifdef MOZ_WIDGET_GONK
   if (const char *ldPreloadPath = getenv("LD_PRELOAD")) {
     newEnvVars["LD_PRELOAD"] = ldPreloadPath;
   }
 #endif // MOZ_WIDGET_GONK
 
+#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
+  // Preload libmozsandbox.so so that sandbox-related interpositions
+  // can be defined there instead of in the executable.
+  // (This could be made conditional on intent to use sandboxing, but
+  // it's harmless for non-sandboxed processes.)
+  {
+    nsAutoCString preload;
+    // Prepend this, because people can and do preload libpthread.
+    // (See bug 1222500.)
+    preload.AssignLiteral("libmozsandbox.so");
+    if (const char* oldPreload = PR_GetEnv("LD_PRELOAD")) {
+      // Doesn't matter if oldPreload is ""; extra separators are ignored.
+      preload.Append(' ');
+      preload.Append(oldPreload);
+    }
+    // Explicitly construct the std::string to make it clear that this
+    // isn't retaining a pointer to the nsCString's buffer.
+    newEnvVars["LD_PRELOAD"] = std::string(preload.get());
+  }
+#endif
+
   // remap the IPC socket fd to a well-known int, as the OS does for
   // STDOUT_FILENO, for example
   int srcChannelFd, dstChannelFd;
   channel().GetClientFileDescriptorMapping(&srcChannelFd, &dstChannelFd);
   mFileMap.push_back(std::pair<int,int>(srcChannelFd, dstChannelFd));
 
   // no need for kProcessChannelID, the child process inherits the
   // other end of the socketpair() from us
--- a/security/sandbox/linux/Sandbox.cpp
+++ b/security/sandbox/linux/Sandbox.cpp
@@ -64,17 +64,17 @@ typedef struct {
 } __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.
-MOZ_EXPORT int gSeccompTsyncBroadcastSignum = 0;
+int gSeccompTsyncBroadcastSignum = 0;
 
 namespace mozilla {
 
 // This is initialized by SandboxSetCrashFunc().
 SandboxCrashFunc gSandboxCrashFunc;
 
 #ifdef MOZ_GMP_SANDBOX
 // For media plugins, we can start the sandbox before we dlopen the
rename from security/sandbox/linux/interpose/SandboxHooks.cpp
rename to security/sandbox/linux/SandboxHooks.cpp
--- a/security/sandbox/linux/interpose/SandboxHooks.cpp
+++ b/security/sandbox/linux/SandboxHooks.cpp
@@ -8,17 +8,17 @@
 #include <errno.h>
 
 #include "mozilla/Types.h"
 
 #include <stdio.h>
 #include <stdlib.h>
 
 // Signal number used to enable seccomp on each thread.
-extern MOZ_EXPORT int gSeccompTsyncBroadcastSignum;
+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,
deleted file mode 100644
--- a/security/sandbox/linux/interpose/moz.build
+++ /dev/null
@@ -1,11 +0,0 @@
-# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
-# vim: set filetype=python:
-# 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/.
-
-Library("mozsandbox_interpose")
-
-SOURCES += [
-    'SandboxHooks.cpp',
-]
--- a/security/sandbox/linux/moz.build
+++ b/security/sandbox/linux/moz.build
@@ -59,16 +59,17 @@ SOURCES += [
     '../chromium/sandbox/linux/services/syscall_wrappers.cc',
     'broker/SandboxBrokerCommon.cpp',
     'LinuxCapabilities.cpp',
     'Sandbox.cpp',
     'SandboxBrokerClient.cpp',
     'SandboxChroot.cpp',
     'SandboxFilter.cpp',
     'SandboxFilterUtil.cpp',
+    'SandboxHooks.cpp',
     'SandboxInfo.cpp',
     'SandboxLogging.cpp',
     'SandboxUtil.cpp',
 ]
 
 # This copy of SafeSPrintf doesn't need to avoid the Chromium logging
 # dependency like the one in libxul does, but this way the behavior is
 # consistent.  See also the comment in SandboxLogging.h.
@@ -103,14 +104,13 @@ if CONFIG['OS_TARGET'] != 'Android':
     # Needed for clock_gettime with glibc < 2.17:
     OS_LIBS += [
         'rt',
     ]
 
 DIRS += [
     'broker',
     'glue',
-    'interpose',
 ]
 
 TEST_DIRS += [
     'gtest',
 ]