CET supported by default
apphost
and singlefilehost
are now marked as Intel CET—compatible (they're compiled with the /CETCOMPAT
option). This change was made to enhance security of .NET applications. However, it imposes a limitation on the shared libraries that .NET apps can load and interop with. Libraries aren't allowed to set thread context to a location with an instruction pointer that's not present on the shadow stack or in a table of allowed continuation addresses for exception handling.
Previous behavior
Previously, shared libraries loaded into the .NET process were able to set thread context using SetThreadContext, RtlRestoreContext/NtContinue
, or their exception handlers to any location in the process address space.
New behavior
Starting in .NET 9, shared libraries loaded into the .NET process are only allowed to set thread context using SetThreadContext, RtlRestoreContext/NtContinue
, or their exception handlers to locations that are either:
- Present on the shadow stack.
- In a table of allowed continuation addresses for exception handling (generated by the
/EHCONT
compiler option or theSetProcessDynamicEHContinuationTargets
API).
If libraries try to change a thread context to any other location, the process is terminated.
Version introduced
.NET 9 Preview 6
Type of breaking change
This change can affect binary compatibility.
Reason for change
Enabling CET enhances the security of .NET applications by adding hardware-enforced stack protection against return-oriented programming (ROP) exploits.
Recommended action
Workarounds:
- You can opt out of CET by adding
<CETCompat>false</CETCompat>
to your app's project file (for example, .csproj file). - Use the Windows Security app or a group policy to opt out of the hardware-supported stack enforcement for the specific .NET application. For more information, see Enable exploit protection.
Affected APIs
- N/A