Bug 1123759: Set low integrity on NPAPI processes for Windows sandboxing policy level >= 2. r=bbondy, r=bsmedberg

This commit is contained in:
Bob Owen 2015-05-22 17:05:45 +01:00
parent 9f6005f287
commit 836edcd4aa
5 changed files with 88 additions and 59 deletions

View File

@ -1198,9 +1198,10 @@ pref("security.sandbox.windows.log", false);
// On windows these levels are:
// 0 - no sandbox
// 1 - sandbox with USER_NON_ADMIN access token level
// 2 - a more strict sandbox, which might cause functionality issues
// 2 - a more strict sandbox, which might cause functionality issues. This now
// includes running at low integrity.
// 3 - the strongest settings we seem to be able to use without breaking
// everything, but will definitely cause some functionality restrictions
// everything, but will probably cause some functionality restrictions
pref("dom.ipc.plugins.sandbox-level.default", 0);
#if defined(MOZ_CONTENT_SANDBOX)

View File

@ -481,7 +481,8 @@ PluginModuleChromeParent::LoadModule(const char* aFilePath, uint32_t aPluginId,
}
#endif
nsAutoPtr<PluginModuleChromeParent> parent(new PluginModuleChromeParent(aFilePath, aPluginId));
nsAutoPtr<PluginModuleChromeParent> parent(new PluginModuleChromeParent(aFilePath, aPluginId,
sandboxLevel));
UniquePtr<LaunchCompleteTask> onLaunchedRunnable(new LaunchedTask(parent));
parent->mSubprocess->SetCallRunnableImmediately(!parent->mIsStartingAsync);
TimeStamp launchStart = TimeStamp::Now();
@ -564,9 +565,11 @@ PluginModuleChromeParent::OnProcessLaunched(const bool aSucceeded)
#endif
#endif
#ifdef XP_WIN
#if defined(XP_WIN) && defined(_X86_)
// Protected mode only applies to Windows and only to x86.
if (!mIsBlocklisted && mIsFlashPlugin &&
Preferences::GetBool("dom.ipc.plugins.flash.disable-protected-mode", false)) {
(Preferences::GetBool("dom.ipc.plugins.flash.disable-protected-mode", false) ||
mSandboxLevel >= 2)) {
SendDisableFlashProtectedMode();
}
#endif
@ -662,7 +665,9 @@ PluginModuleContentParent::~PluginModuleContentParent()
bool PluginModuleChromeParent::sInstantiated = false;
PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, uint32_t aPluginId)
PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath,
uint32_t aPluginId,
int32_t aSandboxLevel)
: PluginModuleParent(true)
, mSubprocess(new PluginProcessParent(aFilePath))
, mPluginId(aPluginId)
@ -674,6 +679,7 @@ PluginModuleChromeParent::PluginModuleChromeParent(const char* aFilePath, uint32
, mHangUIParent(nullptr)
, mHangUIEnabled(true)
, mIsTimerReset(true)
, mSandboxLevel(aSandboxLevel)
#ifdef MOZ_CRASHREPORTER
, mCrashReporterMutex("PluginModuleChromeParent::mCrashReporterMutex")
, mCrashReporter(nullptr)

View File

@ -443,7 +443,8 @@ private:
virtual void ActorDestroy(ActorDestroyReason why) override;
// aFilePath is UTF8, not native!
explicit PluginModuleChromeParent(const char* aFilePath, uint32_t aPluginId);
explicit PluginModuleChromeParent(const char* aFilePath, uint32_t aPluginId,
int32_t aSandboxLevel);
CrashReporterParent* CrashReporter();
@ -483,6 +484,7 @@ private:
PluginHangUIParent *mHangUIParent;
bool mHangUIEnabled;
bool mIsTimerReset;
int32_t mSandboxLevel;
#ifdef MOZ_CRASHREPORTER
/**
* This mutex protects the crash reporter when the Plugin Hang UI event

View File

@ -76,7 +76,7 @@ AddSandboxAllowedFiles(int32_t aSandboxLevel,
vector<std::wstring>& aAllowedFilesRead,
vector<std::wstring>& aAllowedFilesReadWrite)
{
if (aSandboxLevel < 3) {
if (aSandboxLevel < 2) {
return;
}
@ -87,16 +87,26 @@ AddSandboxAllowedFiles(int32_t aSandboxLevel,
return;
}
AddSandboxAllowedFile(aAllowedFilesRead, dirSvc, NS_WIN_HOME_DIR);
AddSandboxAllowedFile(aAllowedFilesRead, dirSvc, NS_WIN_HOME_DIR,
NS_LITERAL_STRING("\\*"));
// Higher than level 2 currently removes the users own rights.
if (aSandboxLevel > 2) {
AddSandboxAllowedFile(aAllowedFilesRead, dirSvc, NS_WIN_HOME_DIR);
AddSandboxAllowedFile(aAllowedFilesRead, dirSvc, NS_WIN_HOME_DIR,
NS_LITERAL_STRING("\\*"));
}
// Level 2 and above is now using low integrity, so we need to give write
// access to the Flash directories.
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\\*"));
#if defined(_X86_)
// Write access to the Temp directory should only be needed for 32-bit as
// it is used to turn off protected mode, which only applies to x86.
AddSandboxAllowedFile(aAllowedFilesReadWrite, dirSvc, NS_OS_TEMP_DIR,
NS_LITERAL_STRING("\\*"));
#endif
}
#endif

View File

@ -162,57 +162,55 @@ SandboxBroker::SetSecurityLevelForPluginProcess(int32_t aSandboxLevel)
return false;
}
sandbox::ResultCode result;
bool ret;
if (aSandboxLevel >= 2) {
result = mPolicy->SetJobLevel(sandbox::JOB_UNPROTECTED,
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,
tokenLevel);
ret = ret && (sandbox::SBOX_ALL_OK == result);
sandbox::MitigationFlags mitigations =
sandbox::MITIGATION_BOTTOM_UP_ASLR |
sandbox::MITIGATION_HEAP_TERMINATE |
sandbox::MITIGATION_SEHOP |
sandbox::MITIGATION_DEP_NO_ATL_THUNK |
sandbox::MITIGATION_DEP;
result = mPolicy->SetProcessMitigations(mitigations);
ret = ret && (sandbox::SBOX_ALL_OK == result);
mitigations =
sandbox::MITIGATION_STRICT_HANDLE_CHECKS;
result = mPolicy->SetDelayedProcessMitigations(mitigations);
ret = ret && (sandbox::SBOX_ALL_OK == result);
// The following is required for the Java plugin.
result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
sandbox::TargetPolicy::FILES_ALLOW_ANY,
L"\\??\\pipe\\jpi2_pid*_pipe*");
ret = ret && (sandbox::SBOX_ALL_OK == result);
sandbox::JobLevel jobLevel;
sandbox::TokenLevel accessTokenLevel;
sandbox::IntegrityLevel initialIntegrityLevel;
sandbox::IntegrityLevel delayedIntegrityLevel;
if (aSandboxLevel > 2) {
jobLevel = sandbox::JOB_UNPROTECTED;
accessTokenLevel = sandbox::USER_LIMITED;
initialIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
delayedIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
} else if (aSandboxLevel == 2) {
jobLevel = sandbox::JOB_UNPROTECTED;
accessTokenLevel = sandbox::USER_INTERACTIVE;
initialIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
delayedIntegrityLevel = sandbox::INTEGRITY_LEVEL_LOW;
} else {
result = mPolicy->SetJobLevel(sandbox::JOB_NONE,
0 /* ui_exceptions */);
ret = (sandbox::SBOX_ALL_OK == result);
result = mPolicy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
sandbox::USER_NON_ADMIN);
ret = ret && (sandbox::SBOX_ALL_OK == result);
jobLevel = sandbox::JOB_NONE;
accessTokenLevel = sandbox::USER_NON_ADMIN;
initialIntegrityLevel = sandbox::INTEGRITY_LEVEL_MEDIUM;
delayedIntegrityLevel = sandbox::INTEGRITY_LEVEL_MEDIUM;
}
result = mPolicy->SetDelayedIntegrityLevel(sandbox::INTEGRITY_LEVEL_MEDIUM);
sandbox::ResultCode result = mPolicy->SetJobLevel(jobLevel,
0 /* ui_exceptions */);
bool ret = (sandbox::SBOX_ALL_OK == result);
result = mPolicy->SetTokenLevel(sandbox::USER_RESTRICTED_SAME_ACCESS,
accessTokenLevel);
ret = ret && (sandbox::SBOX_ALL_OK == result);
result = mPolicy->SetIntegrityLevel(initialIntegrityLevel);
ret = ret && (sandbox::SBOX_ALL_OK == result);
result = mPolicy->SetDelayedIntegrityLevel(delayedIntegrityLevel);
ret = ret && (sandbox::SBOX_ALL_OK == result);
sandbox::MitigationFlags mitigations =
sandbox::MITIGATION_BOTTOM_UP_ASLR |
sandbox::MITIGATION_HEAP_TERMINATE |
sandbox::MITIGATION_SEHOP |
sandbox::MITIGATION_DEP_NO_ATL_THUNK |
sandbox::MITIGATION_DEP;
result = mPolicy->SetProcessMitigations(mitigations);
ret = ret && (sandbox::SBOX_ALL_OK == result);
mitigations =
sandbox::MITIGATION_STRICT_HANDLE_CHECKS;
result = mPolicy->SetDelayedProcessMitigations(mitigations);
ret = ret && (sandbox::SBOX_ALL_OK == result);
// Add the policy for the client side of a pipe. It is just a file
@ -224,12 +222,24 @@ SandboxBroker::SetSecurityLevelForPluginProcess(int32_t aSandboxLevel)
ret = ret && (sandbox::SBOX_ALL_OK == result);
// The NPAPI process needs to be able to duplicate shared memory to the
// content process, which are Section type handles.
// content process and broker process, which are Section type handles.
// Content and broker are for e10s and non-e10s cases.
result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
sandbox::TargetPolicy::HANDLES_DUP_ANY,
L"Section");
ret = ret && (sandbox::SBOX_ALL_OK == result);
result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_HANDLES,
sandbox::TargetPolicy::HANDLES_DUP_BROKER,
L"Section");
ret = ret && (sandbox::SBOX_ALL_OK == result);
// The following is required for the Java plugin.
result = mPolicy->AddRule(sandbox::TargetPolicy::SUBSYS_FILES,
sandbox::TargetPolicy::FILES_ALLOW_ANY,
L"\\??\\pipe\\jpi2_pid*_pipe*");
ret = ret && (sandbox::SBOX_ALL_OK == result);
return ret;
}