https://gcc.gnu.org/bugzilla/show_bug.cgi?id=102953
Bug ID: 102953
Summary: Improvements to CET-IBT and ENDBR generation
Product: gcc
Version: unknown
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: c
Assignee: unassigned at gcc dot gnu.org
Reporter: andrew.cooper3 at citrix dot com
Target Milestone: ---
Hello,
With CET-IBT, ENDBR{32,64} instructions are used to mark legitimate forward
edges for indirect branches.
GCC can generate a CET-IBT binary with -fcf-protection, but the default
behaviour is to generate ENDBR instructions for every function. This creates
more "legal" forward edges than necessary in the eyes of CET-IBT.
https://godbolt.org/z/M15rjMb4G is almost excellent, but it would be far more
helpful if all functions were implicitly nocf_check, so this example produces a
diagnostic. That way, GCC can point out all functions used by function
pointers, rather than the result compiling and failing to be CET-IBT
compatible.
This on its own would be enough to let embedded projects minimise their ENDBR*
count while having some compiler assistance while doing so.
More generally, a lot of common cases (e.g. Linux) could be computed
automatically. Drivers filling in ops structures typically refer to local
symbols, so these defaulting to cf_check would be an improvement still. This
would leave only global symbols needing explicit cf_check. (Maybe LTO could
even figure out the global symbols cases correctly?)
Finally, one minor code generation improvement. When GCC emits a direct
call/jmp to an ENDBR'd symbol, it can actually use sym+4 as an optimisation to
skip the ENDBR instruction (not needed for direct call/jmp's) and save on
decode bandwidth.