https://gcc.gnu.org/bugzilla/show_bug.cgi?id=128373
Bug ID: 128373
Summary: i386: -fcf-protection=check defines __CET__=8 and
causes <cet.h> to emit a zero-valued
GNU_PROPERTY_X86_FEATURE_1_AND note
Product: gcc
Version: 16.2.0
Status: UNCONFIRMED
Severity: normal
Priority: P3
Component: target
Assignee: unassigned at gcc dot gnu.org
Reporter: 220245569 at seu dot edu.cn
CC: 220255623 at seu dot edu.cn, jianhao.xu at seu dot edu.cn
Target Milestone: ---
Target: x86_64-*-* i?86-*-*
Reproducer
----------
$ cat trigger.S
#include <cet.h>
.text
.globl func
.type func, @function
func:
_CET_ENDBR
ret
Compile flag: x86_64-linux-gnu-gcc -O2 -fcf-protection=check -c trigger.S -o
trigger.o
$ x86_64-linux-gnu-gcc -O2 -fcf-protection=check -dM -E trigger.S | grep
__CET__
#define __CET__ 8
$ readelf -n trigger.o
Displaying notes found in: .note.gnu.property
Owner Data size Description
GNU 0x00000010 NT_GNU_PROPERTY_TYPE_0
Properties: x86 feature: <None>
Root cause
----------
The manual documents that -fcf-protection=check "is ignored at the compile
time." However, ix86_target_macros (gcc/config/i386/i386-c.cc:976-977)
defines __CET__ whenever flag_cf_protection != CF_NONE:
if (flag_cf_protection != CF_NONE)
cpp_define_formatted (parse_in, "__CET__=%d", flag_cf_protection &
~CF_SET);
Under -fcf-protection=check, flag_cf_protection is CF_CHECK | CF_SET (8 | 4),
so __CET__ is defined as 8 even though neither IBT (1) nor SHSTK (2) is
enabled. Assembly files including <cet.h> (gcc/config/i386/cet.h:45-89)
therefore enter #ifdef __CET__ and emit a .note.gnu.property section with
GNU_PROPERTY_X86_FEATURE_1_AND = 0x0 (whereas
file_end_indicate_exec_stack_and_cet
in gnu-property.cc:78 only emits the property when feature_1 != 0).
Suggested Fix
-------------
In ix86_target_macros (gcc/config/i386/i386-c.cc:976-977), only define
__CET__ when CF_BRANCH or CF_RETURN is set:
if (flag_cf_protection & (CF_BRANCH | CF_RETURN))
cpp_define_formatted (parse_in, "__CET__=%d",
flag_cf_protection & (CF_BRANCH | CF_RETURN));