#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(), "");
}
}
}
}