Bug 1399787 - Part 9. Sandbox the PDFium process. draft
authorcku <cku@mozilla.com>
Wed, 18 Oct 2017 20:52:45 +0800
changeset 684060 e27498786e93bb7f4acb2de3ea5eb49c4234dff1
parent 684059 341b5cacbff1fa9fdc0326a6a527a7dd99a05b81
child 736790 e37c059142445e97427dc04546d4c90c6e7ee11b
push id85531
push usercku@mozilla.com
push dateFri, 20 Oct 2017 17:42:36 +0000
bugs1399787
milestone58.0a1
Bug 1399787 - Part 9. Sandbox the PDFium process. The PDFium process need privilege to access, includes read and write, files in NS_OS_TEMP_DIR and to use windows GDI API only. MozReview-Commit-ID: 6ED7EPZvOMR
ipc/glue/GeckoChildProcessHost.cpp
security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
security/sandbox/win/src/sandboxbroker/sandboxBroker.h
--- a/ipc/glue/GeckoChildProcessHost.cpp
+++ b/ipc/glue/GeckoChildProcessHost.cpp
@@ -1045,16 +1045,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
@@ -1146,17 +1157,18 @@ GeckoChildProcessHost::PerformAsyncLaunc
   {
     base::LaunchApp(cmdLine, false, false, &process);
 
 # ifdef MOZ_SANDBOX
     // We need to be able to duplicate handles to some types of non-sandboxed
     // child processes.
     if (mProcessType == GeckoProcessType_Content ||
         mProcessType == GeckoProcessType_GPU ||
-        mProcessType == GeckoProcessType_GMPlugin) {
+        mProcessType == GeckoProcessType_GMPlugin ||
+        mProcessType == GeckoProcessType_PDFium) {
       if (!mSandboxBroker.AddTargetPeer(process)) {
         NS_WARNING("Failed to add content process as target peer.");
       }
     }
 # endif // MOZ_SANDBOX
   }
 
 #else // goes with defined(OS_POSIX)
--- a/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
+++ b/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp
@@ -826,16 +826,65 @@ SandboxBroker::SetSecurityLevelForPlugin
                             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;
 }
 
 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_LOCKDOWN);
+  SANDBOX_ENSURE_SUCCESS(result,
+                         "SetTokenLevel should never fail with these arguments, what happened?");
+
+  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_UNTRUSTED);
+  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.");
+
+  // 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?");
+
+  return true;
+}
+
+bool
 SandboxBroker::SetSecurityLevelForGMPlugin(SandboxLevel aLevel)
 {
   if (!mPolicy) {
     return false;
   }
 
   auto result = SetJobLevel(mPolicy, sandbox::JOB_LOCKDOWN,
                             0 /* ui_exceptions */);
--- 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);