Bug 1386832 - Part 1 - Move non-sandbox-specific routines out of SandboxSettings. r=jimm
Moves IsDevelopmentBuild(), GetRepoDir(), and GetObjectDir() out of
SandboxSettings because they also need to be used by ExtensionProtocolHandler
to do security checks on developer builds as a result of how developer builds
rely on symlinks to the repo dir from system extension directories.
Remove the Linux-implementation of GetRepoDir() and GetObjectDir()
because the Linux content sandbox implementation and the
ExtensionProtocolHandler checks don't need them.
MozReview-Commit-ID: KwBFUnh6Cml
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -68,16 +68,20 @@
#include "nsBaseDragService.h"
#include "mozilla/media/MediaChild.h"
#include "mozilla/BasePrincipal.h"
#include "mozilla/WebBrowserPersistDocumentChild.h"
#include "imgLoader.h"
#include "GMPServiceChild.h"
#include "NullPrincipal.h"
+#if !defined(XP_WIN)
+#include "mozilla/Omnijar.h"
+#endif
+
#ifdef MOZ_GECKO_PROFILER
#include "ChildProfilerController.h"
#endif
#if defined(MOZ_CONTENT_SANDBOX)
#include "mozilla/SandboxSettings.h"
#if defined(XP_WIN)
#define TARGET_SANDBOX_EXPORTS
@@ -167,16 +171,24 @@
#ifdef XP_WIN
#include <process.h>
#define getpid _getpid
#include "mozilla/widget/AudioSession.h"
#include "mozilla/audio/AudioNotificationReceiver.h"
#endif
+#if defined(XP_MACOSX)
+#include <CoreServices/CoreServices.h>
+// Info.plist key associated with the developer repo path
+#define MAC_DEV_REPO_KEY "MozillaDeveloperRepoPath"
+// Info.plist key associated with the developer repo object directory
+#define MAC_DEV_OBJ_KEY "MozillaDeveloperObjPath"
+#endif /* XP_MACOSX */
+
#ifdef MOZ_X11
#include "mozilla/X11Util.h"
#endif
#ifdef ACCESSIBILITY
#include "nsAccessibilityService.h"
#ifdef XP_WIN
#include "mozilla/a11y/AccessibleWrap.h"
@@ -3544,9 +3556,130 @@ ContentChild::GetSpecificMessageEventTar
|| aMsg.type() == PJavaScript::Msg_DropObject__ID) {
return do_AddRef(SystemGroup::EventTargetFor(TaskCategory::Other));
}
return nullptr;
}
} // namespace dom
+
+#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 */
+
+#if defined(XP_MACOSX)
+/*
+ * Helper function to read a string value for a given key from the .app's
+ * Info.plist.
+ */
+static nsresult
+GetStringValueFromBundlePlist(const nsAString& aKey, nsAutoCString& aValue)
+{
+ CFBundleRef mainBundle = CFBundleGetMainBundle();
+ if (mainBundle == nullptr) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Read this app's bundle Info.plist as a dictionary
+ CFDictionaryRef bundleInfoDict = CFBundleGetInfoDictionary(mainBundle);
+ if (bundleInfoDict == nullptr) {
+ return NS_ERROR_FAILURE;
+ }
+
+ nsAutoCString keyAutoCString = NS_ConvertUTF16toUTF8(aKey);
+ CFStringRef key = CFStringCreateWithCString(kCFAllocatorDefault,
+ keyAutoCString.get(),
+ kCFStringEncodingUTF8);
+ if (key == nullptr) {
+ return NS_ERROR_FAILURE;
+ }
+
+ CFStringRef value = (CFStringRef)CFDictionaryGetValue(bundleInfoDict, key);
+ CFRelease(key);
+ if (value == nullptr) {
+ return NS_ERROR_FAILURE;
+ }
+
+ CFIndex valueLength = CFStringGetLength(value);
+ if (valueLength == 0) {
+ return NS_ERROR_FAILURE;
+ }
+
+ const char* valueCString = CFStringGetCStringPtr(value,
+ kCFStringEncodingUTF8);
+ if (valueCString) {
+ aValue.Assign(valueCString);
+ return NS_OK;
+ }
+
+ CFIndex maxLength =
+ CFStringGetMaximumSizeForEncoding(valueLength, kCFStringEncodingUTF8) + 1;
+ char* valueBuffer = static_cast<char*>(moz_xmalloc(maxLength));
+ if (!valueBuffer) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ if (!CFStringGetCString(value, valueBuffer, maxLength,
+ kCFStringEncodingUTF8)) {
+ free(valueBuffer);
+ return NS_ERROR_FAILURE;
+ }
+
+ aValue.Assign(valueBuffer);
+ free(valueBuffer);
+ return NS_OK;
+}
+
+/*
+ * Helper function for reading a path string from the .app's Info.plist
+ * and returning a directory object for that path with symlinks resolved.
+ */
+static nsresult
+GetDirFromBundlePlist(const nsAString& aKey, nsIFile **aDir)
+{
+ nsresult rv;
+
+ nsAutoCString dirPath;
+ rv = GetStringValueFromBundlePlist(aKey, dirPath);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIFile> dir;
+ rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(dirPath),
+ false,
+ getter_AddRefs(dir));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = dir->Normalize();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ bool isDirectory = false;
+ rv = dir->IsDirectory(&isDirectory);
+ NS_ENSURE_SUCCESS(rv, rv);
+ if (!isDirectory) {
+ return NS_ERROR_FILE_NOT_DIRECTORY;
+ }
+
+ dir.swap(*aDir);
+ return NS_OK;
+}
+
+nsresult
+GetRepoDir(nsIFile **aRepoDir)
+{
+ MOZ_ASSERT(IsDevelopmentBuild());
+ return GetDirFromBundlePlist(NS_LITERAL_STRING(MAC_DEV_REPO_KEY), aRepoDir);
+}
+
+nsresult
+GetObjDir(nsIFile **aObjDir)
+{
+ MOZ_ASSERT(IsDevelopmentBuild());
+ return GetDirFromBundlePlist(NS_LITERAL_STRING(MAC_DEV_OBJ_KEY), aObjDir);
+}
+#endif /* XP_MACOSX */
+
} // namespace mozilla
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -35,16 +35,33 @@ class nsIURIClassifierCallback;
struct LookAndFeelInt;
namespace mozilla {
class RemoteSpellcheckEngineChild;
class ChildProfilerController;
using mozilla::loader::PScriptCacheChild;
+#if !defined(XP_WIN)
+// Returns whether or not the currently running build is an unpackaged
+// developer build. This check is implemented by looking for omni.ja in the
+// the obj/dist dir. We use this routine to detect when the build dir will
+// use symlinks to the repo and object dir. On Windows, dev builds don't
+// use symlinks.
+bool IsDevelopmentBuild();
+#endif /* !XP_WIN */
+
+#if defined(XP_MACOSX)
+// Return the repo directory and the repo object directory respectively. These
+// should only be used on Mac developer builds to determine the path to the
+// repo or object directory.
+nsresult GetRepoDir(nsIFile **aRepoDir);
+nsresult GetObjDir(nsIFile **aObjDir);
+#endif /* XP_MACOSX */
+
namespace ipc {
class OptionalURIParams;
class URIParams;
}// namespace ipc
namespace dom {
class AlertObserver;
--- a/security/sandbox/common/SandboxSettings.cpp
+++ b/security/sandbox/common/SandboxSettings.cpp
@@ -1,195 +1,21 @@
/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* vim: set ts=8 sts=2 et sw=2 tw=80: */
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this file,
* You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "mozISandboxSettings.h"
-#include "mozilla/Omnijar.h"
#include "mozilla/ModuleUtils.h"
#include "mozilla/Preferences.h"
-#include "nsDirectoryServiceDefs.h"
-
-#if defined(XP_MACOSX)
-#include <CoreServices/CoreServices.h>
-// Info.plist key associated with the developer repo path
-#define MAC_DEV_REPO_KEY "MozillaDeveloperRepoPath"
-// Info.plist key associated with the developer repo object directory
-#define MAC_DEV_OBJ_KEY "MozillaDeveloperObjPath"
-#else
-#include "prenv.h"
-#endif /* XP_MACOSX */
-
namespace mozilla {
-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;
-}
-
-#if defined(XP_MACOSX)
-/*
- * Helper function to read a string value for a given key from the .app's
- * Info.plist.
- */
-static nsresult
-GetStringValueFromBundlePlist(const nsAString& aKey, nsAutoCString& aValue)
-{
- CFBundleRef mainBundle = CFBundleGetMainBundle();
- if (mainBundle == nullptr) {
- return NS_ERROR_FAILURE;
- }
-
- // Read this app's bundle Info.plist as a dictionary
- CFDictionaryRef bundleInfoDict = CFBundleGetInfoDictionary(mainBundle);
- if (bundleInfoDict == nullptr) {
- return NS_ERROR_FAILURE;
- }
-
- nsAutoCString keyAutoCString = NS_ConvertUTF16toUTF8(aKey);
- CFStringRef key = CFStringCreateWithCString(kCFAllocatorDefault,
- keyAutoCString.get(),
- kCFStringEncodingUTF8);
- if (key == nullptr) {
- return NS_ERROR_FAILURE;
- }
-
- CFStringRef value = (CFStringRef)CFDictionaryGetValue(bundleInfoDict, key);
- CFRelease(key);
- if (value == nullptr) {
- return NS_ERROR_FAILURE;
- }
-
- CFIndex valueLength = CFStringGetLength(value);
- if (valueLength == 0) {
- return NS_ERROR_FAILURE;
- }
-
- const char* valueCString = CFStringGetCStringPtr(value,
- kCFStringEncodingUTF8);
- if (valueCString) {
- aValue.Assign(valueCString);
- return NS_OK;
- }
-
- CFIndex maxLength =
- CFStringGetMaximumSizeForEncoding(valueLength, kCFStringEncodingUTF8) + 1;
- char* valueBuffer = static_cast<char*>(moz_xmalloc(maxLength));
- if (!valueBuffer) {
- return NS_ERROR_OUT_OF_MEMORY;
- }
-
- if (!CFStringGetCString(value, valueBuffer, maxLength,
- kCFStringEncodingUTF8)) {
- free(valueBuffer);
- return NS_ERROR_FAILURE;
- }
-
- aValue.Assign(valueBuffer);
- free(valueBuffer);
- return NS_OK;
-}
-
-/*
- * Helper function for reading a path string from the .app's Info.plist
- * and returning a directory object for that path with symlinks resolved.
- */
-static nsresult
-GetDirFromBundlePlist(const nsAString& aKey, nsIFile **aDir)
-{
- nsresult rv;
-
- nsAutoCString dirPath;
- rv = GetStringValueFromBundlePlist(aKey, dirPath);
- NS_ENSURE_SUCCESS(rv, rv);
-
- nsCOMPtr<nsIFile> dir;
- rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(dirPath),
- false,
- getter_AddRefs(dir));
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = dir->Normalize();
- NS_ENSURE_SUCCESS(rv, rv);
-
- bool isDirectory = false;
- rv = dir->IsDirectory(&isDirectory);
- NS_ENSURE_SUCCESS(rv, rv);
- if (!isDirectory) {
- return NS_ERROR_FILE_NOT_DIRECTORY;
- }
-
- dir.swap(*aDir);
- return NS_OK;
-}
-
-#else /* !XP_MACOSX */
-
-/*
- * Helper function for getting a directory object for a given env variable
- */
-static nsresult
-GetDirFromEnv(const char* aEnvVar, nsIFile **aDir)
-{
- nsresult rv;
-
- nsCOMPtr<nsIFile> dir;
- const char *dir_path = PR_GetEnv(aEnvVar);
- if (!dir_path) {
- return NS_ERROR_INVALID_ARG;
- }
-
- rv = NS_NewLocalFile(NS_ConvertUTF8toUTF16(dir_path),
- false,
- getter_AddRefs(dir));
- NS_ENSURE_SUCCESS(rv, rv);
-
- rv = dir->Normalize();
- NS_ENSURE_SUCCESS(rv, rv);
-
- bool isDirectory = false;
- rv = dir->IsDirectory(&isDirectory);
- NS_ENSURE_SUCCESS(rv, rv);
- if (!isDirectory) {
- return NS_ERROR_FILE_NOT_DIRECTORY;
- }
-
- dir.swap(*aDir);
- return NS_OK;
-}
-#endif /* XP_MACOSX */
-
-nsresult
-GetRepoDir(nsIFile **aRepoDir)
-{
- MOZ_ASSERT(IsDevelopmentBuild());
-#if defined(XP_MACOSX)
- return GetDirFromBundlePlist(NS_LITERAL_STRING(MAC_DEV_REPO_KEY), aRepoDir);
-#else
- return GetDirFromEnv("MOZ_DEVELOPER_REPO_DIR", aRepoDir);
-#endif /* XP_MACOSX */
-}
-
-nsresult
-GetObjDir(nsIFile **aObjDir)
-{
- MOZ_ASSERT(IsDevelopmentBuild());
-#if defined(XP_MACOSX)
- return GetDirFromBundlePlist(NS_LITERAL_STRING(MAC_DEV_OBJ_KEY), aObjDir);
-#else
- return GetDirFromEnv("MOZ_DEVELOPER_OBJ_DIR", aObjDir);
-#endif /* XP_MACOSX */
-}
-
int GetEffectiveContentSandboxLevel() {
int level = Preferences::GetInt("security.sandbox.content.level");
// On Windows and macOS, enforce a minimum content sandbox level of 1 (except on
// Nightly, where it can be set to 0).
#if !defined(NIGHTLY_BUILD) && (defined(XP_WIN) || defined(XP_MACOSX))
if (level < 1) {
level = 1;
}
--- a/security/sandbox/common/SandboxSettings.h
+++ b/security/sandbox/common/SandboxSettings.h
@@ -8,21 +8,10 @@
namespace mozilla {
// Return the current sandbox level. This is the
// "security.sandbox.content.level" preference, but rounded up to the current
// minimum allowed level.
int GetEffectiveContentSandboxLevel();
-// Returns whether or not the currently running build is a development build -
-// where development build means "the files in the .app are symlinks to the src
-// directory". This check is implemented by looking for omni.ja in
-// .app/Contents/Resources/.
-bool IsDevelopmentBuild();
-
-// Return the repo directory and the repo object directory respectively. These
-// should only be used on developer builds to determine the path to the repo
-// or object directory.
-nsresult GetRepoDir(nsIFile **aRepoDir);
-nsresult GetObjDir(nsIFile **aObjDir);
}
#endif // mozilla_SandboxPolicies_h