Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1598)

Unified Diff: sandbox/win/src/process_mitigations_test.cc

Issue 1626623003: [Win10 sandbox mitigations] Four new Win10 mitigations added. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Code review changes, part 2. Created 4 years, 11 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: sandbox/win/src/process_mitigations_test.cc
diff --git a/sandbox/win/src/process_mitigations_test.cc b/sandbox/win/src/process_mitigations_test.cc
index 080d8eca3fcbd49752b9b3318e43527cc65e0add..c77453f823efc20e3c8fd7ad98f08c47917d7d44 100644
--- a/sandbox/win/src/process_mitigations_test.cc
+++ b/sandbox/win/src/process_mitigations_test.cc
@@ -2,9 +2,9 @@
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
+#include "base/memory/scoped_ptr.h"
#include "base/strings/stringprintf.h"
#include "base/win/scoped_handle.h"
-
#include "base/win/windows_version.h"
#include "sandbox/win/src/nt_internals.h"
#include "sandbox/win/src/process_mitigations.h"
@@ -28,6 +28,14 @@ typedef BOOL (WINAPI *GetProcessMitigationPolicyFunction)(
PVOID buffer,
SIZE_T length);
+typedef HANDLE(WINAPI* AddFontMemResourceExFunction)(
+ PVOID font_resource,
+ DWORD font_resource_size,
+ PVOID reserved,
+ DWORD* num_fonts_installed);
+
+typedef BOOL(WINAPI* RemoveFontMemResourceExFunction)(HANDLE resource_handle);
Will Harris 2016/01/27 02:04:27 no real need for these here with c++11 syntactic m
penny 2016/01/28 19:25:15 Done.
+
GetProcessMitigationPolicyFunction get_process_mitigation_policy;
#if !defined(_WIN64)
@@ -83,10 +91,204 @@ bool CheckWin8DllExtensionPolicy() {
return policy.DisableExtensionPoints;
}
+bool CheckWin10FontPolicy() {
+ PROCESS_MITIGATION_FONT_DISABLE_POLICY policy = {};
+ if (!get_process_mitigation_policy(::GetCurrentProcess(),
+ ProcessFontDisablePolicy, &policy,
+ sizeof(policy))) {
+ return false;
+ }
+ return policy.DisableNonSystemFonts;
+}
+
+bool LoadFileToMemory(const std::wstring& file_name, std::vector<char>& data) {
Will Harris 2016/01/27 02:04:27 it seems base::File::Read() does a lot of what thi
penny 2016/01/28 19:25:15 Done. I'm using base::File now.
+ base::win::ScopedHandle file(::CreateFile(file_name.c_str(), GENERIC_READ,
+ FILE_SHARE_READ, NULL,
+ OPEN_EXISTING, 0, NULL));
+ if (!file.IsValid())
+ return false;
+
+ DWORD total_length = ::GetFileSize(file.Get(), NULL);
+
+ if (total_length == INVALID_FILE_SIZE)
+ return false;
+
+ data.resize(total_length);
+
+ DWORD current_pos = 0;
+ while (current_pos < total_length) {
+ DWORD bytes_read;
+
+ if (!ReadFile(file.Get(), &data[current_pos], total_length - current_pos,
+ &bytes_read, NULL) ||
+ bytes_read == 0)
+ return false;
+ current_pos += bytes_read;
+ }
+
+ return true;
+}
+
+bool CheckWin10ImageLoadNoRemotePolicy() {
+ PROCESS_MITIGATION_IMAGE_LOAD_POLICY policy = {};
+ if (!get_process_mitigation_policy(::GetCurrentProcess(),
+ ProcessImageLoadPolicy, &policy,
+ sizeof(policy))) {
+ return false;
+ }
+ return policy.NoRemoteImages;
+}
+
+void TestWin10ImageLoadRemote(bool is_success_test) {
+ // ***Insert your manual testing share UNC path here!
+ // E.g.: \\\\hostname\\sharename\\calc.exe
+ std::wstring unc = L"\\\\hostname\\sharename\\calc.exe";
+
+ sandbox::TestRunner runner;
+ sandbox::TargetPolicy* policy = runner.GetPolicy();
+
+ // Set a policy that would normally allow for process creation.
+ policy->SetJobLevel(sandbox::JOB_NONE, 0);
+ policy->SetTokenLevel(sandbox::USER_UNPROTECTED, sandbox::USER_UNPROTECTED);
+ runner.SetDisableCsrss(false);
+
+ if (!is_success_test) {
+ // Enable the NoRemote mitigation.
+ EXPECT_EQ(policy->SetDelayedProcessMitigations(
+ sandbox::MITIGATION_IMAGE_LOAD_NO_REMOTE),
+ sandbox::SBOX_ALL_OK);
+ }
+
+ std::wstring test = L"TestChildProcess ";
+ test += unc.c_str();
+ test += ((is_success_test) ? L" success" : L" failure");
+ EXPECT_EQ(sandbox::SBOX_TEST_SUCCEEDED, runner.RunTest(test.c_str()));
+}
+
+bool CheckWin10ImageLoadNoLowLabelPolicy() {
+ PROCESS_MITIGATION_IMAGE_LOAD_POLICY policy = {};
+ if (!get_process_mitigation_policy(::GetCurrentProcess(),
+ ProcessImageLoadPolicy, &policy,
+ sizeof(policy))) {
+ return false;
+ }
+ return policy.NoLowMandatoryLabelImages;
+}
+
+void TestWin10ImageLoadLowLabel(bool is_success_test) {
Will Harris 2016/01/27 02:04:26 this is a cool test.
+ // Setup a mandatory low executable for this test (calc.exe).
+ WCHAR dir_buffer[MAX_PATH];
+ EXPECT_TRUE(::GetWindowsDirectory(dir_buffer, MAX_PATH));
Will Harris 2016/01/27 02:04:27 you could use base::PathService::Get(base::DIR_WIN
penny 2016/01/28 19:25:15 Done.
+
+ std::wstring orig_path = dir_buffer;
+ orig_path = orig_path + L"\\System32\\calc.exe";
+ std::wstring new_path = dir_buffer;
+ new_path = new_path + L"\\temp\\lowIL_calc.exe";
Will Harris 2016/01/27 02:04:27 can't use temp, as multiple tests might be running
penny 2016/01/28 19:25:15 Nice. ScopedTempDir is handy.
+
+ EXPECT_TRUE(::CopyFileW(orig_path.c_str(), new_path.c_str(), false));
Will Harris 2016/01/27 02:04:27 base::CopyFile and using base::FilePath instead of
penny 2016/01/28 19:25:16 Done.
+
+ std::wstring cmd = L"icacls \"";
+ cmd += new_path.c_str();
+ cmd += L"\" /setintegritylevel Low";
+ scoped_ptr<wchar_t, base::FreeDeleter> cmd_line(_wcsdup(cmd.c_str()));
+
+ STARTUPINFOW startup_info = {};
+ startup_info.cb = sizeof(startup_info);
+ PROCESS_INFORMATION proc_info = {};
+ bool setup_success = false;
+
+ if (::CreateProcessW(NULL, cmd_line.get(), NULL, NULL, false, 0, NULL, NULL,
Will Harris 2016/01/27 02:04:27 base::LaunchProcess() here might be easier.
penny 2016/01/28 19:25:16 Done. Took me quite a while to figure out how to
+ &startup_info, &proc_info)) {
+ if (WAIT_OBJECT_0 == ::WaitForSingleObject(proc_info.hProcess, 10 * 1000)) {
+ DWORD exit_code;
+ if (::GetExitCodeProcess(proc_info.hProcess, &exit_code) &&
+ exit_code == 0) {
+ // icacls was successful.
+ setup_success = true;
+ }
+ } else {
+ ::TerminateProcess(proc_info.hProcess, 0);
+ }
+ ::CloseHandle(proc_info.hProcess);
+ ::CloseHandle(proc_info.hThread);
+ }
+
+ if (setup_success) {
+ sandbox::TestRunner runner;
+ sandbox::TargetPolicy* policy = runner.GetPolicy();
+
+ // Set a policy that would normally allow for process creation.
+ policy->SetJobLevel(sandbox::JOB_NONE, 0);
+ policy->SetTokenLevel(sandbox::USER_UNPROTECTED, sandbox::USER_UNPROTECTED);
+ runner.SetDisableCsrss(false);
+
+ if (!is_success_test) {
+ // Enable the NoLowLabel mitigation.
+ EXPECT_EQ(policy->SetDelayedProcessMitigations(
+ sandbox::MITIGATION_IMAGE_LOAD_NO_LOW_LABEL),
+ sandbox::SBOX_ALL_OK);
+ }
+
+ std::wstring test = L"TestChildProcess ";
+ test += new_path.c_str();
+ test += ((is_success_test) ? L" success" : L" failure");
Will Harris 2016/01/27 02:04:26 nit: for all these success | failure tests can't y
penny 2016/01/28 19:25:15 Done.
+ EXPECT_EQ(sandbox::SBOX_TEST_SUCCEEDED, runner.RunTest(test.c_str()));
+ } else {
+ // If setup failed, make sure to fail the test.
+ EXPECT_TRUE(setup_success);
+ }
+
+ // Clean up.
+ EXPECT_TRUE(::DeleteFileW(new_path.c_str()));
+}
+
} // namespace
namespace sandbox {
+// A shared helper test command that will attempt to CreateProcess
+// with a given command line and an expected result.
+//
+// ***Make sure you've enabled basic process creation in the
+// test sandbox settings via:
+// sandbox::TargetPolicy::SetJobLevel(),
+// sandbox::TargetPolicy::SetTokenLevel(),
+// and TestRunner::SetDisableCsrss().
+SBOX_TESTS_COMMAND int TestChildProcess(int argc, wchar_t** argv) {
+ if (argc < 2)
+ return SBOX_TEST_INVALID_PARAMETER;
+
+ // Initialize the startup information from the policy.
+ STARTUPINFOW startup_info = {};
+ startup_info.cb = sizeof(startup_info);
+ PROCESS_INFORMATION proc_info = {};
+ std::wstring path = argv[0];
+ std::wstring outcome = argv[1];
+ bool success_expected = (0 == outcome.compare(L"success")) ? true : false;
+
+ scoped_ptr<wchar_t, base::FreeDeleter> cmd_line(_wcsdup(path.c_str()));
+ if (::CreateProcessW(NULL, cmd_line.get(), NULL, NULL, false, 0, NULL, NULL,
Will Harris 2016/01/27 02:04:27 base::LaunchProcess maybe? unless you want to lau
penny 2016/01/28 19:25:15 Done. Popping calc is the most thrilling part of
+ &startup_info, &proc_info)) {
+ ::TerminateProcess(proc_info.hProcess, 0);
+ ::CloseHandle(proc_info.hProcess);
+ ::CloseHandle(proc_info.hThread);
+
+ return (success_expected) ? SBOX_TEST_SUCCEEDED : SBOX_TEST_FIRST_ERROR;
+ } else {
+ // Note: GetLastError returns 5, "ERROR_ACCESS_DENIED".
+ return (success_expected) ? SBOX_TEST_FIRST_ERROR : SBOX_TEST_SUCCEEDED;
+ }
+}
+
+/*****************************************************************************/
Will Harris 2016/01/27 02:04:26 This comment style is not chromium, and also below
penny 2016/01/28 19:25:15 Soooo, how does one create a visual horizontal sep
Will Harris 2016/01/30 00:28:43 okay - //-- seems to have precedent with other fil
penny 2016/02/01 20:43:21 Done! I appreciate you noticing that I'm missing
+// Win8 Checks
+// MITIGATION_DEP(_NO_ATL_THUNK)
+// MITIGATION_EXTENSION_DLL_DISABLE
+// MITIGATION_RELOCATE_IMAGE(_REQUIRED) - ASLR, release only
+// MITIGATION_STRICT_HANDLE_CHECKS
+// >= Win8
+/*****************************************************************************/
+
SBOX_TESTS_COMMAND int CheckWin8(int argc, wchar_t **argv) {
get_process_mitigation_policy =
reinterpret_cast<GetProcessMitigationPolicyFunction>(
@@ -138,6 +340,10 @@ TEST(ProcessMitigationsTest, CheckWin8) {
EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8"));
}
+/*****************************************************************************/
+// DEP (MITIGATION_DEP)
+// < Win8 x86
+/*****************************************************************************/
SBOX_TESTS_COMMAND int CheckDep(int argc, wchar_t **argv) {
GetProcessDEPPolicyFunction get_process_dep_policy =
@@ -201,6 +407,11 @@ TEST(ProcessMitigationsTest, CheckDep) {
}
#endif
+/*****************************************************************************/
+// Win32k Lockdown (MITIGATION_WIN32K_DISABLE)
+// >= Win8
+/*****************************************************************************/
+
SBOX_TESTS_COMMAND int CheckWin8Lockdown(int argc, wchar_t **argv) {
get_process_mitigation_policy =
reinterpret_cast<GetProcessMitigationPolicyFunction>(
@@ -248,5 +459,291 @@ TEST(ProcessMitigationsTest, CheckWin8Win32KLockDownSuccess) {
EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin8Lockdown"));
}
+/*****************************************************************************/
+// Disable non-system font loads (MITIGATION_NONSYSTEM_FONT_DISABLE)
+// >= Win10
+/*****************************************************************************/
+
+SBOX_TESTS_COMMAND int CheckWin10FontLockDown(int argc, wchar_t** argv) {
+ get_process_mitigation_policy =
+ reinterpret_cast<GetProcessMitigationPolicyFunction>(::GetProcAddress(
+ ::GetModuleHandleW(L"kernel32.dll"), "GetProcessMitigationPolicy"));
+ if (!get_process_mitigation_policy)
+ return SBOX_TEST_NOT_FOUND;
+
+ if (!CheckWin10FontPolicy())
+ return SBOX_TEST_FIRST_ERROR;
+ return SBOX_TEST_SUCCEEDED;
+}
+
+SBOX_TESTS_COMMAND int CheckWin10FontLoad(int argc, wchar_t** argv) {
+ if (argc < 2)
+ return SBOX_TEST_INVALID_PARAMETER;
+
+ std::wstring outcome = argv[1];
+ bool success_expected = (0 == outcome.compare(L"success")) ? true : false;
+
+ HMODULE gdi_module = ::LoadLibraryW(L"gdi32.dll");
+ if (!gdi_module)
+ return SBOX_TEST_NOT_FOUND;
+
+ AddFontMemResourceExFunction add_font_mem_resource =
+ reinterpret_cast<AddFontMemResourceExFunction>(
+ ::GetProcAddress(gdi_module, "AddFontMemResourceEx"));
+
+ RemoveFontMemResourceExFunction rem_font_mem_resource =
+ reinterpret_cast<RemoveFontMemResourceExFunction>(
+ ::GetProcAddress(gdi_module, "RemoveFontMemResourceEx"));
+
+ if (!add_font_mem_resource || !rem_font_mem_resource)
+ return SBOX_TEST_NOT_FOUND;
+
+ // Load font file passed in as an argument.
+ std::vector<char> font_data;
+ if (!LoadFileToMemory(argv[0], font_data))
+ return SBOX_TEST_NOT_FOUND;
+
+ DWORD font_count = 0;
+ HANDLE font_handle = add_font_mem_resource(
+ &font_data[0], static_cast<DWORD>(font_data.size()), NULL, &font_count);
+
+ if (font_handle) {
+ rem_font_mem_resource(font_handle);
+ return (success_expected) ? SBOX_TEST_SUCCEEDED : SBOX_TEST_FIRST_ERROR;
+ } else {
+ // Note: GetLastError returns 5, "ERROR_ACCESS_DENIED".
+ return (success_expected) ? SBOX_TEST_FIRST_ERROR : SBOX_TEST_SUCCEEDED;
+ }
+
+ return SBOX_TEST_SUCCEEDED;
+}
+
+// This test validates that setting the MITIGATION_NON_SYSTEM_FONTS_DISABLE
+// mitigation enables the setting on a process.
+TEST(ProcessMitigationsTest, CheckWin10NonSystemFontLockDownPolicySuccess) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN10)
+ return;
+
+ TestRunner runner;
+ sandbox::TargetPolicy* policy = runner.GetPolicy();
+
+ EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_NONSYSTEM_FONT_DISABLE),
+ SBOX_ALL_OK);
+ EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckWin10FontLockDown"));
+}
+
+// This test validates that we can load a non-system font
+// if the MITIGATION_NON_SYSTEM_FONTS_DISABLE
+// mitigation is NOT set.
+TEST(ProcessMitigationsTest, CheckWin10NonSystemFontLockDownLoadSuccess) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN10)
+ return;
+
+ TestRunner runner;
+
+ WCHAR dir_buffer[MAX_PATH];
+ EXPECT_TRUE(::GetWindowsDirectory(dir_buffer, MAX_PATH));
+ std::wstring font_name = dir_buffer;
+ // Arial font should always be available
+ font_name = font_name + L"\\fonts\\arial.ttf";
+
+ EXPECT_TRUE(
+ runner.AddFsRule(TargetPolicy::FILES_ALLOW_READONLY, font_name.c_str()));
+
+ std::wstring test_command =
+ L"CheckWin10FontLoad \"" + font_name + L"\" success";
+
+ EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
+}
+
+// This test validates that setting the MITIGATION_NON_SYSTEM_FONTS_DISABLE
+// mitigation prevents the loading of a non-system font.
+TEST(ProcessMitigationsTest, CheckWin10NonSystemFontLockDownLoadFailure) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN10)
+ return;
+
+ TestRunner runner;
+ sandbox::TargetPolicy* policy = runner.GetPolicy();
+
+ WCHAR dir_buffer[MAX_PATH];
+ EXPECT_TRUE(::GetWindowsDirectory(dir_buffer, MAX_PATH));
+ std::wstring font_name = dir_buffer;
+ // Arial font should always be available
+ font_name = font_name + L"\\fonts\\arial.ttf";
+
+ // Turn on the non-system font disable mitigation.
+ EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_NONSYSTEM_FONT_DISABLE),
+ SBOX_ALL_OK);
+ EXPECT_TRUE(
+ runner.AddFsRule(TargetPolicy::FILES_ALLOW_READONLY, font_name.c_str()));
+
+ std::wstring test_command =
+ L"CheckWin10FontLoad \"" + font_name + L"\" failure";
+
+ EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
+}
+
+/*****************************************************************************/
+// Disable image load from remote devices (MITIGATION_IMAGE_LOAD_NO_REMOTE).
+// >= Win10_TH2
+/*****************************************************************************/
+
+SBOX_TESTS_COMMAND int CheckWin10ImageLoadNoRemote(int argc, wchar_t** argv) {
+ get_process_mitigation_policy =
+ reinterpret_cast<GetProcessMitigationPolicyFunction>(::GetProcAddress(
+ ::GetModuleHandleW(L"kernel32.dll"), "GetProcessMitigationPolicy"));
+ if (!get_process_mitigation_policy)
+ return SBOX_TEST_NOT_FOUND;
+
+ if (!CheckWin10ImageLoadNoRemotePolicy())
+ return SBOX_TEST_FIRST_ERROR;
+ return SBOX_TEST_SUCCEEDED;
+}
+
+// This test validates that setting the MITIGATION_IMAGE_LOAD_NO_REMOTE
+// mitigation enables the setting on a process.
+TEST(ProcessMitigationsTest, CheckWin10ImageLoadNoRemotePolicySuccess) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN10_TH2)
+ return;
+
+ TestRunner runner;
+ sandbox::TargetPolicy* policy = runner.GetPolicy();
+
+ EXPECT_EQ(
+ policy->SetDelayedProcessMitigations(MITIGATION_IMAGE_LOAD_NO_REMOTE),
+ SBOX_ALL_OK);
+ EXPECT_EQ(SBOX_TEST_SUCCEEDED,
+ runner.RunTest(L"CheckWin10ImageLoadNoRemote"));
+}
+
+// This test validates that we CAN create a new process from
+// a remote UNC device, if the MITIGATION_IMAGE_LOAD_NO_REMOTE
+// mitigation is NOT set.
+//
+// DISABLED for automated testing bots. Enable for manual testing.
+TEST(ProcessMitigationsTest, DISABLED_CheckWin10ImageLoadNoRemoteSuccess) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN10_TH2)
+ return;
+
+ TestWin10ImageLoadRemote(true);
+}
+
+// This test validates that setting the MITIGATION_IMAGE_LOAD_NO_REMOTE
+// mitigation prevents creating a new process from a remote
+// UNC device.
+//
+// DISABLED for automated testing bots. Enable for manual testing.
+TEST(ProcessMitigationsTest, DISABLED_CheckWin10ImageLoadNoRemoteFailure) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN10_TH2)
+ return;
+
+ TestWin10ImageLoadRemote(false);
+}
+
+/*****************************************************************************/
+// Disable image load when "mandatory low label" (integrity level).
+// (MITIGATION_IMAGE_LOAD_NO_LOW_LABEL)
+// >= Win10_TH2
+/*****************************************************************************/
+
+SBOX_TESTS_COMMAND int CheckWin10ImageLoadNoLowLabel(int argc, wchar_t** argv) {
+ get_process_mitigation_policy =
+ reinterpret_cast<GetProcessMitigationPolicyFunction>(::GetProcAddress(
+ ::GetModuleHandleW(L"kernel32.dll"), "GetProcessMitigationPolicy"));
+ if (!get_process_mitigation_policy)
+ return SBOX_TEST_NOT_FOUND;
+
+ if (!CheckWin10ImageLoadNoLowLabelPolicy())
+ return SBOX_TEST_FIRST_ERROR;
+ return SBOX_TEST_SUCCEEDED;
+}
+
+// This test validates that setting the MITIGATION_IMAGE_LOAD_NO_LOW_LABEL
+// mitigation enables the setting on a process.
+TEST(ProcessMitigationsTest, CheckWin10ImageLoadNoLowLabelPolicySuccess) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN10_TH2)
+ return;
+
+ TestRunner runner;
+ sandbox::TargetPolicy* policy = runner.GetPolicy();
+
+ EXPECT_EQ(
+ policy->SetDelayedProcessMitigations(MITIGATION_IMAGE_LOAD_NO_LOW_LABEL),
+ SBOX_ALL_OK);
+ EXPECT_EQ(SBOX_TEST_SUCCEEDED,
+ runner.RunTest(L"CheckWin10ImageLoadNoLowLabel"));
+}
+
+// This test validates that we CAN create a new process with
+// low mandatory label (IL), if the MITIGATION_IMAGE_LOAD_NO_LOW_LABEL
+// mitigation is NOT set.
+TEST(ProcessMitigationsTest, CheckWin10ImageLoadNoLowLabelSuccess) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN10_TH2)
+ return;
+
+ TestWin10ImageLoadLowLabel(true);
+}
+
+// This test validates that setting the MITIGATION_IMAGE_LOAD_NO_LOW_LABEL
+// mitigation prevents creating a new process with low mandatory label (IL).
+TEST(ProcessMitigationsTest, CheckWin10ImageLoadNoLowLabelFailure) {
+ if (base::win::GetVersion() < base::win::VERSION_WIN10_TH2)
+ return;
+
+ TestWin10ImageLoadLowLabel(false);
+}
+
+/*****************************************************************************/
+// Disable child process creation.
+// - JobLevel <= JOB_LIMITED_USER (on < WIN10_TH2).
+// - JobLevel <= JOB_LIMITED_USER which also triggers setting
+// PROC_THREAD_ATTRIBUTE_CHILD_PROCESS_POLICY to
+// PROCESS_CREATION_CHILD_PROCESS_RESTRICTED in
+// BrokerServicesBase::SpawnTarget (on >= WIN10_TH2).
+/*****************************************************************************/
+
+// This test validates that we can spawn a child process if
+// MITIGATION_CHILD_PROCESS_CREATION_RESTRICTED mitigation is
+// not set.
+TEST(ProcessMitigationsTest, CheckChildProcessSuccess) {
+ TestRunner runner;
+ sandbox::TargetPolicy* policy = runner.GetPolicy();
+
+ // Set a policy that would normally allow for process creation.
+ policy->SetJobLevel(JOB_INTERACTIVE, 0);
+ policy->SetTokenLevel(USER_UNPROTECTED, USER_UNPROTECTED);
+ runner.SetDisableCsrss(false);
+
+ std::wstring test_command = L"TestChildProcess ";
+ WCHAR dir_buffer[MAX_PATH];
+ EXPECT_TRUE(::GetWindowsDirectory(dir_buffer, MAX_PATH));
+ test_command += dir_buffer;
+ test_command += L"\\System32\\calc.exe success";
+
+ EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
+}
+
+// This test validates that setting the
+// MITIGATION_CHILD_PROCESS_CREATION_RESTRICTED mitigation prevents
+// the spawning of child processes.
+TEST(ProcessMitigationsTest, CheckChildProcessFailure) {
+ TestRunner runner;
+ sandbox::TargetPolicy* policy = runner.GetPolicy();
+
+ // Now set the job level to be <= JOB_LIMITED_USER
+ // and ensure we can no longer create a child process.
+ policy->SetJobLevel(JOB_LIMITED_USER, 0);
+ policy->SetTokenLevel(USER_UNPROTECTED, USER_UNPROTECTED);
+ runner.SetDisableCsrss(false);
+
+ std::wstring test_command = L"TestChildProcess ";
+ WCHAR dir_buffer[MAX_PATH];
+ EXPECT_TRUE(::GetWindowsDirectory(dir_buffer, MAX_PATH));
+ test_command += dir_buffer;
+ test_command += L"\\System32\\calc.exe failure";
+
+ EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
+}
+
} // namespace sandbox

Powered by Google App Engine
This is Rietveld 408576698