diff options
Diffstat (limited to 'include/asm-generic')
-rw-r--r-- | include/asm-generic/bug.h | 16 | ||||
-rw-r--r-- | include/asm-generic/vmlinux.lds.h | 20 |
2 files changed, 35 insertions, 1 deletions
diff --git a/include/asm-generic/bug.h b/include/asm-generic/bug.h index 76a10e0dca9f..b402494883b6 100644 --- a/include/asm-generic/bug.h +++ b/include/asm-generic/bug.h @@ -241,6 +241,22 @@ void __warn(const char *file, int line, void *caller, unsigned taint, # define WARN_ON_SMP(x) ({0;}) #endif +/* + * WARN_ON_FUNCTION_MISMATCH() warns if a value doesn't match a + * function address, and can be useful for catching issues with + * callback functions, for example. + * + * With CONFIG_CFI_CLANG, the warning is disabled because the + * compiler replaces function addresses taken in C code with + * local jump table addresses, which breaks cross-module function + * address equality. + */ +#if defined(CONFIG_CFI_CLANG) && defined(CONFIG_MODULES) +# define WARN_ON_FUNCTION_MISMATCH(x, fn) ({ 0; }) +#else +# define WARN_ON_FUNCTION_MISMATCH(x, fn) WARN_ON_ONCE((x) != (fn)) +#endif + #endif /* __ASSEMBLY__ */ #endif diff --git a/include/asm-generic/vmlinux.lds.h b/include/asm-generic/vmlinux.lds.h index 0331d5d49551..40a9c101565e 100644 --- a/include/asm-generic/vmlinux.lds.h +++ b/include/asm-generic/vmlinux.lds.h @@ -544,6 +544,22 @@ . = ALIGN((align)); \ __end_rodata = .; + +/* + * .text..L.cfi.jumptable.* contain Control-Flow Integrity (CFI) + * jump table entries. + */ +#ifdef CONFIG_CFI_CLANG +#define TEXT_CFI_JT \ + . = ALIGN(PMD_SIZE); \ + __cfi_jt_start = .; \ + *(.text..L.cfi.jumptable .text..L.cfi.jumptable.*) \ + . = ALIGN(PMD_SIZE); \ + __cfi_jt_end = .; +#else +#define TEXT_CFI_JT +#endif + /* * Non-instrumentable text section */ @@ -570,6 +586,7 @@ NOINSTR_TEXT \ *(.text..refcount) \ *(.ref.text) \ + TEXT_CFI_JT \ MEM_KEEP(init.text*) \ MEM_KEEP(exit.text*) \ @@ -974,7 +991,8 @@ * keep any .init_array.* sections. * https://bugs.llvm.org/show_bug.cgi?id=46478 */ -#if defined(CONFIG_GCOV_KERNEL) || defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KCSAN) +#if defined(CONFIG_GCOV_KERNEL) || defined(CONFIG_KASAN_GENERIC) || defined(CONFIG_KCSAN) || \ + defined(CONFIG_CFI_CLANG) # ifdef CONFIG_CONSTRUCTORS # define SANITIZER_DISCARDS \ *(.eh_frame) |