Bug 1399787 - Part 11. Sandbox the PDFium process. draft
authorcku <cku@mozilla.com>
Wed, 18 Oct 2017 20:52:45 +0800
changeset 688809 72cf0d365965f2ef36a200b4c0ad133a4f10abb3
parent 686702 afed73ca323a4a03c7a4518fdb37b03d9b573eda
child 688810 53a2755fc3bd371745c97466fea8ff6498ae2173
child 688811 234a7d6b02734f975832d458721ff8232a96f9ae
push id86858
push usercku@mozilla.com
push dateMon, 30 Oct 2017 18:14:58 +0000
bugs1399787
milestone58.0a1
Bug 1399787 - Part 11. Sandbox the PDFium process. MozReview-Commit-ID: 6ED7EPZvOMR
ipc/glue/GeckoChildProcessHost.cpp
security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
security/sandbox/win/src/sandboxbroker/sandboxBroker.h
widget/windows/PDFiumProcessChild.cpp
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -966,16 +966,27 @@ GeckoChildProcessHost::PerformAsyncLaunc
           !PR_GetEnv("MOZ_DISABLE_NPAPI_SANDBOX")) {
         bool ok = mSandboxBroker.SetSecurityLevelForPluginProcess(mSandboxLevel);
         if (!ok) {
           return false;
         }
         shouldSandboxCurrentProcess = true;
       }
       break;
+#ifdef MOZ_ENABLE_SKIA_PDF
+    case GeckoProcessType_PDFium:
+      if (!PR_GetEnv("MOZ_DISABLE_PDFIUM_SANDBOX")) {
+        bool ok = mSandboxBroker.SetSecurityLevelForPDFiumProcess();
+        if (!ok) {
+          return false;
+        }
+        shouldSandboxCurrentProcess = true;
+      }
+      break;
+#endif
     case GeckoProcessType_IPDLUnitTest:
       // XXX: We don't sandbox this process type yet
       break;
     case GeckoProcessType_GMPlugin:
       if (!PR_GetEnv("MOZ_DISABLE_GMP_SANDBOX")) {
         // The Widevine CDM on Windows can only load at USER_RESTRICTED,
         // not at USER_LOCKDOWN. So look in the command line arguments
         // to see if we're loading the path to the Widevine CDM, and if
--- a/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
+++ b/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
@@ -825,16 +825,83 @@ SandboxBroker::SetSecurityLevelForPlugin
                             sandbox::TargetPolicy::REG_ALLOW_ANY,
                             L"HKEY_CURRENT_USER\\Software\\Microsoft\\Windows\\CurrentVersion\\Explorer\\ComDlg32\\LastVisitedPidlMRULegacy\\*");
   SANDBOX_ENSURE_SUCCESS(result,
                          "With these static arguments AddRule should never fail, what happened?");
 
   return true;
 }
 
+#ifdef MOZ_ENABLE_SKIA_PDF
+bool
+SandboxBroker::SetSecurityLevelForPDFiumProcess()
+{
+  if (!mPolicy) {
+    return false;
+  }
+
+  auto result = SetJobLevel(mPolicy, sandbox::JOB_LOCKDOWN,
+                            0 /* ui_exceptions */);
+  SANDBOX_ENSURE_SUCCESS(result,
+                         "SetJobLevel should never fail with these arguments, what happened?");
+  result = mPolicy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
+                                  sandbox::USER_LIMITED);
+  SANDBOX_ENSURE_SUCCESS(result,
+                         "SetTokenLevel should never fail with these arguments, what happened?");
+
+  result = mPolicy->SetAlternateDesktop(true);
+  SANDBOX_ENSURE_SUCCESS(result,
+                         "Failed to create alternate desktop for sandbox.");
+
+  result = mPolicy->SetIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
+  MOZ_ASSERT(sandbox::SBOX_ALL_OK == result,
+             "SetIntegrityLevel should never fail with these arguments, what happened?");
+
+  result =
+    mPolicy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_LOW);
+  SANDBOX_ENSURE_SUCCESS(result,
+                         "SetIntegrityLevel should never fail with these arguments, what happened?");
+
+  sandbox::MitigationFlags mitigations =
+    sandbox::MITIGATION_BOTTOM_UP_ASLR |
+    sandbox::MITIGATION_HEAP_TERMINATE |
+    sandbox::MITIGATION_SEHOP |
+    sandbox::MITIGATION_DEP_NO_ATL_THUNK |
+    sandbox::MITIGATION_DEP;
+
+  result = mPolicy->SetProcessMitigations(mitigations);
+  SANDBOX_ENSURE_SUCCESS(result,
+                         "Invalid flags for SetProcessMitigations.");
+
+  mitigations =
+    sandbox::MITIGATION_STRICT_HANDLE_CHECKS |
+    sandbox::MITIGATION_DLL_SEARCH_ORDER;
+
+  result = mPolicy->SetDelayedProcessMitigations(mitigations);
+  SANDBOX_ENSURE_SUCCESS(result,
+                         "Invalid flags for SetDelayedProcessMitigations.");
+
+
+  // Add the policy for the client side of a pipe. It is just a file
+  // in the \pipe\ namespace. We restrict it to pipes that start with
+  // "chrome." so the sandboxed process cannot connect to system services.
+  result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
+                            sandbox::TargetPolicy::FILES_ALLOW_ANY,
+                            L"\\??\\pipe\\chrome.*");
+  SANDBOX_ENSURE_SUCCESS(result,
+                         "With these static arguments AddRule should never fail, what happened?");
+
+  // Add this rule for loading pdfium.dll.
+  AddCachedDirRule(mPolicy, sandbox::TargetPolicy::FILES_ALLOW_READONLY,
+                   sBinDir, NS_LITERAL_STRING("\\*"));
+
+  return true;
+}
+#endif
+
 bool
 SandboxBroker::SetSecurityLevelForGMPlugin(SandboxLevel aLevel)
 {
   if (!mPolicy) {
     return false;
   }
 
   auto result = SetJobLevel(mPolicy, sandbox::JOB_LOCKDOWN,
--- a/security/sandbox/win/src/sandboxbroker/sandboxBroker.h
+++ b/security/sandbox/win/src/sandboxbroker/sandboxBroker.h
@@ -43,16 +43,19 @@ public:
 #if defined(MOZ_CONTENT_SANDBOX)
   void SetSecurityLevelForContentProcess(int32_t aSandboxLevel,
                                          bool aIsFileProcess);
 #endif
 
   void SetSecurityLevelForGPUProcess(int32_t aSandboxLevel);
 
   bool SetSecurityLevelForPluginProcess(int32_t aSandboxLevel);
+#ifdef MOZ_ENABLE_SKIA_PDF
+  bool SetSecurityLevelForPDFiumProcess();
+#endif
   enum SandboxLevel {
     LockDown,
     Restricted
   };
   bool SetSecurityLevelForGMPlugin(SandboxLevel aLevel);
 
   // File system permissions
   bool AllowReadFile(wchar_t const *file);
--- a/widget/windows/PDFiumProcessChild.cpp
+++ b/widget/windows/PDFiumProcessChild.cpp
@@ -4,16 +4,19 @@
  * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
 
 #include "PDFiumProcessChild.h"
 
 #include "mozilla/ipc/IOThreadChild.h"
 #include "mozilla/BackgroundHangMonitor.h"
 #include "mozilla/dom/ContentChild.h"
 #include "mozilla/dom/ContentParent.h"
+#if defined(MOZ_SANDBOX)
+#include "mozilla/sandboxTarget.h"
+#endif
 
 using mozilla::ipc::IOThreadChild;
 
 namespace mozilla {
 namespace widget {
 
 PDFiumProcessChild::PDFiumProcessChild(ProcessId aParentPid)
 : ProcessChild(aParentPid)
@@ -23,16 +26,21 @@ PDFiumProcessChild::PDFiumProcessChild(P
 PDFiumProcessChild::~PDFiumProcessChild()
 {
 }
 
 bool
 PDFiumProcessChild::Init(int aArgc, char* aArgv[])
 {
   BackgroundHangMonitor::Startup();
+
+#if defined(MOZ_SANDBOX)
+  mozilla::SandboxTarget::Instance()->StartSandbox();
+#endif
+
   mPDFiumActor.Init(ParentPid(),IOThreadChild::message_loop(),
   	                IOThreadChild::channel());
 
   return true;
 }
 
 void
 PDFiumProcessChild::CleanUp()