~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/arch/x86/include/asm/ibt.h

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.9 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

  1 /* SPDX-License-Identifier: GPL-2.0 */
  2 #ifndef _ASM_X86_IBT_H
  3 #define _ASM_X86_IBT_H
  4 
  5 #include <linux/types.h>
  6 
  7 /*
  8  * The rules for enabling IBT are:
  9  *
 10  *  - CC_HAS_IBT:         the toolchain supports it
 11  *  - X86_KERNEL_IBT:     it is selected in Kconfig
 12  *  - !__DISABLE_EXPORTS: this is regular kernel code
 13  *
 14  * Esp. that latter one is a bit non-obvious, but some code like compressed,
 15  * purgatory, realmode etc.. is built with custom CFLAGS that do not include
 16  * -fcf-protection=branch and things will go *bang*.
 17  *
 18  * When all the above are satisfied, HAS_KERNEL_IBT will be 1, otherwise 0.
 19  */
 20 #if defined(CONFIG_X86_KERNEL_IBT) && !defined(__DISABLE_EXPORTS)
 21 
 22 #define HAS_KERNEL_IBT  1
 23 
 24 #ifndef __ASSEMBLY__
 25 
 26 #ifdef CONFIG_X86_64
 27 #define ASM_ENDBR       "endbr64\n\t"
 28 #else
 29 #define ASM_ENDBR       "endbr32\n\t"
 30 #endif
 31 
 32 #define __noendbr       __attribute__((nocf_check))
 33 
 34 /*
 35  * Create a dummy function pointer reference to prevent objtool from marking
 36  * the function as needing to be "sealed" (i.e. ENDBR converted to NOP by
 37  * apply_seal_endbr()).
 38  */
 39 #define IBT_NOSEAL(fname)                               \
 40         ".pushsection .discard.ibt_endbr_noseal\n\t"    \
 41         _ASM_PTR fname "\n\t"                           \
 42         ".popsection\n\t"
 43 
 44 static inline __attribute_const__ u32 gen_endbr(void)
 45 {
 46         u32 endbr;
 47 
 48         /*
 49          * Generate ENDBR64 in a way that is sure to not result in
 50          * an ENDBR64 instruction as immediate.
 51          */
 52         asm ( "mov $~0xfa1e0ff3, %[endbr]\n\t"
 53               "not %[endbr]\n\t"
 54                : [endbr] "=&r" (endbr) );
 55 
 56         return endbr;
 57 }
 58 
 59 static inline __attribute_const__ u32 gen_endbr_poison(void)
 60 {
 61         /*
 62          * 4 byte NOP that isn't NOP4 (in fact it is OSP NOP3), such that it
 63          * will be unique to (former) ENDBR sites.
 64          */
 65         return 0x001f0f66; /* osp nopl (%rax) */
 66 }
 67 
 68 static inline bool is_endbr(u32 val)
 69 {
 70         if (val == gen_endbr_poison())
 71                 return true;
 72 
 73         val &= ~0x01000000U; /* ENDBR32 -> ENDBR64 */
 74         return val == gen_endbr();
 75 }
 76 
 77 extern __noendbr u64 ibt_save(bool disable);
 78 extern __noendbr void ibt_restore(u64 save);
 79 
 80 #else /* __ASSEMBLY__ */
 81 
 82 #ifdef CONFIG_X86_64
 83 #define ENDBR   endbr64
 84 #else
 85 #define ENDBR   endbr32
 86 #endif
 87 
 88 #endif /* __ASSEMBLY__ */
 89 
 90 #else /* !IBT */
 91 
 92 #define HAS_KERNEL_IBT  0
 93 
 94 #ifndef __ASSEMBLY__
 95 
 96 #define ASM_ENDBR
 97 #define IBT_NOSEAL(name)
 98 
 99 #define __noendbr
100 
101 static inline bool is_endbr(u32 val) { return false; }
102 
103 static inline u64 ibt_save(bool disable) { return 0; }
104 static inline void ibt_restore(u64 save) { }
105 
106 #else /* __ASSEMBLY__ */
107 
108 #define ENDBR
109 
110 #endif /* __ASSEMBLY__ */
111 
112 #endif /* CONFIG_X86_KERNEL_IBT */
113 
114 #define ENDBR_INSN_SIZE         (4*HAS_KERNEL_IBT)
115 
116 #endif /* _ASM_X86_IBT_H */
117 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php