cet_shadow_stack_unittest.cc 1.9 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // Copyright 2020 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 <Windows.h>
  5. #include <intrin.h>
  6. #include "base/compiler_specific.h"
  7. #include "base/win/windows_version.h"
  8. #include "testing/gtest/include/gtest/gtest.h"
  9. namespace base {
  10. namespace win {
  11. namespace {
  12. bool IsHardwareEnforcedShadowStacksEnabled() {
  13. // Only supported post Win 10 2004.
  14. if (base::win::GetVersion() < base::win::Version::WIN10_20H1)
  15. return false;
  16. auto get_process_mitigation_policy =
  17. reinterpret_cast<decltype(&GetProcessMitigationPolicy)>(::GetProcAddress(
  18. ::GetModuleHandleA("kernel32.dll"), "GetProcessMitigationPolicy"));
  19. PROCESS_MITIGATION_USER_SHADOW_STACK_POLICY uss_policy;
  20. if (!get_process_mitigation_policy(GetCurrentProcess(),
  21. ProcessUserShadowStackPolicy, &uss_policy,
  22. sizeof(uss_policy))) {
  23. return false;
  24. }
  25. if (uss_policy.EnableUserShadowStack)
  26. return true;
  27. else
  28. return false;
  29. }
  30. void* return_address;
  31. // Bug() simulates a ROP. The first time we are called we save the
  32. // address we will return to and return to it (like a normal function
  33. // call). The second time we return to the saved address. If called
  34. // from a different function the second time, this redirects control
  35. // flow and should be different from the return address in the shadow
  36. // stack.
  37. NOINLINE void Bug() {
  38. void* pvAddressOfReturnAddress = _AddressOfReturnAddress();
  39. if (!return_address)
  40. return_address = *reinterpret_cast<void**>(pvAddressOfReturnAddress);
  41. else
  42. *reinterpret_cast<void**>(pvAddressOfReturnAddress) = return_address;
  43. }
  44. NOINLINE void A() {
  45. Bug();
  46. }
  47. NOINLINE void B() {
  48. Bug();
  49. }
  50. } // namespace
  51. TEST(CET, ShadowStack) {
  52. if (IsHardwareEnforcedShadowStacksEnabled()) {
  53. A();
  54. EXPECT_DEATH(B(), "");
  55. }
  56. }
  57. } // namespace win
  58. } // namespace base