Hello vivs_lunchtime,
I think that everyone can use the xsaveremovefeature 0x800 option; when used, XSTATE_CET_U in SharedUserData.XState.EnabledSupervisorFeatures will not be set and the CET flag in CR4 will not be set. Any feature that depends on CET will not be enabled.
In Alex's original configuration, XSTATE_CET_U and CR4.CET were set. A "side-effect" of setting CR4.CET (i.e. not being able to clear CR0.WP) caused (presumably) PatchGuard to crash the system.
According to the Intel manual, CET provides two capabilities: Shadow Stack and Indirect Branch Tracking.
For brevity, in the following text I have omitted all of my usual "I think/believe" qualifications.
Starting from Windows build 19041, user-mode shadow stack "functionality" is enabled for all threads. I put "functionality" in quotes because what actually happens is dependent on a number of factors, including:
- Whether the DLL has the IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT mark (all Microsoft Windows DLLs should have this flag set).
- Whether SetProcessMitigationPolicy(ProcessUserShadowStackPolicy, ...) has been called (to change default behaviour).
If DLLs marked with IMAGE_DLLCHARACTERISTICS_EX_CET_COMPAT behave correctly, there should be no easily observable impact of the user-mode shadow stacks. There may be some visible indications of shadow stack activity in the Microsoft-Windows-Security-Mitigations event log.
KiUserCetAllowed does not "govern" kernel-mode shadow stacks - it just reflects the setting of CR4.CET. If KiUserCetAllowed is not set then CET is not available and kernel-mode shadow stacks can't be used; as you mentioned, there are also other prerequisites for kernel-mode shadow stacks.
I earlier wrote:
if KiUserCetAllowed then set bit CET in CR4
KiUserCetAllowed is set if SharedUserData.XState.EnabledSupervisorFeatures has bit 11 (0x800) (XSTATE_CET_U) set
KiInitializeXSave initializes SharedUserData.XState.EnabledSupervisorFeatures (combines CPUID information with BCD information)
The order of the text matches how I came to the information:
Search the code in ntoskrnl looking for writes to CR4; check if CET is possibly being set and, if so, what influences the decision (e.g. value of KiUserCetAllowed).
Search the code in ntoskrnl looking for modifications of KiUserCetAllowed and what determines the value set (e.g. value of SharedUserData.XState.EnabledSupervisorFeatures).
Just one further search was needed to see that the CPUID instruction and BCD determined the value of SharedUserData.XState.EnabledSupervisorFeatures.
I think that "bcdedit /deletevalue xsaveremovefeature" should "undo" the bcdedit test but, like you, I have not dared to try it.
Gary