Bug 1290619 - Content sandbox rules should use actual profile directory, not Profiles/*/ regex's. r=jimm

Passes the profile dir to the content process as a -profile CLI option so
that the correct profile dir can be used in the OS X content sandbox rules.
Only enabled on OS X for now.

On Nightly, profile directories will now be read/write protected from the
content process (apart from a few profile subdirectories) even when they
don't reside in ~/Library.

--HG--
extra : rebase_source : 7bf426f14f31b35c8b541e6d21183226db9836c7
This commit is contained in:
Haik Aftandilian 2016-08-22 11:58:18 -07:00
parent 957dd2a412
commit d1e8cf113e
8 changed files with 120 additions and 7 deletions

View File

@ -1316,6 +1316,14 @@ StartMacOSContentSandbox()
MOZ_CRASH("Failed to get NS_OS_TEMP_DIR path"); MOZ_CRASH("Failed to get NS_OS_TEMP_DIR path");
} }
nsCOMPtr<nsIFile> profileDir;
ContentChild::GetSingleton()->GetProfileDir(getter_AddRefs(profileDir));
nsCString profileDirPath;
rv = profileDir->GetNativePath(profileDirPath);
if (NS_FAILED(rv)) {
MOZ_CRASH("Failed to get profile path");
}
MacSandboxInfo info; MacSandboxInfo info;
info.type = MacSandboxType_Content; info.type = MacSandboxType_Content;
info.level = info.level = sandboxLevel; info.level = info.level = sandboxLevel;
@ -1323,6 +1331,7 @@ StartMacOSContentSandbox()
info.appBinaryPath.assign(appBinaryPath.get()); info.appBinaryPath.assign(appBinaryPath.get());
info.appDir.assign(appDir.get()); info.appDir.assign(appDir.get());
info.appTempDir.assign(tempDirPath.get()); info.appTempDir.assign(tempDirPath.get());
info.profileDir.assign(profileDirPath.get());
std::string err; std::string err;
if (!mozilla::StartMacSandbox(info, err)) { if (!mozilla::StartMacSandbox(info, err)) {

View File

@ -21,6 +21,9 @@
#include "nsWeakPtr.h" #include "nsWeakPtr.h"
#include "nsIWindowProvider.h" #include "nsIWindowProvider.h"
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
#include "nsIFile.h"
#endif
struct ChromePackage; struct ChromePackage;
class nsIObserver; class nsIObserver;
@ -114,6 +117,18 @@ public:
void GetProcessName(nsACString& aName) const; void GetProcessName(nsACString& aName) const;
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
void GetProfileDir(nsIFile** aProfileDir) const
{
*aProfileDir = mProfileDir;
}
void SetProfileDir(nsIFile* aProfileDir)
{
mProfileDir = aProfileDir;
}
#endif
bool IsAlive() const; bool IsAlive() const;
static void AppendProcessId(nsACString& aName); static void AppendProcessId(nsACString& aName);
@ -684,6 +699,10 @@ private:
nsCOMPtr<nsIDomainPolicy> mPolicy; nsCOMPtr<nsIDomainPolicy> mPolicy;
nsCOMPtr<nsITimer> mForceKillTimer; nsCOMPtr<nsITimer> mForceKillTimer;
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
nsCOMPtr<nsIFile> mProfileDir;
#endif
// Hashtable to keep track of the pending GetFilesHelper objects. // Hashtable to keep track of the pending GetFilesHelper objects.
// This GetFilesHelperChild objects are removed when RecvGetFilesResponse is // This GetFilesHelperChild objects are removed when RecvGetFilesResponse is
// received. // received.

View File

@ -114,6 +114,21 @@ ContentProcess::SetAppDir(const nsACString& aPath)
mXREEmbed.SetAppDir(aPath); mXREEmbed.SetAppDir(aPath);
} }
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
void
ContentProcess::SetProfile(const nsACString& aProfile)
{
bool flag;
nsresult rv =
XRE_GetFileFromPath(aProfile.BeginReading(), getter_AddRefs(mProfileDir));
if (NS_FAILED(rv) ||
NS_FAILED(mProfileDir->Exists(&flag)) || !flag) {
NS_WARNING("Invalid profile directory passed to content process.");
mProfileDir = nullptr;
}
}
#endif
bool bool
ContentProcess::Init() ContentProcess::Init()
{ {
@ -124,6 +139,10 @@ ContentProcess::Init()
mContent.InitXPCOM(); mContent.InitXPCOM();
mContent.InitGraphicsDeviceData(); mContent.InitGraphicsDeviceData();
#if (defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
mContent.SetProfileDir(mProfileDir);
#endif
#if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX) #if (defined(XP_WIN) || defined(XP_MACOSX)) && defined(MOZ_CONTENT_SANDBOX)
SetUpSandboxEnvironment(); SetUpSandboxEnvironment();
#endif #endif

View File

@ -39,9 +39,18 @@ public:
void SetAppDir(const nsACString& aPath); void SetAppDir(const nsACString& aPath);
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
void SetProfile(const nsACString& aProfile);
#endif
private: private:
ContentChild mContent; ContentChild mContent;
mozilla::ipc::ScopedXREEmbed mXREEmbed; mozilla::ipc::ScopedXREEmbed mXREEmbed;
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
nsCOMPtr<nsIFile> mProfileDir;
#endif
#if defined(XP_WIN) #if defined(XP_WIN)
// This object initializes and configures COM. // This object initializes and configures COM.
mozilla::mscom::MainThreadRuntime mCOMRuntime; mozilla::mscom::MainThreadRuntime mCOMRuntime;

View File

@ -23,6 +23,10 @@
#include "prenv.h" #include "prenv.h"
#include "nsXPCOMPrivate.h" #include "nsXPCOMPrivate.h"
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
#include "nsAppDirectoryServiceDefs.h"
#endif
#include "nsExceptionHandler.h" #include "nsExceptionHandler.h"
#include "nsDirectoryServiceDefs.h" #include "nsDirectoryServiceDefs.h"
@ -608,6 +612,20 @@ AddAppDirToCommandLine(std::vector<std::string>& aCmdLine)
aCmdLine.push_back(path.get()); aCmdLine.push_back(path.get());
#endif #endif
} }
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
// Full path to the profile dir
nsCOMPtr<nsIFile> profileDir;
rv = directoryService->Get(NS_APP_USER_PROFILE_50_DIR,
NS_GET_IID(nsIFile),
getter_AddRefs(profileDir));
if (NS_SUCCEEDED(rv)) {
nsAutoCString path;
MOZ_ALWAYS_SUCCEEDS(profileDir->GetNativePath(path));
aCmdLine.push_back("-profile");
aCmdLine.push_back(path.get());
}
#endif
} }
} }
} }

View File

@ -41,7 +41,8 @@ typedef struct _MacSandboxInfo {
_MacSandboxInfo(const struct _MacSandboxInfo& other) _MacSandboxInfo(const struct _MacSandboxInfo& other)
: type(other.type), level(other.level), pluginInfo(other.pluginInfo), : type(other.type), level(other.level), pluginInfo(other.pluginInfo),
appPath(other.appPath), appBinaryPath(other.appBinaryPath), appPath(other.appPath), appBinaryPath(other.appBinaryPath),
appDir(other.appDir), appTempDir(other.appTempDir) {} appDir(other.appDir), appTempDir(other.appTempDir),
profileDir(other.profileDir) {}
MacSandboxType type; MacSandboxType type;
int32_t level; int32_t level;
MacSandboxPluginInfo pluginInfo; MacSandboxPluginInfo pluginInfo;
@ -49,6 +50,7 @@ typedef struct _MacSandboxInfo {
std::string appBinaryPath; std::string appBinaryPath;
std::string appDir; std::string appDir;
std::string appTempDir; std::string appTempDir;
std::string profileDir;
} MacSandboxInfo; } MacSandboxInfo;
namespace mozilla { namespace mozilla {

View File

@ -157,6 +157,7 @@ static const char contentSandboxRules[] =
"(define appBinaryPath \"%s\")\n" "(define appBinaryPath \"%s\")\n"
"(define appDir \"%s\")\n" "(define appDir \"%s\")\n"
"(define appTempDir \"%s\")\n" "(define appTempDir \"%s\")\n"
"(define profileDir \"%s\")\n"
"(define home-path \"%s\")\n" "(define home-path \"%s\")\n"
"\n" "\n"
"; Allow read access to standard system paths.\n" "; Allow read access to standard system paths.\n"
@ -232,6 +233,9 @@ static const char contentSandboxRules[] =
" (define (home-literal home-relative-literal)\n" " (define (home-literal home-relative-literal)\n"
" (resolving-literal (string-append home-path home-relative-literal)))\n" " (resolving-literal (string-append home-path home-relative-literal)))\n"
"\n" "\n"
" (define (profile-subpath profile-relative-subpath)\n"
" (resolving-subpath (string-append profileDir profile-relative-subpath)))\n"
"\n"
" (define (container-regex container-relative-regex)\n" " (define (container-regex container-relative-regex)\n"
" (resolving-regex (string-append \"^\" (regex-quote container-path) container-relative-regex)))\n" " (resolving-regex (string-append \"^\" (regex-quote container-path) container-relative-regex)))\n"
" (define (container-subpath container-relative-subpath)\n" " (define (container-subpath container-relative-subpath)\n"
@ -371,16 +375,17 @@ static const char contentSandboxRules[] =
" (allow file-read*\n" " (allow file-read*\n"
" (home-regex \"/Library/Application Support/[^/]+/Extensions/[^/]/\")\n" " (home-regex \"/Library/Application Support/[^/]+/Extensions/[^/]/\")\n"
" (resolving-regex \"/Library/Application Support/[^/]+/Extensions/[^/]/\")\n" " (resolving-regex \"/Library/Application Support/[^/]+/Extensions/[^/]/\")\n"
" (home-regex \"/Library/Application Support/Firefox/Profiles/[^/]+/extensions/\")\n" " (profile-subpath \"/extensions\")\n"
" (home-regex \"/Library/Application Support/Firefox/Profiles/[^/]+/weave/\"))\n" " (profile-subpath \"/weave\"))\n"
"\n" "\n"
"; the following rules should be removed when printing and \n" "; the following rules should be removed when printing and\n"
"; opening a file from disk are brokered through the main process\n" "; opening a file from disk are brokered through the main process\n"
" (if\n" " (if\n"
" (< sandbox-level 2)\n" " (< sandbox-level 2)\n"
" (allow file*\n" " (allow file*\n"
" (require-not\n" " (require-all\n"
" (home-subpath \"/Library\")))\n" " (require-not (home-subpath \"/Library\"))\n"
" (require-not (subpath profileDir))))\n"
" (allow file*\n" " (allow file*\n"
" (require-all\n" " (require-all\n"
" (subpath home-path)\n" " (subpath home-path)\n"
@ -497,6 +502,7 @@ bool StartMacSandbox(MacSandboxInfo aInfo, std::string &aErrorMessage)
aInfo.appBinaryPath.c_str(), aInfo.appBinaryPath.c_str(),
aInfo.appDir.c_str(), aInfo.appDir.c_str(),
aInfo.appTempDir.c_str(), aInfo.appTempDir.c_str(),
aInfo.profileDir.c_str(),
getenv("HOME")); getenv("HOME"));
} else { } else {
fprintf(stderr, fprintf(stderr,

View File

@ -606,13 +606,44 @@ XRE_InitChildProcess(int aArgc,
case GeckoProcessType_Content: { case GeckoProcessType_Content: {
process = new ContentProcess(parentPID); process = new ContentProcess(parentPID);
// If passed in grab the application path for xpcom init // If passed in grab the application path for xpcom init
nsCString appDir; bool foundAppdir = false;
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
// If passed in grab the profile path for sandboxing
bool foundProfile = false;
#endif
for (int idx = aArgc; idx > 0; idx--) { for (int idx = aArgc; idx > 0; idx--) {
if (aArgv[idx] && !strcmp(aArgv[idx], "-appdir")) { if (aArgv[idx] && !strcmp(aArgv[idx], "-appdir")) {
MOZ_ASSERT(!foundAppdir);
if (foundAppdir) {
continue;
}
nsCString appDir;
appDir.Assign(nsDependentCString(aArgv[idx+1])); appDir.Assign(nsDependentCString(aArgv[idx+1]));
static_cast<ContentProcess*>(process.get())->SetAppDir(appDir); static_cast<ContentProcess*>(process.get())->SetAppDir(appDir);
foundAppdir = true;
}
#if defined(XP_MACOSX) && defined(MOZ_CONTENT_SANDBOX)
if (aArgv[idx] && !strcmp(aArgv[idx], "-profile")) {
MOZ_ASSERT(!foundProfile);
if (foundProfile) {
continue;
}
nsCString profile;
profile.Assign(nsDependentCString(aArgv[idx+1]));
static_cast<ContentProcess*>(process.get())->SetProfile(profile);
foundProfile = true;
}
if (foundProfile && foundAppdir) {
break; break;
} }
#else
if (foundAppdir) {
break;
}
#endif /* XP_MACOSX && MOZ_CONTENT_SANDBOX */
} }
} }
break; break;