diff options
| author | Ard Biesheuvel <ardb@kernel.org> | 2025-01-23 14:07:38 -0500 |
|---|---|---|
| committer | Ingo Molnar <mingo@kernel.org> | 2025-02-18 10:15:05 +0100 |
| commit | 78c4374ef8b842c6abf195d6f963853c7ec464d2 (patch) | |
| tree | 189d6478e12933789e896952192cf2225550e7d3 /arch/x86/kernel/module.c | |
| parent | x86/relocs: Handle R_X86_64_REX_GOTPCRELX relocations (diff) | |
| download | linux-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.c | 15 |
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; |
