Bug 1457092 - Implement sandboxing on OpenBSD. r=gcp, r=jld
authorLandry Breuil <landry@openbsd.org>
Thu, 23 Aug 2018 07:35:00 -0400
changeset 488181 8f5c17ac83aa8cd493b9b051820ccc4d61c46a14
parent 488180 51b6bdb9197cc31d56533c5209adc9a314b8bb59
child 488182 411427c1f5fe876edcd92f31b3c86bbb8d509ac7
push id9719
push userffxbld-merge
push dateFri, 24 Aug 2018 17:49:46 +0000
treeherdermozilla-beta@719ec98fba77 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersgcp, jld
bugs1457092
milestone63.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 1457092 - Implement sandboxing on OpenBSD. r=gcp, r=jld Add StartOpenBSDSandbox method calling pledge() syscall, and use it where we're sandboxing processes. The pledge subsets are coming from two new prefs: - security.sandbox.pledge.content for the content process - security.sandbox.pledge.main for the main process
dom/ipc/ContentChild.cpp
security/sandbox/common/SandboxSettings.h
toolkit/xre/nsAppRunner.cpp
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -104,16 +104,18 @@
 #if defined(XP_WIN)
 #include "mozilla/sandboxTarget.h"
 #elif defined(XP_LINUX)
 #include "mozilla/Sandbox.h"
 #include "mozilla/SandboxInfo.h"
 #include "CubebUtils.h"
 #elif defined(XP_MACOSX)
 #include "mozilla/Sandbox.h"
+#elif defined(__OpenBSD__)
+#include <unistd.h>
 #endif
 #endif
 
 #include "mozilla/Unused.h"
 
 #include "mozInlineSpellChecker.h"
 #include "nsDocShell.h"
 #include "nsDocShellLoadInfo.h"
@@ -1778,16 +1780,18 @@ ContentChild::RecvSetProcessSandbox(cons
   if (sandboxEnabled) {
     sandboxEnabled =
       SetContentProcessSandbox(ContentProcessSandboxParams::ForThisProcess(aBroker));
   }
 #elif defined(XP_WIN)
   mozilla::SandboxTarget::Instance()->StartSandbox();
 #elif defined(XP_MACOSX)
   sandboxEnabled = StartMacOSContentSandbox();
+#elif defined(__OpenBSD__)
+  sandboxEnabled = StartOpenBSDSandbox(GeckoProcessType_Content);
 #endif
 
   CrashReporter::AnnotateCrashReport(
     CrashReporter::Annotation::ContentSandboxEnabled, sandboxEnabled);
 #if defined(XP_LINUX) && !defined(OS_ANDROID)
   CrashReporter::AnnotateCrashReport(
     CrashReporter::Annotation::ContentSandboxCapabilities,
     static_cast<int>(SandboxInfo::Get().AsInteger()));
@@ -3916,16 +3920,65 @@ PContentChild::Result
 ContentChild::OnMessageReceived(const Message& aMsg, Message*& aReply)
 {
   return PContentChild::OnMessageReceived(aMsg, aReply);
 }
 #endif
 
 } // namespace dom
 
+#if defined(__OpenBSD__) && defined(MOZ_CONTENT_SANDBOX)
+#include <unistd.h>
+
+static LazyLogModule sPledgeLog("SandboxPledge");
+
+bool
+StartOpenBSDSandbox(GeckoProcessType type)
+{
+  nsAutoCString promisesString;
+  nsAutoCString processTypeString;
+
+  switch (type) {
+    case GeckoProcessType_Default:
+      processTypeString = "main";
+      Preferences::GetCString("security.sandbox.pledge.main",
+                              promisesString);
+      break;
+
+    case GeckoProcessType_Content:
+      processTypeString = "content";
+      Preferences::GetCString("security.sandbox.pledge.content",
+                              promisesString);
+      break;
+
+    default:
+      MOZ_ASSERT(false, "unknown process type");
+      return false;
+  };
+
+  if (pledge(promisesString.get(), NULL) == -1) {
+    if (errno == EINVAL) {
+        MOZ_LOG(sPledgeLog, LogLevel::Error,
+               ("pledge promises for %s process is a malformed string: '%s'\n",
+                processTypeString.get(), promisesString.get()));
+    } else if (errno == EPERM) {
+        MOZ_LOG(sPledgeLog, LogLevel::Error,
+               ("pledge promises for %s process can't elevate privileges: '%s'\n",
+                processTypeString.get(), promisesString.get()));
+    }
+    return false;
+  } else {
+      MOZ_LOG(sPledgeLog, LogLevel::Debug,
+             ("pledged %s process with promises: '%s'\n",
+              processTypeString.get(), promisesString.get()));
+  }
+  return true;
+}
+#endif
+
 #if !defined(XP_WIN)
 bool IsDevelopmentBuild()
 {
   nsCOMPtr<nsIFile> path = mozilla::Omnijar::GetPath(mozilla::Omnijar::GRE);
   // If the path doesn't exist, we're a dev build.
   return path == nullptr;
 }
 #endif /* !XP_WIN */
--- a/security/sandbox/common/SandboxSettings.h
+++ b/security/sandbox/common/SandboxSettings.h
@@ -16,10 +16,14 @@ int GetEffectiveContentSandboxLevel();
 
 // Checks whether the effective content sandbox level is > 0.
 bool IsContentSandboxEnabled();
 
 #if defined(XP_MACOSX)
 int ClampFlashSandboxLevel(const int aLevel);
 #endif
 
+#if defined(__OpenBSD__)
+bool StartOpenBSDSandbox(GeckoProcessType type);
+#endif
+
 }
 #endif // mozilla_SandboxPolicies_h
--- a/toolkit/xre/nsAppRunner.cpp
+++ b/toolkit/xre/nsAppRunner.cpp
@@ -4379,16 +4379,19 @@ void AddSandboxAnnotations()
 #if defined(XP_WIN)
   // All supported Windows versions support some level of content sandboxing
   sandboxCapable = true;
 #elif defined(XP_MACOSX)
   // All supported OS X versions are capable
   sandboxCapable = true;
 #elif defined(XP_LINUX)
   sandboxCapable = SandboxInfo::Get().CanSandboxContent();
+#elif defined(__OpenBSD__)
+  sandboxCapable = true;
+  StartOpenBSDSandbox(GeckoProcessType_Default);
 #endif
 
   CrashReporter::AnnotateCrashReport(
     CrashReporter::Annotation::ContentSandboxCapable, sandboxCapable);
 }
 #endif /* MOZ_CONTENT_SANDBOX */
 
 /*