Bug 1361733 - In debug builds, do not allow content sandbox to write to all of /private/var
This permission was needed for the memory bloat logging, which is used for
leaktest, including logging intentionally crashing processes. Now we restrict
ourselves to only allowing writes to the location needed for this logging,
rather than all of /private/var.
MozReview-Commit-ID: 5AbJEZlDHNV
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -1274,16 +1274,40 @@ GetAppPaths(nsCString &aAppPath, nsCStri
static 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;
}
+// This function is only used in an |#ifdef DEBUG| path.
+#ifdef DEBUG
+// Given a path to a file, return the directory which contains it.
+static nsAutoCString
+GetDirectoryPath(const char *aPath) {
+ nsCOMPtr<nsIFile> file = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
+ if (!file ||
+ NS_FAILED(file->InitWithNativePath(nsDependentCString(aPath)))) {
+ MOZ_CRASH("Failed to create or init an nsIFile");
+ }
+ nsCOMPtr<nsIFile> directoryFile;
+ if (NS_FAILED(file->GetParent(getter_AddRefs(directoryFile))) ||
+ !directoryFile) {
+ MOZ_CRASH("Failed to get parent for an nsIFile");
+ }
+ directoryFile->Normalize();
+ nsAutoCString directoryPath;
+ if (NS_FAILED(directoryFile->GetNativePath(directoryPath))) {
+ MOZ_CRASH("Failed to get path for an nsIFile");
+ }
+ return directoryPath;
+}
+#endif // DEBUG
+
static bool
StartMacOSContentSandbox()
{
int sandboxLevel = Preferences::GetInt("security.sandbox.content.level");
if (sandboxLevel < 1) {
return false;
}
@@ -1347,16 +1371,29 @@ StartMacOSContentSandbox()
if (profileDir) {
info.hasSandboxedProfile = true;
info.profileDir.assign(profileDirPath.get());
} else {
info.hasSandboxedProfile = false;
}
+#ifdef DEBUG
+ // When a content process dies intentionally (|NoteIntentionalCrash|), for
+ // tests it wants to log that it did this. Allow writing to this location
+ // that the testrunner wants.
+ char *bloatLog = PR_GetEnv("XPCOM_MEM_BLOAT_LOG");
+ if (bloatLog != nullptr) {
+ // |bloatLog| points to a specific file, but we actually write to a sibling
+ // of that path.
+ nsAutoCString bloatDirectoryPath = GetDirectoryPath(bloatLog);
+ info.debugWriteDir.assign(bloatDirectoryPath.get());
+ }
+#endif // DEBUG
+
std::string err;
if (!mozilla::StartMacSandbox(info, err)) {
NS_WARNING(err.c_str());
MOZ_CRASH("sandbox_init() failed");
}
return true;
}
--- a/security/sandbox/mac/Sandbox.h
+++ b/security/sandbox/mac/Sandbox.h
@@ -43,27 +43,29 @@ typedef struct _MacSandboxInfo {
shouldLog(true) {}
_MacSandboxInfo(const struct _MacSandboxInfo& other)
: type(other.type), level(other.level),
hasFilePrivileges(other.hasFilePrivileges),
hasSandboxedProfile(other.hasSandboxedProfile),
pluginInfo(other.pluginInfo),
appPath(other.appPath), appBinaryPath(other.appBinaryPath),
appDir(other.appDir), appTempDir(other.appTempDir),
- profileDir(other.profileDir), shouldLog(other.shouldLog) {}
+ profileDir(other.profileDir), debugWriteDir(other.debugWriteDir),
+ shouldLog(other.shouldLog) {}
MacSandboxType type;
int32_t level;
bool hasFilePrivileges;
bool hasSandboxedProfile;
MacSandboxPluginInfo pluginInfo;
std::string appPath;
std::string appBinaryPath;
std::string appDir;
std::string appTempDir;
std::string profileDir;
+ std::string debugWriteDir;
bool shouldLog;
} MacSandboxInfo;
namespace mozilla {
bool StartMacSandbox(MacSandboxInfo aInfo, std::string &aErrorMessage);
} // namespace mozilla
--- a/security/sandbox/mac/Sandbox.mm
+++ b/security/sandbox/mac/Sandbox.mm
@@ -173,22 +173,22 @@ bool StartMacSandbox(MacSandboxInfo aInf
params.push_back("PROFILE_DIR");
params.push_back(aInfo.profileDir.c_str());
params.push_back("HOME_PATH");
params.push_back(getenv("HOME"));
params.push_back("HAS_SANDBOXED_PROFILE");
params.push_back(aInfo.hasSandboxedProfile ? "TRUE" : "FALSE");
params.push_back("HAS_FILE_PRIVILEGES");
params.push_back(aInfo.hasFilePrivileges ? "TRUE" : "FALSE");
- params.push_back("DEBUG_BUILD");
#ifdef DEBUG
- params.push_back("TRUE");
-#else
- params.push_back("FALSE");
-#endif
+ if (!aInfo.debugWriteDir.empty()) {
+ params.push_back("DEBUG_WRITE_DIR");
+ params.push_back(aInfo.debugWriteDir.c_str());
+ }
+#endif // DEBUG
} else {
fprintf(stderr,
"Content sandbox disabled due to sandbox level setting\n");
return false;
}
}
else {
char *msg = NULL;
--- a/security/sandbox/mac/SandboxPolicies.h
+++ b/security/sandbox/mac/SandboxPolicies.h
@@ -44,30 +44,30 @@ static const char pluginSandboxRules[] =
static const char widevinePluginSandboxRulesAddend[] = R"(
(allow mach-lookup (global-name "com.apple.windowserver.active"))
)";
static const char contentSandboxRules[] = R"(
(version 1)
- (define should-log (param "SHOULD_LOG"))
+ (define should-log (param "SHOULD_LOG"))
(define sandbox-level-1 (param "SANDBOX_LEVEL_1"))
(define sandbox-level-2 (param "SANDBOX_LEVEL_2"))
(define sandbox-level-3 (param "SANDBOX_LEVEL_3"))
(define macosMinorVersion-9 (param "MAC_OS_MINOR_9"))
(define appPath (param "APP_PATH"))
(define appBinaryPath (param "APP_BINARY_PATH"))
(define appDir (param "APP_DIR"))
(define appTempDir (param "APP_TEMP_DIR"))
(define hasProfileDir (param "HAS_SANDBOXED_PROFILE"))
(define profileDir (param "PROFILE_DIR"))
(define home-path (param "HOME_PATH"))
(define hasFilePrivileges (param "HAS_FILE_PRIVILEGES"))
- (define isDebugBuild (param "DEBUG_BUILD"))
+ (define debugWriteDir (param "DEBUG_WRITE_DIR"))
; Allow read access to standard system paths.
(allow file-read*
(require-all (file-mode #o0004)
(require-any (subpath "/Library/Filesystems/NetFSPlugins")
(subpath "/System")
(subpath "/usr/lib")
(subpath "/usr/share"))))
@@ -219,18 +219,18 @@ static const char contentSandboxRules[]
(allow file-read-metadata (home-subpath "/Library"))
(allow file-read-metadata
(literal "/private/var")
(subpath "/private/var/folders"))
; bug 1303987
- (if (string=? isDebugBuild "TRUE")
- (allow file-write* (subpath "/private/var")))
+ (if (string? debugWriteDir)
+ (allow file-write* (subpath debugWriteDir)))
; bug 1324610
(allow network-outbound (literal "/private/var/run/cupsd"))
(allow-shared-list "org.mozilla.plugincontainer")
; the following rule should be removed when microphone access
; is brokered through the content process
@@ -317,18 +317,17 @@ static const char contentSandboxRules[]
(iokit-user-client-class "AppleGraphicsPolicyClient"))
; bug 1153809
(allow iokit-open
(iokit-user-client-class "NVDVDContextTesla")
(iokit-user-client-class "Gen6DVDContext"))
; bug 1237847
- (allow file-read*
+ (allow file-read* file-write*
(subpath appTempDir))
- (allow file-write*
- (subpath appTempDir))
+
)
)";
}
#endif // mozilla_SandboxPolicies_h