From 5c65115cb9e028060a8736f09efd6fcffbbefb46 Mon Sep 17 00:00:00 2001 From: Alex Gaynor Date: Fri, 7 Apr 2017 14:53:19 -0400 Subject: [PATCH] Bug 1294641 - whitelist reads from the .app directory in the macOS sandbox r=froydnj,haik This patch does a few things: a) Adds the resources location from the .app directory to the read whitelist b) When it's a non-packaged build, mach run (and various mach tests) set an environment variable for the repo location which we allow reads from. r=haik,froydnj MozReview-Commit-ID: KNvAoUs5Ati --- dom/ipc/ContentChild.cpp | 28 +++++++++++++++++++++-- layout/tools/reftest/mach_commands.py | 1 + layout/tools/reftest/runreftest.py | 1 + python/mozbuild/mozbuild/mach_commands.py | 4 +++- testing/mochitest/mach_commands.py | 1 + testing/mochitest/mochitest_options.py | 3 +++ testing/mochitest/runtests.py | 3 +++ testing/xpcshell/runxpcshelltests.py | 1 + 8 files changed, 39 insertions(+), 3 deletions(-) diff --git a/dom/ipc/ContentChild.cpp b/dom/ipc/ContentChild.cpp index ef72b63621f8e..284136940b0e5 100644 --- a/dom/ipc/ContentChild.cpp +++ b/dom/ipc/ContentChild.cpp @@ -59,6 +59,7 @@ #include "mozilla/layout/RenderFrameChild.h" #include "mozilla/net/NeckoChild.h" #include "mozilla/net/CaptivePortalService.h" +#include "mozilla/Omnijar.h" #include "mozilla/plugins/PluginInstanceParent.h" #include "mozilla/plugins/PluginModuleParent.h" #include "mozilla/widget/ScreenManager.h" @@ -1225,7 +1226,7 @@ GetAppPaths(nsCString &aAppPath, nsCString &aAppBinaryPath, nsCString &aAppDir) if (!dirSvc) { return false; } - rv = dirSvc->Get(NS_XPCOM_CURRENT_PROCESS_DIR, + rv = dirSvc->Get(NS_GRE_DIR, NS_GET_IID(nsIFile), getter_AddRefs(appDir)); if (NS_FAILED(rv)) { return false; @@ -1259,6 +1260,18 @@ GetAppPaths(nsCString &aAppPath, nsCString &aAppBinaryPath, nsCString &aAppDir) return true; } +// 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/. +static bool +IsDevelopmentBuild() +{ + nsCOMPtr path = mozilla::Omnijar::GetPath(mozilla::Omnijar::GRE); + // If the path doesn't exist, we're a dev build. + return path == nullptr; +} + static bool StartMacOSContentSandbox() { @@ -1302,6 +1315,13 @@ StartMacOSContentSandbox() } bool isFileProcess = cc->GetRemoteType().EqualsLiteral(FILE_REMOTE_TYPE); + char *developer_repo_dir = nullptr; + if (IsDevelopmentBuild()) { + // If this is a developer build the resources in the .app are symlinks to + // outside of the .app. Therefore in non-release builds we allow reads from + // the whole repository. MOZ_DEVELOPER_REPO_DIR is set by mach run. + developer_repo_dir = PR_GetEnv("MOZ_DEVELOPER_REPO_DIR"); + } MacSandboxInfo info; info.type = MacSandboxType_Content; @@ -1311,7 +1331,11 @@ StartMacOSContentSandbox() PR_GetEnv("MOZ_SANDBOX_LOGGING"); info.appPath.assign(appPath.get()); info.appBinaryPath.assign(appBinaryPath.get()); - info.appDir.assign(appDir.get()); + if (developer_repo_dir != nullptr) { + info.appDir.assign(developer_repo_dir); + } else { + info.appDir.assign(appDir.get()); + } info.appTempDir.assign(tempDirPath.get()); if (profileDir) { diff --git a/layout/tools/reftest/mach_commands.py b/layout/tools/reftest/mach_commands.py index f2d6e72cfc2d8..f1fb914459718 100644 --- a/layout/tools/reftest/mach_commands.py +++ b/layout/tools/reftest/mach_commands.py @@ -222,6 +222,7 @@ def run_crashtest(self, **kwargs): return self._run_reftest(**kwargs) def _run_reftest(self, **kwargs): + kwargs["topsrcdir"] = self.topsrcdir process_test_objects(kwargs) reftest = self._spawn(ReftestRunner) if conditions.is_android(self): diff --git a/layout/tools/reftest/runreftest.py b/layout/tools/reftest/runreftest.py index f98368e5bbced..1fd33d35a8290 100644 --- a/layout/tools/reftest/runreftest.py +++ b/layout/tools/reftest/runreftest.py @@ -362,6 +362,7 @@ def buildBrowserEnv(self, options, profileDir): browserEnv = self.environment( xrePath=options.xrePath, debugger=options.debugger) browserEnv["XPCOM_DEBUG_BREAK"] = "stack" + browserEnv["MOZ_DEVELOPER_REPO_DIR"] = options.topsrcdir if mozinfo.info["asan"]: # Disable leak checking for reftests for now diff --git a/python/mozbuild/mozbuild/mach_commands.py b/python/mozbuild/mozbuild/mach_commands.py index 2c73eca3a64cf..3d2ebc17c67e9 100644 --- a/python/mozbuild/mozbuild/mach_commands.py +++ b/python/mozbuild/mozbuild/mach_commands.py @@ -1182,7 +1182,9 @@ def run(self, params, remote, background, noprofile, disable_e10s, args.append('-profile') args.append(path) - extra_env = {} + extra_env = { + 'MOZ_DEVELOPER_REPO_DIR': self.topsrcdir, + } if not enable_crash_reporter: extra_env['MOZ_CRASHREPORTER_DISABLE'] = '1' diff --git a/testing/mochitest/mach_commands.py b/testing/mochitest/mach_commands.py index 994431c1b7024..3b8eee9e589b1 100644 --- a/testing/mochitest/mach_commands.py +++ b/testing/mochitest/mach_commands.py @@ -139,6 +139,7 @@ def run_desktop_test(self, context, tests=None, suite=None, **kwargs): logging.getLogger().removeHandler(handler) options = Namespace(**kwargs) + options.topsrcdir = self.topsrcdir from manifestparser import TestManifest if tests and not options.manifestFile: diff --git a/testing/mochitest/mochitest_options.py b/testing/mochitest/mochitest_options.py index 3886b24680c7e..e468bf9575814 100644 --- a/testing/mochitest/mochitest_options.py +++ b/testing/mochitest/mochitest_options.py @@ -1002,6 +1002,9 @@ def validate(self, parser, options, context): if options.xrePath is None: options.xrePath = options.utilityPath + if build_obj: + options.topsrcdir = build_obj.topsrcdir + if options.pidFile != "": f = open(options.pidFile, 'w') f.write("%s" % os.getpid()) diff --git a/testing/mochitest/runtests.py b/testing/mochitest/runtests.py index 3bc18f1b3f140..ddd5df23a91d3 100644 --- a/testing/mochitest/runtests.py +++ b/testing/mochitest/runtests.py @@ -1577,6 +1577,9 @@ def buildBrowserEnv(self, options, debugger=False, env=None): dmdPath=options.dmdPath, lsanPath=lsanPath) + if hasattr(options, "topsrcdir"): + browserEnv["MOZ_DEVELOPER_REPO_DIR"] = options.topsrcdir + # These variables are necessary for correct application startup; change # via the commandline at your own risk. browserEnv["XPCOM_DEBUG_BREAK"] = "stack" diff --git a/testing/xpcshell/runxpcshelltests.py b/testing/xpcshell/runxpcshelltests.py index bcdfa107de8f5..5d9f78483c2e2 100755 --- a/testing/xpcshell/runxpcshelltests.py +++ b/testing/xpcshell/runxpcshelltests.py @@ -921,6 +921,7 @@ def buildCoreEnvironment(self): # enable non-local connections for the purposes of local testing. # Don't override the user's choice here. See bug 1049688. self.env.setdefault('MOZ_DISABLE_NONLOCAL_CONNECTIONS', '1') + self.env["MOZ_DEVELOPER_REPO_DIR"] = self.mozInfo["topsrcdir"] def buildEnvironment(self): """