process_mitigations_unittest.cc 52 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387
  1. // Copyright 2011 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "sandbox/win/src/process_mitigations.h"
  5. #include <ktmw32.h>
  6. #include <windows.h>
  7. #include "base/files/file_util.h"
  8. #include "base/numerics/safe_conversions.h"
  9. #include "base/path_service.h"
  10. #include "base/process/kill.h"
  11. #include "base/scoped_native_library.h"
  12. #include "base/test/test_timeouts.h"
  13. #include "base/win/scoped_handle.h"
  14. #include "base/win/windows_version.h"
  15. #include "sandbox/win/src/nt_internals.h"
  16. #include "sandbox/win/src/sandbox_nt_util.h"
  17. #include "sandbox/win/src/target_services.h"
  18. #include "sandbox/win/tests/common/controller.h"
  19. #include "sandbox/win/tests/integration_tests/hooking_dll.h"
  20. #include "sandbox/win/tests/integration_tests/integration_tests_common.h"
  21. #include "testing/gtest/include/gtest/gtest.h"
  22. // PROCESS_MITIGATION_USER_SHADOW_STACK_POLICY.EnableUserShadowStackStrictMode
  23. // is only defined starting 10.0.20226.0.
  24. #define CET_STRICT_MODE_MASK (1 << 4)
  25. // PROCESS_MITIGATION_USER_SHADOW_STACK_POLICY.CetDynamicApisOutOfProcOnly is
  26. // only defined starting 10.0.20226.0.
  27. #define CET_DYNAMIC_APIS_OUT_OF_PROC_ONLY_MASK (1 << 8)
  28. namespace {
  29. //------------------------------------------------------------------------------
  30. // Internal Defines & Functions
  31. //------------------------------------------------------------------------------
  32. // API defined in winbase.h.
  33. using GetProcessDEPPolicyFunction = decltype(&GetProcessDEPPolicy);
  34. // API defined in processthreadsapi.h.
  35. using GetProcessMitigationPolicyFunction =
  36. decltype(&GetProcessMitigationPolicy);
  37. GetProcessMitigationPolicyFunction get_process_mitigation_policy;
  38. // APIs defined in wingdi.h.
  39. using AddFontMemResourceExFunction = decltype(&AddFontMemResourceEx);
  40. using RemoveFontMemResourceExFunction = decltype(&RemoveFontMemResourceEx);
  41. //------------------------------------------------------------------------------
  42. // NonSystemFont test helper function.
  43. //
  44. // 1. Pick font file and set up sandbox to allow read access to it.
  45. // 2. Trigger test child process (with or without mitigation enabled).
  46. //------------------------------------------------------------------------------
  47. void TestWin10NonSystemFont(bool is_success_test) {
  48. base::FilePath font_path;
  49. EXPECT_TRUE(base::PathService::Get(base::DIR_WINDOWS_FONTS, &font_path));
  50. // Arial font should always be available
  51. font_path = font_path.Append(L"arial.ttf");
  52. sandbox::TestRunner runner;
  53. EXPECT_TRUE(runner.AddFsRule(sandbox::Semantics::kFilesAllowReadonly,
  54. font_path.value().c_str()));
  55. if (!is_success_test) {
  56. sandbox::TargetPolicy* policy = runner.GetPolicy();
  57. // Turn on the non-system font disable mitigation.
  58. EXPECT_EQ(policy->SetProcessMitigations(
  59. sandbox::MITIGATION_NONSYSTEM_FONT_DISABLE),
  60. sandbox::SBOX_ALL_OK);
  61. }
  62. std::wstring test_command = L"CheckWin10FontLoad \"";
  63. test_command += font_path.value().c_str();
  64. test_command += L"\"";
  65. EXPECT_EQ((is_success_test ? sandbox::SBOX_TEST_SUCCEEDED
  66. : sandbox::SBOX_TEST_FAILED),
  67. runner.RunTest(test_command.c_str()));
  68. }
  69. //------------------------------------------------------------------------------
  70. // ForceMsSigned test helper function.
  71. // - LoadLibrary fails with ERROR_INVALID_IMAGE_HASH if this mitigation is
  72. // enabled and the target is not appropriately signed.
  73. // - Acquire the global g_hooking_dll_mutex mutex before calling
  74. // (as we meddle with a shared system resource).
  75. // - Note: Do not use ASSERTs in this function, as a global mutex is held.
  76. //
  77. // Trigger test child process (with or without mitigation enabled).
  78. //------------------------------------------------------------------------------
  79. void TestWin10MsSigned(int expected,
  80. bool enable_mitigation,
  81. bool delayed,
  82. bool use_ms_signed_binary,
  83. bool add_dll_permission,
  84. bool add_directory_permission) {
  85. sandbox::TestRunner runner;
  86. sandbox::TargetPolicy* policy = runner.GetPolicy();
  87. if (enable_mitigation) {
  88. // Enable the ForceMsSigned mitigation.
  89. if (delayed) {
  90. EXPECT_EQ(policy->SetDelayedProcessMitigations(
  91. sandbox::MITIGATION_FORCE_MS_SIGNED_BINS),
  92. sandbox::SBOX_ALL_OK);
  93. } else {
  94. EXPECT_EQ(policy->SetProcessMitigations(
  95. sandbox::MITIGATION_FORCE_MS_SIGNED_BINS),
  96. sandbox::SBOX_ALL_OK);
  97. }
  98. }
  99. // Choose the appropriate DLL and make sure the sandbox allows access to it.
  100. base::FilePath dll_path;
  101. if (use_ms_signed_binary) {
  102. EXPECT_TRUE(base::PathService::Get(base::DIR_SYSTEM, &dll_path));
  103. dll_path = dll_path.Append(L"gdi32.dll");
  104. } else {
  105. EXPECT_TRUE(base::PathService::Get(base::DIR_EXE, &dll_path));
  106. dll_path = dll_path.Append(hooking_dll::g_hook_dll_file);
  107. if (add_dll_permission) {
  108. EXPECT_EQ(sandbox::SBOX_ALL_OK, policy->GetConfig()->AddRule(
  109. sandbox::SubSystem::kSignedBinary,
  110. sandbox::Semantics::kSignedAllowLoad,
  111. dll_path.value().c_str()));
  112. }
  113. if (add_directory_permission) {
  114. base::FilePath exe_path;
  115. EXPECT_TRUE(base::PathService::Get(base::DIR_EXE, &exe_path));
  116. EXPECT_EQ(sandbox::SBOX_ALL_OK,
  117. policy->GetConfig()->AddRule(
  118. sandbox::SubSystem::kSignedBinary,
  119. sandbox::Semantics::kSignedAllowLoad,
  120. exe_path.DirName().AppendASCII("*.dll").value().c_str()));
  121. }
  122. }
  123. EXPECT_TRUE(runner.AddFsRule(sandbox::Semantics::kFilesAllowReadonly,
  124. dll_path.value().c_str()));
  125. // Set up test string.
  126. std::wstring test = L"TestDllLoad \"";
  127. test += dll_path.value().c_str();
  128. test += L"\"";
  129. // Note: ERROR_INVALID_IMAGE_HASH is being displayed in a system pop-up when
  130. // the DLL load is attempted for delayed mitigations, but the value
  131. // returned from the test process itself is SBOX_TEST_FAILED.
  132. EXPECT_EQ(expected, runner.RunTest(test.c_str()));
  133. }
  134. } // namespace
  135. namespace sandbox {
  136. //------------------------------------------------------------------------------
  137. // Exported functions called by child test processes.
  138. //------------------------------------------------------------------------------
  139. //------------------------------------------------------------------------------
  140. // Common test function for checking that a policy was enabled.
  141. // - Use enum TestPolicy defined in integration_tests_common.h to specify which
  142. // policy to check - passed as arg1.
  143. //------------------------------------------------------------------------------
  144. SBOX_TESTS_COMMAND int CheckPolicy(int argc, wchar_t** argv) {
  145. if (argc < 1)
  146. return SBOX_TEST_INVALID_PARAMETER;
  147. int test = ::_wtoi(argv[0]);
  148. if (!test)
  149. return SBOX_TEST_INVALID_PARAMETER;
  150. get_process_mitigation_policy =
  151. reinterpret_cast<GetProcessMitigationPolicyFunction>(::GetProcAddress(
  152. ::GetModuleHandleW(L"kernel32.dll"), "GetProcessMitigationPolicy"));
  153. if (!get_process_mitigation_policy)
  154. return SBOX_TEST_NOT_FOUND;
  155. switch (test) {
  156. //--------------------------------------------------
  157. // MITIGATION_DEP
  158. // MITIGATION_DEP_NO_ATL_THUNK
  159. //--------------------------------------------------
  160. case (TESTPOLICY_DEP): {
  161. #if !defined(_WIN64)
  162. // DEP - always enabled on 64-bit.
  163. PROCESS_MITIGATION_DEP_POLICY policy = {};
  164. if (!get_process_mitigation_policy(::GetCurrentProcess(),
  165. ProcessDEPPolicy, &policy,
  166. sizeof(policy))) {
  167. return SBOX_TEST_NOT_FOUND;
  168. }
  169. if (!policy.Enable || !policy.Permanent)
  170. return SBOX_TEST_FAILED;
  171. #endif // !defined(_WIN64)
  172. break;
  173. }
  174. //--------------------------------------------------
  175. // MITIGATION_RELOCATE_IMAGE
  176. // MITIGATION_RELOCATE_IMAGE_REQUIRED
  177. //--------------------------------------------------
  178. case (TESTPOLICY_ASLR): {
  179. PROCESS_MITIGATION_ASLR_POLICY policy = {};
  180. if (!get_process_mitigation_policy(::GetCurrentProcess(),
  181. ProcessASLRPolicy, &policy,
  182. sizeof(policy))) {
  183. return SBOX_TEST_NOT_FOUND;
  184. }
  185. if (!policy.EnableForceRelocateImages || !policy.DisallowStrippedImages)
  186. return SBOX_TEST_FAILED;
  187. break;
  188. }
  189. //--------------------------------------------------
  190. // MITIGATION_STRICT_HANDLE_CHECKS
  191. //--------------------------------------------------
  192. case (TESTPOLICY_STRICTHANDLE): {
  193. PROCESS_MITIGATION_STRICT_HANDLE_CHECK_POLICY policy = {};
  194. if (!get_process_mitigation_policy(::GetCurrentProcess(),
  195. ProcessStrictHandleCheckPolicy,
  196. &policy, sizeof(policy))) {
  197. return SBOX_TEST_NOT_FOUND;
  198. }
  199. if (!policy.RaiseExceptionOnInvalidHandleReference ||
  200. !policy.HandleExceptionsPermanentlyEnabled) {
  201. return SBOX_TEST_FAILED;
  202. }
  203. break;
  204. }
  205. //--------------------------------------------------
  206. // MITIGATION_WIN32K_DISABLE
  207. //--------------------------------------------------
  208. case (TESTPOLICY_WIN32K): {
  209. PROCESS_MITIGATION_SYSTEM_CALL_DISABLE_POLICY policy = {};
  210. if (!get_process_mitigation_policy(::GetCurrentProcess(),
  211. ProcessSystemCallDisablePolicy,
  212. &policy, sizeof(policy))) {
  213. return SBOX_TEST_NOT_FOUND;
  214. }
  215. if (!policy.DisallowWin32kSystemCalls)
  216. return SBOX_TEST_FIRST_ERROR;
  217. // Check if we can call a Win32k API. Fail if it succeeds.
  218. if (::GetDC(nullptr))
  219. return SBOX_TEST_SECOND_ERROR;
  220. break;
  221. }
  222. //--------------------------------------------------
  223. // MITIGATION_EXTENSION_POINT_DISABLE
  224. //--------------------------------------------------
  225. case (TESTPOLICY_EXTENSIONPOINT): {
  226. PROCESS_MITIGATION_EXTENSION_POINT_DISABLE_POLICY policy = {};
  227. if (!get_process_mitigation_policy(::GetCurrentProcess(),
  228. ProcessExtensionPointDisablePolicy,
  229. &policy, sizeof(policy))) {
  230. return SBOX_TEST_NOT_FOUND;
  231. }
  232. if (!policy.DisableExtensionPoints)
  233. return SBOX_TEST_FAILED;
  234. break;
  235. }
  236. //--------------------------------------------------
  237. // MITIGATION_DYNAMIC_CODE_DISABLE
  238. //--------------------------------------------------
  239. case (TESTPOLICY_DYNAMICCODE): {
  240. PROCESS_MITIGATION_DYNAMIC_CODE_POLICY policy = {};
  241. if (!get_process_mitigation_policy(::GetCurrentProcess(),
  242. ProcessDynamicCodePolicy, &policy,
  243. sizeof(policy))) {
  244. return SBOX_TEST_NOT_FOUND;
  245. }
  246. if (!policy.ProhibitDynamicCode)
  247. return SBOX_TEST_FAILED;
  248. break;
  249. }
  250. //--------------------------------------------------
  251. // MITIGATION_NONSYSTEM_FONT_DISABLE
  252. //--------------------------------------------------
  253. case (TESTPOLICY_NONSYSFONT): {
  254. PROCESS_MITIGATION_FONT_DISABLE_POLICY policy = {};
  255. if (!get_process_mitigation_policy(::GetCurrentProcess(),
  256. ProcessFontDisablePolicy, &policy,
  257. sizeof(policy))) {
  258. return SBOX_TEST_NOT_FOUND;
  259. }
  260. if (!policy.DisableNonSystemFonts)
  261. return SBOX_TEST_FAILED;
  262. break;
  263. }
  264. //--------------------------------------------------
  265. // MITIGATION_FORCE_MS_SIGNED_BINS
  266. //--------------------------------------------------
  267. case (TESTPOLICY_MSSIGNED): {
  268. PROCESS_MITIGATION_BINARY_SIGNATURE_POLICY policy = {};
  269. if (!get_process_mitigation_policy(::GetCurrentProcess(),
  270. ProcessSignaturePolicy, &policy,
  271. sizeof(policy))) {
  272. return SBOX_TEST_NOT_FOUND;
  273. }
  274. if (!policy.MicrosoftSignedOnly)
  275. return SBOX_TEST_FAILED;
  276. break;
  277. }
  278. //--------------------------------------------------
  279. // MITIGATION_IMAGE_LOAD_NO_REMOTE
  280. //--------------------------------------------------
  281. case (TESTPOLICY_LOADNOREMOTE): {
  282. PROCESS_MITIGATION_IMAGE_LOAD_POLICY policy = {};
  283. if (!get_process_mitigation_policy(::GetCurrentProcess(),
  284. ProcessImageLoadPolicy, &policy,
  285. sizeof(policy))) {
  286. return SBOX_TEST_NOT_FOUND;
  287. }
  288. if (!policy.NoRemoteImages)
  289. return SBOX_TEST_FAILED;
  290. break;
  291. }
  292. //--------------------------------------------------
  293. // MITIGATION_IMAGE_LOAD_NO_LOW_LABEL
  294. //--------------------------------------------------
  295. case (TESTPOLICY_LOADNOLOW): {
  296. PROCESS_MITIGATION_IMAGE_LOAD_POLICY policy = {};
  297. if (!get_process_mitigation_policy(::GetCurrentProcess(),
  298. ProcessImageLoadPolicy, &policy,
  299. sizeof(policy))) {
  300. return SBOX_TEST_NOT_FOUND;
  301. }
  302. if (!policy.NoLowMandatoryLabelImages)
  303. return SBOX_TEST_FAILED;
  304. break;
  305. }
  306. //--------------------------------------------------
  307. // MITIGATION_DYNAMIC_CODE_DISABLE_WITH_OPT_OUT
  308. //--------------------------------------------------
  309. case (TESTPOLICY_DYNAMICCODEOPTOUT): {
  310. PROCESS_MITIGATION_DYNAMIC_CODE_POLICY policy = {};
  311. if (!get_process_mitigation_policy(::GetCurrentProcess(),
  312. ProcessDynamicCodePolicy, &policy,
  313. sizeof(policy))) {
  314. return SBOX_TEST_NOT_FOUND;
  315. }
  316. if (!policy.ProhibitDynamicCode || !policy.AllowThreadOptOut)
  317. return SBOX_TEST_FAILED;
  318. break;
  319. }
  320. //--------------------------------------------------
  321. // MITIGATION_IMAGE_LOAD_PREFER_SYS32
  322. //--------------------------------------------------
  323. case (TESTPOLICY_LOADPREFERSYS32): {
  324. PROCESS_MITIGATION_IMAGE_LOAD_POLICY policy = {};
  325. if (!get_process_mitigation_policy(::GetCurrentProcess(),
  326. ProcessImageLoadPolicy, &policy,
  327. sizeof(policy))) {
  328. return SBOX_TEST_NOT_FOUND;
  329. }
  330. if (!policy.PreferSystem32Images)
  331. return SBOX_TEST_FAILED;
  332. break;
  333. }
  334. //--------------------------------------------------
  335. // MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION
  336. //--------------------------------------------------
  337. case (TESTPOLICY_RESTRICTINDIRECTBRANCHPREDICTION): {
  338. // TODO(pennymac): No Policy defines available yet!
  339. // Can't use GetProcessMitigationPolicy() API to check if enabled at this
  340. // time. If the creation of THIS process succeeded, then the call to
  341. // UpdateProcThreadAttribute() with this mitigation succeeded.
  342. break;
  343. }
  344. //--------------------------------------------------
  345. // MITIGATION_CET_DISABLED
  346. //--------------------------------------------------
  347. case (TESTPOLICY_CETDISABLED): {
  348. PROCESS_MITIGATION_USER_SHADOW_STACK_POLICY policy = {};
  349. if (!get_process_mitigation_policy(::GetCurrentProcess(),
  350. ProcessUserShadowStackPolicy, &policy,
  351. sizeof(policy))) {
  352. return SBOX_TEST_NOT_FOUND;
  353. }
  354. // We wish to disable the policy.
  355. if (policy.EnableUserShadowStack)
  356. return SBOX_TEST_FAILED;
  357. break;
  358. }
  359. //--------------------------------------------------
  360. // MITIGATION_CET_ALLOW_DYNAMIC_APIS
  361. //--------------------------------------------------
  362. case (TESTPOLICY_CETDYNAMICAPIS): {
  363. PROCESS_MITIGATION_USER_SHADOW_STACK_POLICY policy = {};
  364. if (!get_process_mitigation_policy(::GetCurrentProcess(),
  365. ProcessUserShadowStackPolicy, &policy,
  366. sizeof(policy))) {
  367. return SBOX_TEST_NOT_FOUND;
  368. }
  369. // CET should be enabled (we only run this test if CET is available).
  370. if (!policy.EnableUserShadowStack)
  371. return SBOX_TEST_FIRST_RESULT;
  372. // We wish to disable the setting.
  373. // (Once win sdk is updated to 10.0.20226.0
  374. // we can use CetDynamicApisOutOfProcOnly here.)
  375. if (policy.Flags & CET_DYNAMIC_APIS_OUT_OF_PROC_ONLY_MASK)
  376. return SBOX_TEST_FAILED;
  377. break;
  378. }
  379. //--------------------------------------------------
  380. // MITIGATION_CET_STRICT_MODE
  381. //--------------------------------------------------
  382. case (TESTPOLICY_CETSTRICT): {
  383. PROCESS_MITIGATION_USER_SHADOW_STACK_POLICY policy = {};
  384. if (!get_process_mitigation_policy(::GetCurrentProcess(),
  385. ProcessUserShadowStackPolicy, &policy,
  386. sizeof(policy))) {
  387. return SBOX_TEST_NOT_FOUND;
  388. }
  389. // CET should be enabled (we only run this test if CET is available).
  390. if (!policy.EnableUserShadowStack)
  391. return SBOX_TEST_FIRST_ERROR;
  392. // We wish to enable the setting.
  393. // (Once win sdk is updated to 10.0.20226.0 we can use
  394. // EnableUserShadowStackStrictMode here.)
  395. if (!(policy.Flags & CET_STRICT_MODE_MASK))
  396. return SBOX_TEST_FAILED;
  397. break;
  398. }
  399. //--------------------------------------------------
  400. // MITIGATION_KTM_COMPONENT_FILTER
  401. //--------------------------------------------------
  402. case (TESTPOLICY_KTMCOMPONENTFILTER): {
  403. // If the mitigation is enabled, creating a KTM should fail.
  404. SECURITY_ATTRIBUTES tm_attributes = {0};
  405. tm_attributes.nLength = sizeof(SECURITY_ATTRIBUTES);
  406. tm_attributes.lpSecurityDescriptor = nullptr;
  407. tm_attributes.bInheritHandle = false;
  408. base::win::ScopedHandle ktm;
  409. ktm.Set(CreateTransactionManager(&tm_attributes, nullptr,
  410. TRANSACTION_MANAGER_VOLATILE,
  411. TRANSACTION_MANAGER_COMMIT_DEFAULT));
  412. if (ktm.IsValid() || ::GetLastError() != ERROR_ACCESS_DENIED)
  413. return SBOX_TEST_FAILED;
  414. break;
  415. }
  416. default:
  417. return SBOX_TEST_INVALID_PARAMETER;
  418. }
  419. return SBOX_TEST_SUCCEEDED;
  420. }
  421. SBOX_TESTS_COMMAND int CheckDep(int argc, wchar_t** argv) {
  422. GetProcessDEPPolicyFunction get_process_dep_policy =
  423. reinterpret_cast<GetProcessDEPPolicyFunction>(::GetProcAddress(
  424. ::GetModuleHandleW(L"kernel32.dll"), "GetProcessDEPPolicy"));
  425. if (get_process_dep_policy) {
  426. BOOL is_permanent = false;
  427. DWORD dep_flags = 0;
  428. if (!get_process_dep_policy(::GetCurrentProcess(), &dep_flags,
  429. &is_permanent)) {
  430. return SBOX_TEST_FIRST_ERROR;
  431. }
  432. if (!(dep_flags & PROCESS_DEP_ENABLE) || !is_permanent)
  433. return SBOX_TEST_SECOND_ERROR;
  434. } else {
  435. ULONG size = 0;
  436. ULONG dep_flags = 0;
  437. if (!SUCCEEDED(GetNtExports()->QueryInformationProcess(
  438. ::GetCurrentProcess(), ProcessExecuteFlags, &dep_flags,
  439. sizeof(dep_flags), &size))) {
  440. return SBOX_TEST_THIRD_ERROR;
  441. }
  442. static const int MEM_EXECUTE_OPTION_DISABLE = 2;
  443. static const int MEM_EXECUTE_OPTION_PERMANENT = 8;
  444. dep_flags &= 0xff;
  445. if (dep_flags !=
  446. (MEM_EXECUTE_OPTION_DISABLE | MEM_EXECUTE_OPTION_PERMANENT)) {
  447. return SBOX_TEST_FOURTH_ERROR;
  448. }
  449. }
  450. return SBOX_TEST_SUCCEEDED;
  451. }
  452. // ForceMsSigned tests:
  453. // Try to load the DLL given in arg1.
  454. SBOX_TESTS_COMMAND int TestDllLoad(int argc, wchar_t** argv) {
  455. if (argc < 1 || !argv[0])
  456. return SBOX_TEST_INVALID_PARAMETER;
  457. std::wstring dll = argv[0];
  458. base::ScopedNativeLibrary test_dll((base::FilePath(dll)));
  459. if (test_dll.is_valid())
  460. return SBOX_TEST_SUCCEEDED;
  461. // Note: GetLastError() does not get an accurate failure code
  462. // at this point.
  463. return SBOX_TEST_FAILED;
  464. }
  465. // This test attempts a non-system font load.
  466. //
  467. // 1) Load gdi32.dll for required font APIs.
  468. // 2) Load file contents of font file passed in arg1 into memory.
  469. // 3) Call API to try loading a non-system font.
  470. //
  471. // Arg1: Full path to font file to try loading.
  472. SBOX_TESTS_COMMAND int CheckWin10FontLoad(int argc, wchar_t** argv) {
  473. if (argc < 1)
  474. return SBOX_TEST_INVALID_PARAMETER;
  475. HMODULE gdi_module = ::LoadLibraryW(L"gdi32.dll");
  476. if (!gdi_module)
  477. return SBOX_TEST_NOT_FOUND;
  478. AddFontMemResourceExFunction add_font_mem_resource =
  479. reinterpret_cast<AddFontMemResourceExFunction>(
  480. ::GetProcAddress(gdi_module, "AddFontMemResourceEx"));
  481. RemoveFontMemResourceExFunction rem_font_mem_resource =
  482. reinterpret_cast<RemoveFontMemResourceExFunction>(
  483. ::GetProcAddress(gdi_module, "RemoveFontMemResourceEx"));
  484. if (!add_font_mem_resource || !rem_font_mem_resource)
  485. return SBOX_TEST_NOT_FOUND;
  486. // Open font file passed in as an argument.
  487. base::File file(base::FilePath(argv[0]),
  488. base::File::FLAG_OPEN | base::File::FLAG_READ);
  489. if (!file.IsValid())
  490. // Failed to open the font file passed in.
  491. return SBOX_TEST_NOT_FOUND;
  492. std::vector<char> font_data;
  493. int64_t len = file.GetLength();
  494. if (len < 0)
  495. return SBOX_TEST_NOT_FOUND;
  496. font_data.resize(len);
  497. int read = file.Read(0, &font_data[0], base::checked_cast<int>(len));
  498. file.Close();
  499. if (read != len)
  500. return SBOX_TEST_NOT_FOUND;
  501. DWORD font_count = 0;
  502. HANDLE font_handle =
  503. add_font_mem_resource(&font_data[0], static_cast<DWORD>(font_data.size()),
  504. nullptr, &font_count);
  505. if (font_handle) {
  506. rem_font_mem_resource(font_handle);
  507. return SBOX_TEST_SUCCEEDED;
  508. }
  509. return SBOX_TEST_FAILED;
  510. }
  511. // Common helper test for CreateProcess.
  512. // Arg1: The process commandline to create.
  513. // Arg2: Will process end on its own:
  514. // - "true" for a process expected to finish on its own (wait for it).
  515. // - "false" for a process that will require terminating.
  516. // Arg3: [OPTIONAL] Expected or forced exit code:
  517. // - If arg2 is "true", this is the expected exit code (default 0).
  518. // - If arg2 is "false", terminate the process with this exit code (default 0).
  519. //
  520. // ***Make sure you've enabled basic process creation in the
  521. // test sandbox settings via:
  522. // sandbox::TargetPolicy::SetJobLevel(),
  523. // sandbox::TargetPolicy::SetTokenLevel(),
  524. // and TestRunner::SetDisableCsrss().
  525. SBOX_TESTS_COMMAND int TestChildProcess(int argc, wchar_t** argv) {
  526. if (argc < 2 || argc > 3)
  527. return SBOX_TEST_INVALID_PARAMETER;
  528. bool process_finishes = true;
  529. std::wstring arg2 = argv[1];
  530. if (arg2.compare(L"false") == 0)
  531. process_finishes = false;
  532. int desired_exit_code = 0;
  533. if (argc == 3) {
  534. desired_exit_code = wcstoul(argv[2], nullptr, 0);
  535. }
  536. std::wstring cmd = argv[0];
  537. base::LaunchOptions options = base::LaunchOptionsForTest();
  538. base::Process setup_proc = base::LaunchProcess(cmd.c_str(), options);
  539. if (setup_proc.IsValid()) {
  540. if (process_finishes) {
  541. // Wait for process exit and compare exit code.
  542. int exit_code = 1;
  543. if (!setup_proc.WaitForExitWithTimeout(TestTimeouts::action_max_timeout(),
  544. &exit_code)) {
  545. // Unexpected failure.
  546. setup_proc.Terminate(0, false);
  547. return SBOX_TEST_TIMED_OUT;
  548. }
  549. if (exit_code != desired_exit_code)
  550. return SBOX_TEST_FAILED;
  551. return SBOX_TEST_SUCCEEDED;
  552. } else {
  553. // Terminate process with requested exit code.
  554. setup_proc.Terminate(desired_exit_code, false);
  555. return SBOX_TEST_SUCCEEDED;
  556. }
  557. }
  558. // Process failed to be created.
  559. // Note: GetLastError from CreateProcess returns 5, "ERROR_ACCESS_DENIED".
  560. return SBOX_TEST_FAILED;
  561. }
  562. //------------------------------------------------------------------------------
  563. // Exported Mitigation Tests
  564. //------------------------------------------------------------------------------
  565. //------------------------------------------------------------------------------
  566. // DEP (MITIGATION_DEP and MITIGATION_DEP_NO_ATL_THUNK)
  567. // Win7 x86
  568. //------------------------------------------------------------------------------
  569. #if !defined(_WIN64)
  570. // DEP is always enabled on 64-bit. Only test on x86.
  571. TEST(ProcessMitigationsTest, CheckDepWin7) {
  572. if (base::win::GetVersion() > base::win::Version::WIN7)
  573. return;
  574. TestRunner runner;
  575. sandbox::TargetPolicy* policy = runner.GetPolicy();
  576. EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_DEP |
  577. MITIGATION_DEP_NO_ATL_THUNK |
  578. MITIGATION_SEHOP),
  579. SBOX_ALL_OK);
  580. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(L"CheckDep"));
  581. }
  582. #endif // !defined(_WIN64)
  583. //------------------------------------------------------------------------------
  584. // DEP (MITIGATION_DEP and MITIGATION_DEP_NO_ATL_THUNK)
  585. // >= Win8 x86
  586. //------------------------------------------------------------------------------
  587. #if !defined(_WIN64)
  588. // DEP is always enabled on 64-bit. Only test on x86.
  589. // This test validates that setting the MITIGATION_DEP*
  590. // mitigations enables the setting on a process.
  591. TEST(ProcessMitigationsTest, CheckDepWin8PolicySuccess) {
  592. if (base::win::GetVersion() < base::win::Version::WIN8)
  593. return;
  594. std::wstring test_command = L"CheckPolicy ";
  595. test_command += std::to_wstring(TESTPOLICY_DEP);
  596. //---------------------------------
  597. // 1) Test setting pre-startup.
  598. //---------------------------------
  599. TestRunner runner;
  600. sandbox::TargetPolicy* policy = runner.GetPolicy();
  601. EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_DEP |
  602. MITIGATION_DEP_NO_ATL_THUNK),
  603. SBOX_ALL_OK);
  604. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
  605. //---------------------------------
  606. // 2) Test setting post-startup.
  607. //---------------------------------
  608. TestRunner runner2;
  609. sandbox::TargetPolicy* policy2 = runner2.GetPolicy();
  610. EXPECT_EQ(policy2->SetDelayedProcessMitigations(MITIGATION_DEP |
  611. MITIGATION_DEP_NO_ATL_THUNK),
  612. SBOX_ALL_OK);
  613. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner2.RunTest(test_command.c_str()));
  614. }
  615. #endif // !defined(_WIN64)
  616. //------------------------------------------------------------------------------
  617. // ASLR
  618. // - MITIGATION_RELOCATE_IMAGE
  619. // - MITIGATION_RELOCATE_IMAGE_REQUIRED
  620. // - MITIGATION_BOTTOM_UP_ASLR
  621. // - MITIGATION_HIGH_ENTROPY_ASLR
  622. // >= Win8
  623. //------------------------------------------------------------------------------
  624. TEST(ProcessMitigationsTest, CheckWin8AslrPolicySuccess) {
  625. if (base::win::GetVersion() < base::win::Version::WIN8)
  626. return;
  627. std::wstring test_command = L"CheckPolicy ";
  628. test_command += std::to_wstring(TESTPOLICY_ASLR);
  629. //---------------------------------------------
  630. // Only test in release for now.
  631. // TODO(pennymac): overhaul ASLR, crbug/834907.
  632. //---------------------------------------------
  633. #if defined(NDEBUG)
  634. TestRunner runner;
  635. sandbox::TargetPolicy* policy = runner.GetPolicy();
  636. EXPECT_EQ(policy->SetProcessMitigations(
  637. MITIGATION_RELOCATE_IMAGE | MITIGATION_RELOCATE_IMAGE_REQUIRED |
  638. MITIGATION_BOTTOM_UP_ASLR | MITIGATION_HIGH_ENTROPY_ASLR),
  639. SBOX_ALL_OK);
  640. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
  641. #endif // defined(NDEBUG)
  642. }
  643. //------------------------------------------------------------------------------
  644. // Strict handle checks (MITIGATION_STRICT_HANDLE_CHECKS)
  645. // >= Win8
  646. //------------------------------------------------------------------------------
  647. TEST(ProcessMitigationsTest, CheckWin8StrictHandlePolicySuccess) {
  648. if (base::win::GetVersion() < base::win::Version::WIN8)
  649. return;
  650. std::wstring test_command = L"CheckPolicy ";
  651. test_command += std::to_wstring(TESTPOLICY_STRICTHANDLE);
  652. //---------------------------------
  653. // 1) Test setting post-startup.
  654. // ** Can only be set post-startup.
  655. //---------------------------------
  656. TestRunner runner;
  657. sandbox::TargetPolicy* policy = runner.GetPolicy();
  658. EXPECT_EQ(
  659. policy->SetDelayedProcessMitigations(MITIGATION_STRICT_HANDLE_CHECKS),
  660. SBOX_ALL_OK);
  661. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
  662. }
  663. //------------------------------------------------------------------------------
  664. // Disable non-system font loads (MITIGATION_NONSYSTEM_FONT_DISABLE)
  665. // >= Win10
  666. //------------------------------------------------------------------------------
  667. // This test validates that setting the MITIGATION_NON_SYSTEM_FONTS_DISABLE
  668. // mitigation enables the setting on a process.
  669. TEST(ProcessMitigationsTest, CheckWin10NonSystemFontLockDownPolicySuccess) {
  670. if (base::win::GetVersion() < base::win::Version::WIN10)
  671. return;
  672. std::wstring test_command = L"CheckPolicy ";
  673. test_command += std::to_wstring(TESTPOLICY_NONSYSFONT);
  674. //---------------------------------
  675. // 1) Test setting pre-startup.
  676. //---------------------------------
  677. TestRunner runner;
  678. sandbox::TargetPolicy* policy = runner.GetPolicy();
  679. EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_NONSYSTEM_FONT_DISABLE),
  680. SBOX_ALL_OK);
  681. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
  682. //---------------------------------
  683. // 2) Test setting post-startup.
  684. //---------------------------------
  685. TestRunner runner2;
  686. sandbox::TargetPolicy* policy2 = runner2.GetPolicy();
  687. EXPECT_EQ(
  688. policy2->SetDelayedProcessMitigations(MITIGATION_NONSYSTEM_FONT_DISABLE),
  689. SBOX_ALL_OK);
  690. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner2.RunTest(test_command.c_str()));
  691. }
  692. // This test validates that we can load a non-system font if the
  693. // MITIGATION_NON_SYSTEM_FONTS_DISABLE mitigation is NOT set.
  694. TEST(ProcessMitigationsTest, CheckWin10NonSystemFontLockDownLoadSuccess) {
  695. if (base::win::GetVersion() < base::win::Version::WIN10)
  696. return;
  697. TestWin10NonSystemFont(true /* is_success_test */);
  698. }
  699. // This test validates that setting the MITIGATION_NON_SYSTEM_FONTS_DISABLE
  700. // mitigation prevents the loading of a non-system font.
  701. TEST(ProcessMitigationsTest, CheckWin10NonSystemFontLockDownLoadFailure) {
  702. if (base::win::GetVersion() < base::win::Version::WIN10)
  703. return;
  704. TestWin10NonSystemFont(false /* is_success_test */);
  705. }
  706. //------------------------------------------------------------------------------
  707. // Force MS Signed Binaries (MITIGATION_FORCE_MS_SIGNED_BINS)
  708. // >= Win10 TH2
  709. //
  710. // (Note: the signing options for "MS store-signed" and "MS, store, or WHQL"
  711. // are not supported or tested by the sandbox at the moment.)
  712. //------------------------------------------------------------------------------
  713. // This test validates that setting the MITIGATION_FORCE_MS_SIGNED_BINS
  714. // mitigation enables the setting on a process.
  715. TEST(ProcessMitigationsTest, CheckWin10MsSignedPolicySuccessDelayed) {
  716. if (base::win::GetVersion() < base::win::Version::WIN10_TH2)
  717. return;
  718. std::wstring test_command = L"CheckPolicy ";
  719. test_command += std::to_wstring(TESTPOLICY_MSSIGNED);
  720. //---------------------------------
  721. // 1) Test setting post-startup.
  722. // **Only test if NOT component build, otherwise component DLLs are not signed
  723. // by MS and prevent process setup.
  724. // **Only test post-startup, otherwise this test executable has dependencies
  725. // on DLLs that are not signed by MS and they prevent process startup.
  726. //---------------------------------
  727. #if !defined(COMPONENT_BUILD)
  728. TestRunner runner2;
  729. sandbox::TargetPolicy* policy2 = runner2.GetPolicy();
  730. EXPECT_EQ(
  731. policy2->SetDelayedProcessMitigations(MITIGATION_FORCE_MS_SIGNED_BINS),
  732. SBOX_ALL_OK);
  733. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner2.RunTest(test_command.c_str()));
  734. #endif // !defined(COMPONENT_BUILD)
  735. }
  736. // This test validates that setting the MITIGATION_FORCE_MS_SIGNED_BINS
  737. // mitigation enables the setting on a process when non-delayed.
  738. // Disabled due to crbug.com/1081080
  739. TEST(ProcessMitigationsTest, DISABLED_CheckWin10MsSignedPolicySuccess) {
  740. if (base::win::GetVersion() < base::win::Version::WIN10_TH2)
  741. return;
  742. std::wstring test_command = L"CheckPolicy ";
  743. test_command += std::to_wstring(TESTPOLICY_MSSIGNED);
  744. //---------------------------------
  745. // 1) Test setting post-startup.
  746. // **Only test if NOT component build, otherwise component DLLs are not signed
  747. // by MS and prevent process setup.
  748. // **Only test post-startup, otherwise this test executable has dependencies
  749. // on DLLs that are not signed by MS and they prevent process startup.
  750. //---------------------------------
  751. TestRunner runner2;
  752. sandbox::TargetPolicy* policy = runner2.GetPolicy();
  753. EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_FORCE_MS_SIGNED_BINS),
  754. SBOX_ALL_OK);
  755. // In a component build, the DLLs must be allowed to load.
  756. #if defined(COMPONENT_BUILD)
  757. base::FilePath exe_path;
  758. EXPECT_TRUE(base::PathService::Get(base::DIR_EXE, &exe_path));
  759. // Allow all *.dll in current directory to load.
  760. EXPECT_EQ(sandbox::SBOX_ALL_OK,
  761. policy->GetConfig()->AddRule(
  762. sandbox::SubSystem::kSignedBinary,
  763. sandbox::Semantics::kSignedAllowLoad,
  764. exe_path.DirName().AppendASCII("*.dll").value().c_str()));
  765. #endif // defined(COMPONENT_BUILD)
  766. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner2.RunTest(test_command.c_str()));
  767. }
  768. // This test validates that we can load an unsigned DLL if the
  769. // MITIGATION_FORCE_MS_SIGNED_BINS mitigation is NOT set.
  770. TEST(ProcessMitigationsTest, CheckWin10MsSigned_Success) {
  771. if (base::win::GetVersion() < base::win::Version::WIN10_TH2)
  772. return;
  773. ScopedTestMutex mutex(hooking_dll::g_hooking_dll_mutex);
  774. TestWin10MsSigned(sandbox::SBOX_TEST_SUCCEEDED /* expected */,
  775. false /* enable_mitigation */,
  776. false /* delayed */,
  777. false /* use_ms_signed_binary */,
  778. false /* add_dll_permission */,
  779. false /* add_directory_permission */);
  780. }
  781. // This test validates that setting the MITIGATION_FORCE_MS_SIGNED_BINS
  782. // mitigation prevents the loading of an unsigned DLL.
  783. TEST(ProcessMitigationsTest, CheckWin10MsSigned_Failure) {
  784. if (base::win::GetVersion() < base::win::Version::WIN10_TH2)
  785. return;
  786. ScopedTestMutex mutex(hooking_dll::g_hooking_dll_mutex);
  787. TestWin10MsSigned(sandbox::SBOX_TEST_FAILED /* expected */,
  788. true /* enable_mitigation */,
  789. true /* delayed */,
  790. false /* use_ms_signed_binary */,
  791. false /* add_dll_permission */,
  792. false /* add_directory_permission */);
  793. }
  794. // ASAN doesn't initialize early enough for the intercepts in NtCreateSection to
  795. // be able to use std::unique_ptr, so disable pre-launch CIG on ASAN builds.
  796. #if !defined(ADDRESS_SANITIZER)
  797. #define MAYBE_CheckWin10MsSigned_FailurePreSpawn \
  798. CheckWin10MsSigned_FailurePreSpawn
  799. #else
  800. #define MAYBE_CheckWin10MsSigned_FailurePreSpawn \
  801. DISABLED_CheckWin10MsSigned_FailurePreSpawn
  802. #endif
  803. // This test validates that setting the MITIGATION_FORCE_MS_SIGNED_BINS
  804. // mitigation allows the loading of an unsigned DLL if intercept in place.
  805. // Disabled due to crbug.com/1081080. This test was previously disabled on ASAN
  806. // builds, so if re-enabling remember to test that behaviour.
  807. TEST(ProcessMitigationsTest, DISABLED_CheckWin10MsSignedWithIntercept_Success) {
  808. if (base::win::GetVersion() < base::win::Version::WIN10_TH2)
  809. return;
  810. ScopedTestMutex mutex(hooking_dll::g_hooking_dll_mutex);
  811. // Expect success; Enable mitigation; Use non MS-signed binary.
  812. #if defined(COMPONENT_BUILD)
  813. // In a component build, add the directory to the allowed list.
  814. TestWin10MsSigned(sandbox::SBOX_TEST_SUCCEEDED /* expected */,
  815. true /* enable_mitigation */,
  816. false /* delayed */,
  817. false /* use_ms_signed_binary */,
  818. true /* add_dll_permission */,
  819. true /* add_directory_permission */);
  820. #else
  821. TestWin10MsSigned(sandbox::SBOX_TEST_SUCCEEDED /* expected */,
  822. true /* enable_mitigation */,
  823. false /* delayed */,
  824. false /* use_ms_signed_binary */,
  825. true /* add_dll_permission */,
  826. false /* add_directory_permission */);
  827. #endif // defined(COMPONENT_BUILD)
  828. }
  829. // This test validates that setting the MITIGATION_FORCE_MS_SIGNED_BINS
  830. // mitigation pre-load prevents the loading of an unsigned DLL.
  831. TEST(ProcessMitigationsTest, MAYBE_CheckWin10MsSigned_FailurePreSpawn) {
  832. if (base::win::GetVersion() < base::win::Version::WIN10_TH2)
  833. return;
  834. ScopedTestMutex mutex(hooking_dll::g_hooking_dll_mutex);
  835. // Other code in base/process relies on this invariant.
  836. static_assert(
  837. base::win::kStatusInvalidImageHashExitCode == STATUS_INVALID_IMAGE_HASH,
  838. "Invalid hash exit code does not match between base and sandbox.");
  839. #if defined(COMPONENT_BUILD)
  840. // In a component build, the executable will fail to start-up because
  841. // imports e.g. base.dll cannot be resolved.
  842. int expected = STATUS_INVALID_IMAGE_HASH;
  843. #else
  844. // In a non-component build, the process will start, but the unsigned
  845. // DLL will fail to load inside the test itself.
  846. int expected = sandbox::SBOX_TEST_FAILED;
  847. #endif
  848. TestWin10MsSigned(expected /* expected */,
  849. true /* enable_mitigation */,
  850. false /* delayed */,
  851. false /* use_ms_signed_binary */,
  852. false /* add_dll_permission */,
  853. false /* add_directory_permission */);
  854. }
  855. // This test validates that we can load a signed Microsoft DLL if the
  856. // MITIGATION_FORCE_MS_SIGNED_BINS mitigation is NOT set. Very basic
  857. // sanity test.
  858. TEST(ProcessMitigationsTest, CheckWin10MsSigned_MsBaseline) {
  859. if (base::win::GetVersion() < base::win::Version::WIN10_TH2)
  860. return;
  861. ScopedTestMutex mutex(hooking_dll::g_hooking_dll_mutex);
  862. TestWin10MsSigned(sandbox::SBOX_TEST_SUCCEEDED /* expected */,
  863. false /* enable_mitigation */,
  864. false /* delayed */,
  865. true /* use_ms_signed_binary */,
  866. false /* add_dll_permission */,
  867. false /* add_directory_permission */);
  868. }
  869. // This test validates that setting the MITIGATION_FORCE_MS_SIGNED_BINS
  870. // mitigation still allows the load of an MS-signed DLL.
  871. TEST(ProcessMitigationsTest, CheckWin10MsSigned_MsSuccess) {
  872. if (base::win::GetVersion() < base::win::Version::WIN10_TH2)
  873. return;
  874. ScopedTestMutex mutex(hooking_dll::g_hooking_dll_mutex);
  875. TestWin10MsSigned(sandbox::SBOX_TEST_SUCCEEDED /* expected */,
  876. true /* enable_mitigation */,
  877. true /* delayed */,
  878. true /* use_ms_signed_binary */,
  879. false /* add_dll_permission */,
  880. false /* add_directory_permission */);
  881. }
  882. //------------------------------------------------------------------------------
  883. // Disable child process creation.
  884. // - JobLevel <= JobLevel::kLimitedUser (on < WIN10_TH2).
  885. // - JobLevel <= JobLevel::kLimitedUser which also triggers setting
  886. // PROC_THREAD_ATTRIBUTE_CHILD_PROCESS_POLICY to
  887. // PROCESS_CREATION_CHILD_PROCESS_RESTRICTED in
  888. // BrokerServicesBase::SpawnTarget (on >= WIN10_TH2).
  889. //------------------------------------------------------------------------------
  890. // This test validates that we can spawn a child process if
  891. // MITIGATION_CHILD_PROCESS_CREATION_RESTRICTED mitigation is
  892. // not set.
  893. TEST(ProcessMitigationsTest, CheckChildProcessSuccess) {
  894. TestRunner runner;
  895. sandbox::TargetPolicy* policy = runner.GetPolicy();
  896. // Set a policy that would normally allow for process creation.
  897. policy->SetJobLevel(JobLevel::kInteractive, 0);
  898. policy->SetTokenLevel(USER_UNPROTECTED, USER_UNPROTECTED);
  899. runner.SetDisableCsrss(false);
  900. base::FilePath cmd;
  901. EXPECT_TRUE(base::PathService::Get(base::DIR_SYSTEM, &cmd));
  902. cmd = cmd.Append(L"calc.exe");
  903. std::wstring test_command = L"TestChildProcess \"";
  904. test_command += cmd.value().c_str();
  905. test_command += L"\" false";
  906. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
  907. }
  908. // This test validates that setting the
  909. // MITIGATION_CHILD_PROCESS_CREATION_RESTRICTED mitigation prevents
  910. // the spawning of child processes.
  911. TEST(ProcessMitigationsTest, CheckChildProcessFailure) {
  912. TestRunner runner;
  913. sandbox::TargetPolicy* policy = runner.GetPolicy();
  914. // Now set the job level to be <= JobLevel::kLimitedUser
  915. // and ensure we can no longer create a child process.
  916. policy->SetJobLevel(JobLevel::kLimitedUser, 0);
  917. policy->SetTokenLevel(USER_UNPROTECTED, USER_UNPROTECTED);
  918. runner.SetDisableCsrss(false);
  919. base::FilePath cmd;
  920. EXPECT_TRUE(base::PathService::Get(base::DIR_SYSTEM, &cmd));
  921. cmd = cmd.Append(L"calc.exe");
  922. std::wstring test_command = L"TestChildProcess \"";
  923. test_command += cmd.value().c_str();
  924. test_command += L"\" false";
  925. EXPECT_EQ(SBOX_TEST_FAILED, runner.RunTest(test_command.c_str()));
  926. }
  927. // This test validates that when the sandboxed target within a job spawns a
  928. // child process and the target process exits abnormally, the broker correctly
  929. // handles the JOB_OBJECT_MSG_ABNORMAL_EXIT_PROCESS message.
  930. // Because this involves spawning a child process from the target process and is
  931. // very similar to the above CheckChildProcess* tests, this test is here rather
  932. // than elsewhere closer to the other Job tests.
  933. TEST(ProcessMitigationsTest, CheckChildProcessAbnormalExit) {
  934. TestRunner runner;
  935. sandbox::TargetPolicy* policy = runner.GetPolicy();
  936. // Set a policy that would normally allow for process creation.
  937. policy->SetJobLevel(JobLevel::kInteractive, 0);
  938. policy->SetTokenLevel(USER_UNPROTECTED, USER_UNPROTECTED);
  939. runner.SetDisableCsrss(false);
  940. base::FilePath cmd;
  941. EXPECT_TRUE(base::PathService::Get(base::DIR_SYSTEM, &cmd));
  942. cmd = cmd.Append(L"calc.exe");
  943. std::wstring test_command = L"TestChildProcess \"";
  944. test_command += cmd.value().c_str();
  945. test_command += L"\" false ";
  946. test_command += std::to_wstring(STATUS_ACCESS_VIOLATION);
  947. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
  948. }
  949. //------------------------------------------------------------------------------
  950. // Restrict indirect branch prediction
  951. // (MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION)
  952. // >= Win10 RS3
  953. //------------------------------------------------------------------------------
  954. // This test validates that setting the
  955. // MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION mitigation enables the setting
  956. // on a process.
  957. TEST(ProcessMitigationsTest,
  958. CheckWin10RestrictIndirectBranchPredictionPolicySuccess) {
  959. if (base::win::GetVersion() < base::win::Version::WIN10_RS3)
  960. return;
  961. std::wstring test_command = L"CheckPolicy ";
  962. test_command += std::to_wstring(TESTPOLICY_RESTRICTINDIRECTBRANCHPREDICTION);
  963. //---------------------------------
  964. // 1) Test setting pre-startup.
  965. //---------------------------------
  966. TestRunner runner;
  967. sandbox::TargetPolicy* policy = runner.GetPolicy();
  968. EXPECT_EQ(policy->SetProcessMitigations(
  969. MITIGATION_RESTRICT_INDIRECT_BRANCH_PREDICTION),
  970. SBOX_ALL_OK);
  971. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
  972. //---------------------------------
  973. // 2) Test setting post-startup.
  974. // ** Post-startup not supported. Must be enabled on creation.
  975. //---------------------------------
  976. }
  977. //------------------------------------------------------------------------------
  978. // Hardware shadow stack / Control(flow) Enforcement Technology / CETCOMPAT
  979. // (MITIGATION_CET_DISABLED)
  980. // >= Win10 2004
  981. //------------------------------------------------------------------------------
  982. // This test validates that setting the
  983. // MITIGATION_CET_DISABLED mitigation disables CET in child processes. The test
  984. // only makes sense where the parent was launched with CET enabled, hence we
  985. // bail out early on systems that do not support CET.
  986. TEST(ProcessMitigationsTest, CetDisablePolicy) {
  987. if (base::win::GetVersion() < base::win::Version::WIN10_20H1)
  988. return;
  989. // Verify policy is available and set for this process (i.e. CET is
  990. // enabled via IFEO or through the CETCOMPAT bit on the executable).
  991. auto get_process_mitigation_policy =
  992. reinterpret_cast<decltype(&GetProcessMitigationPolicy)>(::GetProcAddress(
  993. ::GetModuleHandleA("kernel32.dll"), "GetProcessMitigationPolicy"));
  994. PROCESS_MITIGATION_USER_SHADOW_STACK_POLICY uss_policy;
  995. if (!get_process_mitigation_policy(GetCurrentProcess(),
  996. ProcessUserShadowStackPolicy, &uss_policy,
  997. sizeof(uss_policy))) {
  998. return;
  999. }
  1000. if (!uss_policy.EnableUserShadowStack)
  1001. return;
  1002. std::wstring test_command = L"CheckPolicy ";
  1003. test_command += std::to_wstring(TESTPOLICY_CETDISABLED);
  1004. //---------------------------------
  1005. // 1) Test setting pre-startup.
  1006. //---------------------------------
  1007. TestRunner runner;
  1008. sandbox::TargetPolicy* policy = runner.GetPolicy();
  1009. EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_CET_DISABLED),
  1010. SBOX_ALL_OK);
  1011. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
  1012. //---------------------------------
  1013. // 2) Test setting post-startup.
  1014. // ** Post-startup not supported. Must be enabled on creation.
  1015. //---------------------------------
  1016. }
  1017. // This test validates that setting the
  1018. // MITIGATION_CET_ALLOW_DYNAMIC_APIS enables CET with in-process dynamic apis
  1019. // allowed for the child process. The test only makes sense where the parent was
  1020. // launched with CET enabled, hence we bail out early on systems that do not
  1021. // support CET.
  1022. TEST(ProcessMitigationsTest, CetAllowDynamicApis) {
  1023. if (base::win::GetVersion() < base::win::Version::WIN10_20H1)
  1024. return;
  1025. // Verify policy is available and set for this process (i.e. CET is
  1026. // enabled via IFEO or through the CETCOMPAT bit on the executable).
  1027. auto get_process_mitigation_policy =
  1028. reinterpret_cast<decltype(&GetProcessMitigationPolicy)>(::GetProcAddress(
  1029. ::GetModuleHandleA("kernel32.dll"), "GetProcessMitigationPolicy"));
  1030. PROCESS_MITIGATION_USER_SHADOW_STACK_POLICY uss_policy;
  1031. if (!get_process_mitigation_policy(GetCurrentProcess(),
  1032. ProcessUserShadowStackPolicy, &uss_policy,
  1033. sizeof(uss_policy))) {
  1034. return;
  1035. }
  1036. if (!uss_policy.EnableUserShadowStack)
  1037. return;
  1038. std::wstring test_command = L"CheckPolicy ";
  1039. test_command += std::to_wstring(TESTPOLICY_CETDYNAMICAPIS);
  1040. //---------------------------------
  1041. // 1) Test setting pre-startup.
  1042. //---------------------------------
  1043. TestRunner runner;
  1044. sandbox::TargetPolicy* policy = runner.GetPolicy();
  1045. EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_CET_ALLOW_DYNAMIC_APIS),
  1046. SBOX_ALL_OK);
  1047. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
  1048. //---------------------------------
  1049. // 2) Test setting post-startup.
  1050. // ** Post-startup not supported. Must be enabled on creation.
  1051. //---------------------------------
  1052. }
  1053. // This test validates that setting the MITIGATION_CET_STRICT_MODE enables CET
  1054. // in strict mode. The test only makes sense where the parent was launched with
  1055. // CET enabled, hence we bail out early on systems that do not support CET.
  1056. TEST(ProcessMitigationsTest, CetStrictMode) {
  1057. if (base::win::GetVersion() < base::win::Version::WIN10_20H1)
  1058. return;
  1059. // Verify policy is available and set for this process (i.e. CET is
  1060. // enabled via IFEO or through the CETCOMPAT bit on the executable).
  1061. auto get_process_mitigation_policy =
  1062. reinterpret_cast<decltype(&GetProcessMitigationPolicy)>(::GetProcAddress(
  1063. ::GetModuleHandleA("kernel32.dll"), "GetProcessMitigationPolicy"));
  1064. PROCESS_MITIGATION_USER_SHADOW_STACK_POLICY uss_policy;
  1065. if (!get_process_mitigation_policy(GetCurrentProcess(),
  1066. ProcessUserShadowStackPolicy, &uss_policy,
  1067. sizeof(uss_policy))) {
  1068. return;
  1069. }
  1070. if (!uss_policy.EnableUserShadowStack)
  1071. return;
  1072. std::wstring test_command = L"CheckPolicy ";
  1073. test_command += std::to_wstring(TESTPOLICY_CETSTRICT);
  1074. //---------------------------------
  1075. // 1) Test setting pre-startup.
  1076. //---------------------------------
  1077. TestRunner runner;
  1078. sandbox::TargetPolicy* policy = runner.GetPolicy();
  1079. EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_CET_STRICT_MODE),
  1080. SBOX_ALL_OK);
  1081. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
  1082. //---------------------------------
  1083. // 2) Test setting post-startup.
  1084. // ** Post-startup not supported. Must be enabled on creation.
  1085. //---------------------------------
  1086. }
  1087. TEST(ProcessMitigationsTest, CheckWin10KernelTransactionManagerMitigation) {
  1088. const auto& ver = base::win::OSInfo::GetInstance()->version_number();
  1089. // This feature is enabled starting in KB5005101
  1090. if (ver.build < 19041 || (ver.build < 19044 && ver.patch < 1202))
  1091. return;
  1092. std::wstring test_policy_command = L"CheckPolicy ";
  1093. test_policy_command += std::to_wstring(TESTPOLICY_KTMCOMPONENTFILTER);
  1094. TestRunner runner;
  1095. sandbox::TargetPolicy* policy = runner.GetPolicy();
  1096. EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_KTM_COMPONENT),
  1097. SBOX_ALL_OK);
  1098. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_policy_command.c_str()));
  1099. }
  1100. TEST(ProcessMitigationsTest, CheckWin10ImageLoadNoRemotePolicySuccess) {
  1101. if (base::win::GetVersion() < base::win::Version::WIN10_TH2)
  1102. return;
  1103. std::wstring test_command = L"CheckPolicy ";
  1104. test_command += std::to_wstring(TESTPOLICY_LOADNOREMOTE);
  1105. //---------------------------------
  1106. // 1) Test setting pre-startup.
  1107. //---------------------------------
  1108. TestRunner runner;
  1109. sandbox::TargetPolicy* policy = runner.GetPolicy();
  1110. EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_IMAGE_LOAD_NO_REMOTE),
  1111. SBOX_ALL_OK);
  1112. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
  1113. //---------------------------------
  1114. // 2) Test setting post-startup.
  1115. //---------------------------------
  1116. TestRunner runner2;
  1117. sandbox::TargetPolicy* policy2 = runner2.GetPolicy();
  1118. EXPECT_EQ(
  1119. policy2->SetDelayedProcessMitigations(MITIGATION_IMAGE_LOAD_NO_REMOTE),
  1120. SBOX_ALL_OK);
  1121. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner2.RunTest(test_command.c_str()));
  1122. }
  1123. //---------------
  1124. // This test validates that setting the MITIGATION_IMAGE_LOAD_NO_LOW_LABEL
  1125. // mitigation enables the setting on a process.
  1126. TEST(ProcessMitigationsTest, CheckWin10ImageLoadNoLowLabelPolicySuccess) {
  1127. if (base::win::GetVersion() < base::win::Version::WIN10_TH2)
  1128. return;
  1129. std::wstring test_command = L"CheckPolicy ";
  1130. test_command += std::to_wstring(TESTPOLICY_LOADNOLOW);
  1131. //---------------------------------
  1132. // 1) Test setting pre-startup.
  1133. //---------------------------------
  1134. TestRunner runner;
  1135. sandbox::TargetPolicy* policy = runner.GetPolicy();
  1136. EXPECT_EQ(policy->SetProcessMitigations(MITIGATION_IMAGE_LOAD_NO_LOW_LABEL),
  1137. SBOX_ALL_OK);
  1138. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner.RunTest(test_command.c_str()));
  1139. //---------------------------------
  1140. // 2) Test setting post-startup.
  1141. //---------------------------------
  1142. TestRunner runner2;
  1143. sandbox::TargetPolicy* policy2 = runner2.GetPolicy();
  1144. EXPECT_EQ(
  1145. policy2->SetDelayedProcessMitigations(MITIGATION_IMAGE_LOAD_NO_LOW_LABEL),
  1146. SBOX_ALL_OK);
  1147. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner2.RunTest(test_command.c_str()));
  1148. }
  1149. // This test validates that setting the MITIGATION_IMAGE_LOAD_PREFER_SYS32
  1150. // mitigation enables the setting on a process.
  1151. TEST(ProcessMitigationsTest, CheckWin10ImageLoadPreferSys32PolicySuccess) {
  1152. if (base::win::GetVersion() < base::win::Version::WIN10_RS1)
  1153. return;
  1154. std::wstring test_command = L"CheckPolicy ";
  1155. test_command += std::to_wstring(TESTPOLICY_LOADPREFERSYS32);
  1156. //---------------------------------
  1157. // 1) Test setting pre-startup.
  1158. // ** Currently disabled. All PreferSys32 tests start to explode on
  1159. // >= Win10 1703/RS2 when this mitigation is set pre-startup.
  1160. // Child process creation works fine, but when ::ResumeThread() is called,
  1161. // there is a fatal error: "Entry point ucnv_convertEx_60 could not be
  1162. // located in the DLL ... sbox_integration_tests.exe."
  1163. // This is a character conversion function in a ucnv (unicode) DLL.
  1164. // Potentially the loader is finding a different version of this DLL that
  1165. // we have a dependency on in System32... but it doesn't match up with
  1166. // what we build against???!
  1167. //---------------------------------
  1168. //---------------------------------
  1169. // 2) Test setting post-startup.
  1170. //---------------------------------
  1171. TestRunner runner2;
  1172. sandbox::TargetPolicy* policy2 = runner2.GetPolicy();
  1173. EXPECT_EQ(
  1174. policy2->SetDelayedProcessMitigations(MITIGATION_IMAGE_LOAD_PREFER_SYS32),
  1175. SBOX_ALL_OK);
  1176. EXPECT_EQ(SBOX_TEST_SUCCEEDED, runner2.RunTest(test_command.c_str()));
  1177. }
  1178. } // namespace sandbox