aboutsummaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/module.c
diff options
context:
space:
mode:
authorArd Biesheuvel <ardb@kernel.org>2025-01-23 14:07:38 -0500
committerIngo Molnar <mingo@kernel.org>2025-02-18 10:15:05 +0100
commit78c4374ef8b842c6abf195d6f963853c7ec464d2 (patch)
tree189d6478e12933789e896952192cf2225550e7d3 /arch/x86/kernel/module.c
parentx86/relocs: Handle R_X86_64_REX_GOTPCRELX relocations (diff)
downloadlinux-78c4374ef8b842c6abf195d6f963853c7ec464d2.tar.gz
linux-78c4374ef8b842c6abf195d6f963853c7ec464d2.zip
x86/module: Deal with GOT based stack cookie load on Clang < 17
Clang versions before 17 will not honour -fdirect-access-external-data for the load of the stack cookie emitted into each function's prologue and epilogue. This is not an issue for the core kernel, as the linker will relax these loads into LEA instructions that take the address of __stack_chk_guard directly. For modules, however, we need to work around this, by dealing with R_X86_64_REX_GOTPCRELX relocations that refer to __stack_chk_guard. In this case, given that this is a GOT load, the reference should not refer to __stack_chk_guard directly, but to a memory location that holds its address. So take the address of __stack_chk_guard into a static variable, and fix up the relocations to refer to that. [ mingo: Fix broken R_X86_64_GOTPCRELX definition. ] Signed-off-by: Ard Biesheuvel <ardb@kernel.org> Signed-off-by: Brian Gerst <brgerst@gmail.com> Signed-off-by: Ingo Molnar <mingo@kernel.org> Cc: Linus Torvalds <torvalds@linux-foundation.org> Link: https://lore.kernel.org/r/20250123190747.745588-7-brgerst@gmail.com
Diffstat (limited to 'arch/x86/kernel/module.c')
-rw-r--r--arch/x86/kernel/module.c15
1 files changed, 15 insertions, 0 deletions
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index 8984abd91c00..a286f32c5503 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -19,6 +19,7 @@
#include <linux/jump_label.h>
#include <linux/random.h>
#include <linux/memory.h>
+#include <linux/stackprotector.h>
#include <asm/text-patching.h>
#include <asm/page.h>
@@ -130,6 +131,20 @@ static int __write_relocate_add(Elf64_Shdr *sechdrs,
goto overflow;
size = 4;
break;
+#if defined(CONFIG_STACKPROTECTOR) && \
+ defined(CONFIG_CC_IS_CLANG) && CONFIG_CLANG_VERSION < 170000
+ case R_X86_64_REX_GOTPCRELX: {
+ static unsigned long __percpu *const addr = &__stack_chk_guard;
+
+ if (sym->st_value != (u64)addr) {
+ pr_err("%s: Unsupported GOTPCREL relocation\n", me->name);
+ return -ENOEXEC;
+ }
+
+ val = (u64)&addr + rel[i].r_addend;
+ fallthrough;
+ }
+#endif
case R_X86_64_PC32:
case R_X86_64_PLT32:
val -= (u64)loc;