You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Control Flow Guard is a security mitigation that verifies the
target address of indirect calls. It works by having the compiler insert
instrumentation code at indirect call sites, and also the linker write the
necessary data and flags into the PE/COFF image to enable the feature on
Windows' end.
Existing Support in LLVM
In LLVM, Clang already knows how to insert the CFGuard instrumentation code
and LLD is able to produce CFGuard data, like how MSVC does it. 12
Conveniently, these work the same when targeting mingw-w64 given the proper
compiler and linker flags. They however assume certain symbols to be available
in order to work, and mingw-w64 does not provide them yet. For example, if
you try to compile a source file into an x86_64 EXE with -Xclang -cfguard,
you may get this:
To be compatible with MSVC, Clang expects the symbol __guard_dispatch_icall_fptr
on x86_64, and __guard_check_icall_fptr on x86, arm and aarch64. In addition,
LLD uses the contents of the _load_config_used symbol as the load config
directory, which contains CFGuard support flags and data pointers.
Using with mingw-w64
If we are fine with reusing these existing support in LLVM as-is, here is
what we need to do:
Add the symbols __guard_check_icall_fptr and __guard_dispatch_icall_fptr
along with the corresponding placeholder functions (to be used when running
with CFGuard disabled or unavailable).
Provide a default _load_config_used data structure which LLD will use
as the load config directory, and fill its fields with the LLD-provided
symbols needed for CFGuard.
Compile all included libraries (e.g. mingw-w64-*, compiler-rt, libc++)
with CFGuard enabled. This means adding -Xclang -cfguard to compile flags
and -Wl,-Xlink,-guard:cf to link flags.
Users will still need to opt into enabling CFGuard by passing the same compile
flags and link flags. For users who does not enable CFGuard, this setup does
add a small amount of bloat:
Every indirect calls in the included libraries get an overhead of several
instructions and a far call.
All images linked with LLD will include the default load config directory,
which may add a couple hundred bytes to the image.
What About GCC and Binutils?
As far as I can tell, there is zero support for CFGuard in GCC and Binutils.
These changes should not affect a GCC-based mingw-w64 toolchain.
The text was updated successfully, but these errors were encountered:
Control Flow Guard is a security mitigation that verifies the
target address of indirect calls. It works by having the compiler insert
instrumentation code at indirect call sites, and also the linker write the
necessary data and flags into the PE/COFF image to enable the feature on
Windows' end.
Existing Support in LLVM
In LLVM, Clang already knows how to insert the CFGuard instrumentation code
and LLD is able to produce CFGuard data, like how MSVC does it. 1 2
Conveniently, these work the same when targeting mingw-w64 given the proper
compiler and linker flags. They however assume certain symbols to be available
in order to work, and mingw-w64 does not provide them yet. For example, if
you try to compile a source file into an x86_64 EXE with
-Xclang -cfguard
,you may get this:
To be compatible with MSVC, Clang expects the symbol
__guard_dispatch_icall_fptr
on x86_64, and
__guard_check_icall_fptr
on x86, arm and aarch64. In addition,LLD uses the contents of the
_load_config_used
symbol as the load configdirectory, which contains CFGuard support flags and data pointers.
Using with mingw-w64
If we are fine with reusing these existing support in LLVM as-is, here is
what we need to do:
__guard_check_icall_fptr
and__guard_dispatch_icall_fptr
along with the corresponding placeholder functions (to be used when running
with CFGuard disabled or unavailable).
_load_config_used
data structure which LLD will useas the load config directory, and fill its fields with the LLD-provided
symbols needed for CFGuard.
mingw-w64-*
,compiler-rt
,libc++
)with CFGuard enabled. This means adding
-Xclang -cfguard
to compile flagsand
-Wl,-Xlink,-guard:cf
to link flags.Users will still need to opt into enabling CFGuard by passing the same compile
flags and link flags. For users who does not enable CFGuard, this setup does
add a small amount of bloat:
instructions and a far call.
which may add a couple hundred bytes to the image.
What About GCC and Binutils?
As far as I can tell, there is zero support for CFGuard in GCC and Binutils.
These changes should not affect a GCC-based mingw-w64 toolchain.
The text was updated successfully, but these errors were encountered: