Bug 1401786 - Move the Linux sandboxing parts of GeckoChildProcessHost into security/sandbox. r=gcp
authorJed Davis <jld@mozilla.com>
Fri, 06 Oct 2017 17:15:46 -0600
changeset 436174 d97cb5ef7531a0b02162ee02dd600da74b697341
parent 436173 f53d4e3b563526a4191ea488d374cb0ebc7b597e
child 436175 d953d54b2a2074e03747526017cbad52da9fd961
push id117
push userfmarier@mozilla.com
push dateTue, 28 Nov 2017 20:17:16 +0000
reviewersgcp
bugs1401786
milestone59.0a1
Bug 1401786 - Move the Linux sandboxing parts of GeckoChildProcessHost into security/sandbox. r=gcp MozReview-Commit-ID: JknJhF5umZc
ipc/glue/GeckoChildProcessHost.cpp
security/sandbox/linux/launch/SandboxLaunch.cpp
security/sandbox/linux/launch/SandboxLaunch.h
security/sandbox/linux/launch/moz.build
security/sandbox/linux/moz.build
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -51,17 +51,17 @@
 #if defined(MOZ_SANDBOX)
 #include "mozilla/Preferences.h"
 #include "mozilla/sandboxing/sandboxLogging.h"
 #include "WinUtils.h"
 #endif
 #endif
 
 #if defined(XP_LINUX) && defined(MOZ_SANDBOX)
-#include "mozilla/SandboxReporter.h"
+#include "mozilla/SandboxLaunch.h"
 #endif
 
 #include "nsTArray.h"
 #include "nsClassHashtable.h"
 #include "nsHashKeys.h"
 #include "nsNativeCharsetUtils.h"
 #include "nscore.h" // for NS_FREE_PERMANENT_DATA
 
@@ -225,16 +225,20 @@ void
 GeckoChildProcessHost::PrepareLaunch()
 {
 #ifdef MOZ_CRASHREPORTER
   if (CrashReporter::GetEnabled()) {
     CrashReporter::OOPInit();
   }
 #endif
 
+#if defined(XP_LINUX) && defined(MOZ_SANDBOX)
+  SandboxLaunchPrepare(mProcessType, mLaunchOptions.get());
+#endif
+
 #ifdef XP_WIN
   if (mProcessType == GeckoProcessType_Plugin) {
     InitWindowsGroupID();
   }
 
 #if defined(MOZ_CONTENT_SANDBOX)
   // We need to get the pref here as the process is launched off main thread.
   if (mProcessType == GeckoProcessType_Content) {
@@ -703,37 +707,16 @@ GeckoChildProcessHost::PerformAsyncLaunc
     mLaunchOptions->environ["DYLD_INSERT_LIBRARIES"] = interpose.get();
 #  endif // defined(OS_LINUX) || defined(OS_BSD)
   }
 # endif // defined(OS_LINUX) || defined(OS_MACOSX) || defined(OS_BSD) || defined(OS_SOLARIS)
 
   FilePath exePath;
   BinaryPathType pathType = GetPathToBinary(exePath, mProcessType);
 
-# 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.
-    mLaunchOptions->environ["LD_PRELOAD"] = std::string(preload.get());
-  }
-# endif // defined(XP_LINUX) && defined(MOZ_SANDBOX)
-
   // 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);
   mLaunchOptions->fds_to_remap
     .push_back(std::pair<int,int>(srcChannelFd, dstChannelFd));
 
   // no need for kProcessChannelID, the child process inherits the
@@ -800,25 +783,16 @@ GeckoChildProcessHost::PerformAsyncLaunc
     // "false" == crash reporting disabled
     childArgv.push_back("false");
   }
 #  elif defined(MOZ_WIDGET_COCOA) // defined(OS_LINUX) || defined(OS_BSD) || defined(OS_SOLARIS)
   childArgv.push_back(CrashReporter::GetChildNotificationPipe());
 #  endif  // defined(OS_LINUX) || defined(OS_BSD) || defined(OS_SOLARIS)
 # endif // defined(MOZ_CRASHREPORTER)
 
-# if defined(XP_LINUX) && defined(MOZ_SANDBOX)
-  {
-    int srcFd, dstFd;
-    SandboxReporter::Singleton()
-      ->GetClientFileDescriptorMapping(&srcFd, &dstFd);
-    mLaunchOptions->fds_to_remap.push_back(std::make_pair(srcFd, dstFd));
-  }
-# endif // defined(XP_LINUX) && defined(MOZ_SANDBOX)
-
 # ifdef MOZ_WIDGET_COCOA
   // Add a mach port to the command line so the child can communicate its
   // 'task_t' back to the parent.
   //
   // Put a random number into the channel name, so that a compromised renderer
   // can't pretend being the child that's forked off.
   std::string mach_connection_name = StringPrintf("org.mozilla.machname.%d",
                                                   base::RandInt(0, std::numeric_limits<int>::max()));
new file mode 100644
--- /dev/null
+++ b/security/sandbox/linux/launch/SandboxLaunch.cpp
@@ -0,0 +1,57 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 "SandboxLaunch.h"
+
+#include "mozilla/Assertions.h"
+#include "mozilla/SandboxReporter.h"
+#include "nsString.h"
+#include "prenv.h"
+
+namespace mozilla {
+
+static void
+PreloadSandboxLib(base::environment_map* aEnv)
+{
+  // 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);
+  }
+  MOZ_ASSERT(aEnv->count("LD_PRELOAD") == 0);
+  (*aEnv)["LD_PRELOAD"] = preload.get();
+}
+
+static void
+AttachSandboxReporter(base::file_handle_mapping_vector* aFdMap)
+{
+  int srcFd, dstFd;
+  SandboxReporter::Singleton()
+    ->GetClientFileDescriptorMapping(&srcFd, &dstFd);
+  aFdMap->push_back({srcFd, dstFd});
+}
+
+void
+SandboxLaunchPrepare(GeckoProcessType aType,
+		     base::LaunchOptions* aOptions)
+{
+  PreloadSandboxLib(&aOptions->environ);
+  AttachSandboxReporter(&aOptions->fds_to_remap);
+
+  // aType will be used in bug 1401062 to take over the functionality
+  // of SandboxEarlyInit
+}
+
+
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/security/sandbox/linux/launch/SandboxLaunch.h
@@ -0,0 +1,23 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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/. */
+
+#ifndef mozilla_SandboxLaunch_h
+#define mozilla_SandboxLaunch_h
+
+#include "base/process_util.h"
+#include "nsXULAppAPI.h"
+
+namespace mozilla {
+
+// Called in the parent process to set up launch-time aspects of
+// sandboxing.  If aType is GeckoProcessType_Content, this must be
+// called on the main thread in order to access prefs.
+void SandboxLaunchPrepare(GeckoProcessType aType,
+                          base::LaunchOptions* aOptions);
+
+} // namespace mozilla
+
+#endif // mozilla_SandboxLaunch_h
new file mode 100644
--- /dev/null
+++ b/security/sandbox/linux/launch/moz.build
@@ -0,0 +1,28 @@
+# -*- Mode: python; python-indent: 4; 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/.
+
+EXPORTS.mozilla += [
+    'SandboxLaunch.h',
+]
+
+SOURCES += [
+    'SandboxLaunch.cpp',
+]
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
+LOCAL_INCLUDES += [
+    # Need this for safe_sprintf.h used by SandboxLogging.h,
+    # but it has to be after ipc/chromium/src.
+    '/security/sandbox/chromium',
+    '/security/sandbox/linux',
+]
+
+USE_LIBS += [
+    'mozsandbox',
+]
+
+FINAL_LIBRARY = 'xul'
--- a/security/sandbox/linux/moz.build
+++ b/security/sandbox/linux/moz.build
@@ -113,14 +113,15 @@ if CONFIG['OS_TARGET'] != 'Android':
     OS_LIBS += [
         'rt',
     ]
 
 DIRS += [
     'broker',
     'glue',
     'interfaces',
+    'launch',
     'reporter',
 ]
 
 TEST_DIRS += [
     'gtest',
 ]