From 87c482bdfa79f378297d92af49cdf265be199df5 Mon Sep 17 00:00:00 2001 From: Helge Deller Date: Fri, 8 Jul 2022 11:44:54 +0200 Subject: modules: Ensure natural alignment for .altinstructions and __bug_table sections In the kernel image vmlinux.lds.S linker scripts the .altinstructions and __bug_table sections are 4- or 8-byte aligned because they hold 32- and/or 64-bit values. Most architectures use altinstructions and BUG() or WARN() in modules as well, but in the module linker script (module.lds.S) those sections are currently missing. As consequence the linker will store their content byte-aligned by default, which then can lead to unnecessary unaligned memory accesses by the CPU when those tables are processed at runtime. Usually unaligned memory accesses are unnoticed, because either the hardware (as on x86 CPUs) or in-kernel exception handlers (e.g. on parisc or sparc) emulate and fix them up at runtime. Nevertheless, such unaligned accesses introduce a performance penalty and can even crash the kernel if there is a bug in the unalignment exception handlers (which happened once to me on the parisc architecture and which is why I noticed that issue at all). This patch fixes a non-critical issue and might be backported at any time. It's trivial and shouldn't introduce any regression because it simply tells the linker to use a different (8-byte alignment) for those sections by default. Signed-off-by: Helge Deller Link: https://lore.kernel.org/all/Yr8%2Fgr8e8I7tVX4d@p100/ Signed-off-by: Luis Chamberlain --- scripts/module.lds.S | 2 ++ 1 file changed, 2 insertions(+) (limited to 'scripts/module.lds.S') diff --git a/scripts/module.lds.S b/scripts/module.lds.S index 1d0e1e4dc3d2..3a3aa2354ed8 100644 --- a/scripts/module.lds.S +++ b/scripts/module.lds.S @@ -27,6 +27,8 @@ SECTIONS { .ctors 0 : ALIGN(8) { *(SORT(.ctors.*)) *(.ctors) } .init_array 0 : ALIGN(8) { *(SORT(.init_array.*)) *(.init_array) } + .altinstructions 0 : ALIGN(8) { KEEP(*(.altinstructions)) } + __bug_table 0 : ALIGN(8) { KEEP(*(__bug_table)) } __jump_table 0 : ALIGN(8) { KEEP(*(__jump_table)) } __patchable_function_entries : { *(__patchable_function_entries) } -- cgit From 89245600941e4e0f87d77f60ee269b5e61ef4e49 Mon Sep 17 00:00:00 2001 From: Sami Tolvanen Date: Thu, 8 Sep 2022 14:54:47 -0700 Subject: cfi: Switch to -fsanitize=kcfi Switch from Clang's original forward-edge control-flow integrity implementation to -fsanitize=kcfi, which is better suited for the kernel, as it doesn't require LTO, doesn't use a jump table that requires altering function references, and won't break cross-module function address equality. Signed-off-by: Sami Tolvanen Reviewed-by: Kees Cook Tested-by: Kees Cook Tested-by: Nathan Chancellor Acked-by: Peter Zijlstra (Intel) Tested-by: Peter Zijlstra (Intel) Signed-off-by: Kees Cook Link: https://lore.kernel.org/r/20220908215504.3686827-6-samitolvanen@google.com --- scripts/module.lds.S | 23 ++++------------------- 1 file changed, 4 insertions(+), 19 deletions(-) (limited to 'scripts/module.lds.S') diff --git a/scripts/module.lds.S b/scripts/module.lds.S index 3a3aa2354ed8..da4bddd26171 100644 --- a/scripts/module.lds.S +++ b/scripts/module.lds.S @@ -3,20 +3,10 @@ * Archs are free to supply their own linker scripts. ld will * combine them automatically. */ -#ifdef CONFIG_CFI_CLANG -# include -# define ALIGN_CFI ALIGN(PAGE_SIZE) -# define SANITIZER_DISCARDS *(.eh_frame) -#else -# define ALIGN_CFI -# define SANITIZER_DISCARDS -#endif - SECTIONS { /DISCARD/ : { *(.discard) *(.discard.*) - SANITIZER_DISCARDS } __ksymtab 0 : { *(SORT(___ksymtab+*)) } @@ -33,6 +23,10 @@ SECTIONS { __patchable_function_entries : { *(__patchable_function_entries) } +#ifdef CONFIG_ARCH_USES_CFI_TRAPS + __kcfi_traps : { KEEP(*(.kcfi_traps)) } +#endif + #ifdef CONFIG_LTO_CLANG /* * With CONFIG_LTO_CLANG, LLD always enables -fdata-sections and @@ -53,15 +47,6 @@ SECTIONS { *(.rodata .rodata.[0-9a-zA-Z_]*) *(.rodata..L*) } - - /* - * With CONFIG_CFI_CLANG, we assume __cfi_check is at the beginning - * of the .text section, and is aligned to PAGE_SIZE. - */ - .text : ALIGN_CFI { - *(.text.__cfi_check) - *(.text .text.[0-9a-zA-Z_]* .text..L.cfi*) - } #endif } -- cgit