"H.J. Lu" hjl.tools@gmail.com writes:
Intel Control-flow Enforcement Technology (CET):
https://software.intel.com/en-us/articles/intel-sdm
contains shadow stack (SHSTK) and indirect branch tracking (IBT). When CET is enabled, ELF object files must be marked with .note.gnu.property section. Also when IBT is enabled, all indirect branch targets must start with ENDBR instruction.
This patch adds X86_ENDBR and the CET marker to config.m4.in when CET is enabled. It updates PROLOGUE with X86_ENDBR.
I'd like to have a look at what gcc produces. How is it enabled with gcc? In the docs, I find
-mshstk
The -mshstk option enables shadow stack built-in functions from x86 Control-flow Enforcement Technology (CET).
but when I try compiling a trivial function,
$ cat foo-cet.c int foo(void) {return 0;} $ gcc -save-temps -c -mshstk foo-cet.c
I get no endbr instruction and no note in the foo-cet.s. I'm using gcc-8.3. I do get an
.section .note.GNU-stack,"",@progbits
corresponding to Nettle's ASM_MARK_NOEXEC_STACK
--- a/config.m4.in +++ b/config.m4.in @@ -8,6 +8,10 @@ define(<ALIGN_LOG>, <@ASM_ALIGN_LOG@>)dnl define(<W64_ABI>, <@W64_ABI@>)dnl define(<RODATA>, <@ASM_RODATA@>)dnl define(<WORDS_BIGENDIAN>, <@ASM_WORDS_BIGENDIAN@>)dnl +define(<X86_ENDBR>,<@X86_ENDBR@>)dnl +divert(1) +@X86_GNU_PROPERTY@ +divert divert(1) @ASM_MARK_NOEXEC_STACK@ divert
You can put the two properties in the same m4 divert. Also, please rename the autoconf substitutions with ASM_ prefix, and something more descriptive than X64_GNU_PROPERTY. E.g., ASM_X86_ENDBR and ASM_X86_MARK_CET.
diff --git a/configure.ac b/configure.ac index ba3ab7c6..e9ed630c 100644 --- a/configure.ac +++ b/configure.ac @@ -803,6 +803,82 @@ EOF ASM_ALIGN_LOG="$nettle_cv_asm_align_log" fi
+dnl Define +dnl 1. X86_ENDBR for endbr32/endbr64. +dnl 2. X86_GNU_PROPERTY to add a .note.gnu.property section to mark +dnl Intel CET support if needed. +dnl .section ".note.gnu.property", "a" +dnl .p2align POINTER-ALIGN +dnl .long 1f - 0f +dnl .long 4f - 1f +dnl .long 5 +dnl 0: +dnl .asciz "GNU" +dnl 1: +dnl .p2align POINTER-ALIGN +dnl .long 0xc0000002 +dnl .long 3f - 2f +dnl 2: +dnl .long 3 +dnl 3: +dnl .p2align POINTER-ALIGN +dnl 4:
No need to repeat the definition in full in this comment. And as I think I've said before, I'm a bit surprised that it needs to be this verbose.
+AC_CACHE_CHECK([if Intel CET is enabled],
- [nettle_cv_asm_x86_intel_cet],
- [AC_TRY_COMPILE([
+#ifndef __CET__ +#error Intel CET is not enabled +#endif
- ], [],
- [nettle_cv_asm_x86_intel_cet=yes],
- [nettle_cv_asm_x86_intel_cet=no])])
+if test "$nettle_cv_asm_x86_intel_cet" = yes; then
- case $ABI in
- 32|standard)
- X86_ENDBR=endbr32
- p2align=2
- ;;
- X86_ENDBR=endbr64
- p2align=3
- ;;
- x32)
- X86_ENDBR=endbr64
- p2align=2
- ;;
- esac
- AC_CACHE_CHECK([if .note.gnu.property section is needed],
- [nettle_cv_asm_x86_gnu_property],
- [AC_TRY_COMPILE([
+#if !defined __ELF__ || !defined __CET__ +#error GNU property is not needed +#endif
- ], [],
- [nettle_cv_asm_x86_gnu_property=yes],
- [nettle_cv_asm_x86_gnu_property=no])])
+else
- nettle_cv_asm_x86_gnu_property=no
+fi +if test "$nettle_cv_asm_x86_gnu_property" = yes; then
- X86_GNU_PROPERTY="
- .section ".note.gnu.property", "a"
- .p2align $p2align
- .long 1f - 0f
- .long 4f - 1f
- .long 5
+0:
- .asciz "GNU"
+1:
- .p2align $p2align
- .long 0xc0000002
- .long 3f - 2f
+2:
- .long 3
+3:
- .p2align $p2align
+4:" +fi
Maybe a bit easier to read if you use single quotes for X86_GNU_PROPERTY='...', don't escape the inner double quotes. That leaves the expansion of $p2align, maybe it's better to define a separate substituted variable for pointer alignment? (If there's no easier way to enforce pointer-alignment).
Regards, /Niels