diff --git a/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp b/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp index b2893308d..753bd27b3 100644 --- a/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp +++ b/FEXCore/Source/Interface/Core/ArchHelpers/Arm64Emitter.cpp @@ -370,6 +370,8 @@ Arm64Emitter::Arm64Emitter(FEXCore::Context::ContextImpl* ctx, void* EmissionPtr // Hardcode a 256-bit vector width if we are running in the simulator. // Allow the user to override this. Simulator.SetVectorLengthInBits(ForceSVEWidth() ? ForceSVEWidth() : 256); + // FEX doesn't support GCS. + Simulator.DisableGCSCheck(); #endif #ifdef VIXL_DISASSEMBLER // Only setup the disassembler if enabled. diff --git a/Source/Tools/FEXLoader/FEXLoader.cpp b/Source/Tools/FEXLoader/FEXLoader.cpp index d9ebe995c..0081eeeba 100644 --- a/Source/Tools/FEXLoader/FEXLoader.cpp +++ b/Source/Tools/FEXLoader/FEXLoader.cpp @@ -270,6 +270,33 @@ void SetupCompatInput(bool enable) { } } // namespace FEX::CompatInput +namespace FEX::GCS { + void CheckForGCS() { +#ifndef PR_GET_SHADOW_STACK_STATUS +#define PR_GET_SHADOW_STACK_STATUS 74 +#endif +#ifndef PR_LOCK_SHADOW_STACK_STATUS +#define PR_LOCK_SHADOW_STACK_STATUS 76 +#endif +#ifndef PR_SHADOW_STACK_ENABLE +#define PR_SHADOW_STACK_ENABLE (1ULL << 0) +#endif + uint64_t ShadowStackWord {}; + if (prctl(PR_GET_SHADOW_STACK_STATUS, &ShadowStackWord, 0, 0, 0) == -1) { + return; + } + + // Kernel supports shadow stack. + if (ShadowStackWord & PR_SHADOW_STACK_ENABLE) { + // Welp. + ERROR_AND_DIE_FMT("Shadow stack is enabled which FEX is incompatible with!"); + } + + // Disable if we've gotten this far, to ensure guest can't try. + prctl(PR_LOCK_SHADOW_STACK_STATUS, ~0ULL, 0, 0, 0); + } +} + /** * @brief Get an FD from an environment variable and then unset the environment variable. * @@ -314,6 +341,8 @@ int main(int argc, char** argv, char** const envp) { return 0; } + FEX::GCS::CheckForGCS(); + FEX::Config::LoadConfig(std::move(ArgsLoader), Program.ProgramName, envp, PortableInfo); // Reload the meta layer