diff --git a/browser/app/profile/firefox.js b/browser/app/profile/firefox.js index df90f4d7d951..2072c10b8210 100644 --- a/browser/app/profile/firefox.js +++ b/browser/app/profile/firefox.js @@ -1194,6 +1194,8 @@ pref("security.sandbox.windows.log", false); // 0 - no sandbox // 1 - sandbox with USER_NON_ADMIN access token level // 2 - a more strict sandbox, which might cause functionality issues +// 3 - the strongest settings we seem to be able to use without breaking +// everything, but will definitely cause some functionality restrictions pref("dom.ipc.plugins.sandbox-level.default", 0); pref("dom.ipc.plugins.sandbox-level.flash", 1); diff --git a/dom/plugins/ipc/PluginProcessParent.cpp b/dom/plugins/ipc/PluginProcessParent.cpp index fc82a034d4c9..5434a7cfc82c 100644 --- a/dom/plugins/ipc/PluginProcessParent.cpp +++ b/dom/plugins/ipc/PluginProcessParent.cpp @@ -14,6 +14,10 @@ #include "mozilla/Telemetry.h" #include "nsThreadUtils.h" +#if defined(XP_WIN) && defined(MOZ_SANDBOX) +#include "nsDirectoryServiceDefs.h" +#endif + using std::vector; using std::string; @@ -42,12 +46,67 @@ PluginProcessParent::~PluginProcessParent() { } +#if defined(XP_WIN) && defined(MOZ_SANDBOX) +static void +AddSandboxAllowedFile(vector& aAllowedFiles, nsIProperties* aDirSvc, + const char* aDir, const nsAString& aSuffix = EmptyString()) +{ + nsCOMPtr userDir; + nsresult rv = aDirSvc->Get(aDir, NS_GET_IID(nsIFile), getter_AddRefs(userDir)); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + nsAutoString userDirPath; + rv = userDir->GetPath(userDirPath); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + if (!aSuffix.IsEmpty()) { + userDirPath.Append(aSuffix); + } + aAllowedFiles.push_back(userDirPath.get()); + return; +} + +static void +AddSandboxAllowedFiles(int32_t aSandboxLevel, + vector& aAllowedFilesRead, + vector& aAllowedFilesReadWrite) +{ + if (aSandboxLevel < 3) { + return; + } + + nsresult rv; + nsCOMPtr dirSvc = + do_GetService(NS_DIRECTORY_SERVICE_CONTRACTID, &rv); + if (NS_WARN_IF(NS_FAILED(rv))) { + return; + } + + AddSandboxAllowedFile(aAllowedFilesRead, dirSvc, NS_WIN_HOME_DIR); + AddSandboxAllowedFile(aAllowedFilesRead, dirSvc, NS_WIN_HOME_DIR, + NS_LITERAL_STRING("\\*")); + + AddSandboxAllowedFile(aAllowedFilesReadWrite, dirSvc, NS_WIN_APPDATA_DIR, + NS_LITERAL_STRING("\\Macromedia\\Flash Player\\*")); + AddSandboxAllowedFile(aAllowedFilesReadWrite, dirSvc, NS_WIN_APPDATA_DIR, + NS_LITERAL_STRING("\\Adobe\\Flash Player\\*")); + AddSandboxAllowedFile(aAllowedFilesReadWrite, dirSvc, NS_OS_TEMP_DIR, + NS_LITERAL_STRING("\\*")); +} +#endif + bool PluginProcessParent::Launch(mozilla::UniquePtr aLaunchCompleteTask, int32_t aSandboxLevel) { #if defined(XP_WIN) && defined(MOZ_SANDBOX) mSandboxLevel = aSandboxLevel; + AddSandboxAllowedFiles(mSandboxLevel, mAllowedFilesRead, + mAllowedFilesReadWrite); #else if (aSandboxLevel != 0) { MOZ_ASSERT(false, diff --git a/ipc/glue/GeckoChildProcessHost.cpp b/ipc/glue/GeckoChildProcessHost.cpp index 19d218e2dd40..8cbb2e9a0bfa 100644 --- a/ipc/glue/GeckoChildProcessHost.cpp +++ b/ipc/glue/GeckoChildProcessHost.cpp @@ -848,6 +848,12 @@ GeckoChildProcessHost::PerformAsyncLaunchInternal(std::vector& aExt ++it) { mSandboxBroker.AllowReadFile(it->c_str()); } + + for (auto it = mAllowedFilesReadWrite.begin(); + it != mAllowedFilesReadWrite.end(); + ++it) { + mSandboxBroker.AllowReadWriteFile(it->c_str()); + } } #endif // XP_WIN && MOZ_SANDBOX diff --git a/ipc/glue/GeckoChildProcessHost.h b/ipc/glue/GeckoChildProcessHost.h index 5cee2d0c1bf0..c014c8983459 100644 --- a/ipc/glue/GeckoChildProcessHost.h +++ b/ipc/glue/GeckoChildProcessHost.h @@ -171,6 +171,7 @@ protected: #ifdef MOZ_SANDBOX SandboxBroker mSandboxBroker; std::vector mAllowedFilesRead; + std::vector mAllowedFilesReadWrite; bool mEnableSandboxLogging; int32_t mSandboxLevel; bool mMoreStrictSandbox; diff --git a/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp b/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp index 77cfec870497..b0030c7f4a26 100644 --- a/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp +++ b/security/sandbox/win/src/sandboxbroker/sandboxBroker.cpp @@ -130,8 +130,15 @@ SandboxBroker::SetSecurityLevelForPluginProcess(int32_t aSandboxLevel) 0 /* ui_exceptions */); ret = (sandbox::SBOX_ALL_OK == result); + sandbox::TokenLevel tokenLevel; + if (aSandboxLevel >= 3) { + tokenLevel = sandbox::USER_LIMITED; + } else { + tokenLevel = sandbox::USER_INTERACTIVE; + } + result = mPolicy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS, - sandbox::USER_INTERACTIVE); + tokenLevel); ret = ret && (sandbox::SBOX_ALL_OK == result); sandbox::MitigationFlags mitigations =