Bug 1457092 - Implement sandboxing on OpenBSD. r=gcp, r=jld
authorLandry Breuil <landry@openbsd.org>
Thu, 23 Aug 2018 07:35:00 -0400
changeset 831084 8f5c17ac83aa8cd493b9b051820ccc4d61c46a14
parent 831083 51b6bdb9197cc31d56533c5209adc9a314b8bb59
child 831085 411427c1f5fe876edcd92f31b3c86bbb8d509ac7
push id118868
push userbmo:zjz@zjz.name
push dateFri, 24 Aug 2018 07:04:39 +0000
reviewersgcp, jld
bugs1457092
milestone63.0a1
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 */
 
 /*