#include <Windows.h>
#include <intrin.h>
#include "base/compiler_specific.h"
#include "base/win/windows_version.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace base {
namespace win {
namespace {
bool IsHardwareEnforcedShadowStacksEnabled() {
if (base::win::GetVersion() < base::win::Version::WIN10_20H1) {
return false;
}
PROCESS_MITIGATION_USER_SHADOW_STACK_POLICY uss_policy;
if (!::GetProcessMitigationPolicy(GetCurrentProcess(),
ProcessUserShadowStackPolicy, &uss_policy,
sizeof(uss_policy))) {
return false;
}
if (uss_policy.EnableUserShadowStack) {
return true;
} else {
return false;
}
}
void* return_address;
NOINLINE void Bug() {
void* pvAddressOfReturnAddress = _AddressOfReturnAddress();
if (!return_address) {
return_address = *reinterpret_cast<void**>(pvAddressOfReturnAddress);
} else {
*reinterpret_cast<void**>(pvAddressOfReturnAddress) = return_address;
}
}
NOINLINE void A() {
Bug();
}
NOINLINE void B() {
Bug();
}
}
TEST(CET, ShadowStack) {
if (IsHardwareEnforcedShadowStacksEnabled()) {
A();
EXPECT_DEATH(B(), "");
}
}
}
}