Bug 1611288 - add macOS sandboxing to socket process. r=haik
authorMichael Froman <mfroman@mozilla.com>
Thu, 12 Mar 2020 17:13:40 +0000
changeset 518568 c1ca51edaa44d3da1b8ba361196f65016a10ca86
parent 518567 cb979a1c473fd99e263a413874a58ba8ed92ee8c
child 518569 a6ba2f16bf2ea673e19e6ee870ac203a20220d3d
push id37213
push usershindli@mozilla.com
push dateFri, 13 Mar 2020 21:46:16 +0000
treeherdermozilla-central@8ef0a54d7715 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewershaik
bugs1611288
milestone76.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 1611288 - add macOS sandboxing to socket process. r=haik Differential Revision: https://phabricator.services.mozilla.com/D60988
ipc/glue/GeckoChildProcessHost.cpp
netwerk/ipc/SocketProcessHost.cpp
netwerk/ipc/SocketProcessHost.h
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -33,16 +33,17 @@
 #include "nsDirectoryService.h"
 #include "nsDirectoryServiceDefs.h"
 #include "nsIFile.h"
 #include "nsPrintfCString.h"
 #include "nsIObserverService.h"
 
 #include "mozilla/ipc/BrowserProcessSubThread.h"
 #include "mozilla/ipc/EnvironmentMap.h"
+#include "mozilla/net/SocketProcessHost.h"
 #include "mozilla/LinkedList.h"
 #include "mozilla/Logging.h"
 #include "mozilla/Maybe.h"
 #include "mozilla/Omnijar.h"
 #include "mozilla/RDDProcessHost.h"
 #include "mozilla/Scoped.h"
 #include "mozilla/Services.h"
 #include "mozilla/SharedThreadPool.h"
@@ -1701,16 +1702,19 @@ bool GeckoChildProcessHost::StartMacSand
     case GeckoProcessType_Content:
       // Content processes don't use GeckoChildProcessHost
       // to configure sandboxing so hard code the sandbox type.
       sandboxType = MacSandboxType_Content;
       break;
     case GeckoProcessType_RDD:
       sandboxType = RDDProcessHost::GetMacSandboxType();
       break;
+    case GeckoProcessType_Socket:
+      sandboxType = net::SocketProcessHost::GetMacSandboxType();
+      break;
     case GeckoProcessType_GMPlugin:
       sandboxType = gmp::GMPProcessParent::GetMacSandboxType();
       break;
     default:
       return true;
   }
   return mozilla::StartMacSandboxIfEnabled(sandboxType, aArgc, aArgv,
                                            aErrorMessage);
--- a/netwerk/ipc/SocketProcessHost.cpp
+++ b/netwerk/ipc/SocketProcessHost.cpp
@@ -13,16 +13,20 @@
 #  include "mozilla/SandboxBroker.h"
 #  include "mozilla/SandboxBrokerPolicyFactory.h"
 #endif
 
 #ifdef MOZ_GECKO_PROFILER
 #  include "ProfilerParent.h"
 #endif
 
+#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
+#  include "mozilla/Sandbox.h"
+#endif
+
 namespace mozilla {
 namespace net {
 
 #define NS_IPC_IOSERVICE_SET_OFFLINE_TOPIC "ipc:network:set-offline"
 
 class OfflineObserver final : public nsIObserver {
  public:
   NS_DECL_THREADSAFE_ISUPPORTS
@@ -75,25 +79,36 @@ class OfflineObserver final : public nsI
   }
   virtual ~OfflineObserver() = default;
 
   SocketProcessHost* mProcessHost;
 };
 
 NS_IMPL_ISUPPORTS(OfflineObserver, nsIObserver)
 
+#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
+bool SocketProcessHost::sLaunchWithMacSandbox = false;
+#endif
+
 SocketProcessHost::SocketProcessHost(Listener* aListener)
     : GeckoChildProcessHost(GeckoProcessType_Socket),
       mListener(aListener),
       mTaskFactory(this),
       mLaunchPhase(LaunchPhase::Unlaunched),
       mShutdownRequested(false),
       mChannelClosed(false) {
   MOZ_ASSERT(NS_IsMainThread());
   MOZ_COUNT_CTOR(SocketProcessHost);
+#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
+  if (!sLaunchWithMacSandbox) {
+    sLaunchWithMacSandbox =
+        (PR_GetEnv("MOZ_DISABLE_SOCKET_PROCESS_SANDBOX") == nullptr);
+  }
+  mDisableOSActivityMode = sLaunchWithMacSandbox;
+#endif
 }
 
 SocketProcessHost::~SocketProcessHost() {
   MOZ_COUNT_DTOR(SocketProcessHost);
   if (mOfflineObserver) {
     RefPtr<OfflineObserver> observer = mOfflineObserver;
     NS_DispatchToMainThread(
         NS_NewRunnableFunction("SocketProcessHost::DestroyOfflineObserver",
@@ -140,17 +155,16 @@ void SocketProcessHost::OnChannelConnect
     runnable = mTaskFactory.NewRunnableMethod(
         &SocketProcessHost::OnChannelConnectedTask);
   }
   NS_DispatchToMainThread(runnable);
 }
 
 void SocketProcessHost::OnChannelError() {
   MOZ_ASSERT(!NS_IsMainThread());
-
   GeckoChildProcessHost::OnChannelError();
 
   // Post a task to the main thread. Take the lock because mTaskFactory is not
   // thread-safe.
   RefPtr<Runnable> runnable;
   {
     MonitorAutoLock lock(mMonitor);
     runnable =
@@ -274,16 +288,36 @@ void SocketProcessHost::DestroyProcess()
     MonitorAutoLock lock(mMonitor);
     mTaskFactory.RevokeAll();
   }
 
   MessageLoop::current()->PostTask(NS_NewRunnableFunction(
       "DestroySocketProcessRunnable", [this] { Destroy(); }));
 }
 
+#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
+/* static */
+bool SocketProcessHost::StaticFillMacSandboxInfo(MacSandboxInfo& aInfo) {
+  GeckoChildProcessHost::StaticFillMacSandboxInfo(aInfo);
+  if (!aInfo.shouldLog && PR_GetEnv("MOZ_SANDBOX_SOCKET_PROCESS_LOGGING")) {
+    aInfo.shouldLog = true;
+  }
+  return true;
+}
+
+bool SocketProcessHost::FillMacSandboxInfo(MacSandboxInfo& aInfo) {
+  return SocketProcessHost::StaticFillMacSandboxInfo(aInfo);
+}
+
+/* static */
+MacSandboxType SocketProcessHost::GetMacSandboxType() {
+  return MacSandboxType_Socket;
+}
+#endif
+
 //-----------------------------------------------------------------------------
 // SocketProcessMemoryReporter
 //-----------------------------------------------------------------------------
 
 bool SocketProcessMemoryReporter::IsAlive() const {
   MOZ_ASSERT(gIOService);
 
   if (!gIOService->mSocketProcess) {
--- a/netwerk/ipc/SocketProcessHost.h
+++ b/netwerk/ipc/SocketProcessHost.h
@@ -72,31 +72,48 @@ class SocketProcessHost final : public m
 
     return !!mSocketProcessParent;
   }
 
   // Called on the IO thread.
   void OnChannelConnected(int32_t peer_pid) override;
   void OnChannelError() override;
 
+#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
+  static bool StaticFillMacSandboxInfo(MacSandboxInfo& aInfo);
+
+  // Return the sandbox type to be used with this process type.
+  static MacSandboxType GetMacSandboxType();
+#endif
+
  private:
   ~SocketProcessHost();
 
   // Called on the main thread.
   void OnChannelConnectedTask();
   void OnChannelErrorTask();
 
   // Called on the main thread after a connection has been established.
   void InitAfterConnect(bool aSucceeded);
 
   // Called on the main thread when the mSocketParent actor is shutting down.
   void OnChannelClosed();
 
   void DestroyProcess();
 
+#if defined(XP_MACOSX) && defined(MOZ_SANDBOX)
+  static bool sLaunchWithMacSandbox;
+
+  // Sandbox the Socket process at launch for all instances
+  bool IsMacSandboxLaunchEnabled() override { return sLaunchWithMacSandbox; }
+
+  // Override so we can turn on Socket process-specific sandbox logging
+  bool FillMacSandboxInfo(MacSandboxInfo& aInfo) override;
+#endif
+
   DISALLOW_COPY_AND_ASSIGN(SocketProcessHost);
 
   RefPtr<Listener> mListener;
   mozilla::ipc::TaskFactory<SocketProcessHost> mTaskFactory;
 
   enum class LaunchPhase { Unlaunched, Waiting, Complete };
   LaunchPhase mLaunchPhase;