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));

Reply via email to