Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

objtool: Add action to check for absence of absolute relocations

The x86 startup code must not use absolute references to code or data,
as it executes before the kernel virtual mapping is up.

Add an action to objtool to check all allocatable sections (with the
exception of __patchable_function_entries, which uses absolute
references for nebulous reasons) and raise an error if any absolute
references are found.

Note that debug sections typically contain lots of absolute references
too, but those are not allocatable so they will be ignored.

Signed-off-by: Ard Biesheuvel <ardb@kernel.org>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Acked-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://lore.kernel.org/20250828102202.1849035-39-ardb+git@google.com

authored by

Ard Biesheuvel and committed by
Borislav Petkov (AMD)
0d6e4563 05ce314b

+60
+12
tools/objtool/arch/x86/decode.c
··· 880 880 return 8; 881 881 } 882 882 } 883 + 884 + bool arch_absolute_reloc(struct elf *elf, struct reloc *reloc) 885 + { 886 + switch (reloc_type(reloc)) { 887 + case R_X86_64_32: 888 + case R_X86_64_32S: 889 + case R_X86_64_64: 890 + return true; 891 + default: 892 + return false; 893 + } 894 + }
+2
tools/objtool/builtin-check.c
··· 87 87 OPT_BOOLEAN('t', "static-call", &opts.static_call, "annotate static calls"), 88 88 OPT_BOOLEAN('u', "uaccess", &opts.uaccess, "validate uaccess rules for SMAP"), 89 89 OPT_BOOLEAN(0 , "cfi", &opts.cfi, "annotate kernel control flow integrity (kCFI) function preambles"), 90 + OPT_BOOLEAN(0 , "noabs", &opts.noabs, "reject absolute references in allocatable sections"), 90 91 OPT_CALLBACK_OPTARG(0, "dump", NULL, NULL, "orc", "dump metadata", parse_dump), 91 92 92 93 OPT_GROUP("Options:"), ··· 163 162 opts.hack_noinstr || 164 163 opts.ibt || 165 164 opts.mcount || 165 + opts.noabs || 166 166 opts.noinstr || 167 167 opts.orc || 168 168 opts.retpoline ||
+44
tools/objtool/check.c
··· 4644 4644 disas_funcs(funcs); 4645 4645 } 4646 4646 4647 + __weak bool arch_absolute_reloc(struct elf *elf, struct reloc *reloc) 4648 + { 4649 + unsigned int type = reloc_type(reloc); 4650 + size_t sz = elf_addr_size(elf); 4651 + 4652 + return (sz == 8) ? (type == R_ABS64) : (type == R_ABS32); 4653 + } 4654 + 4655 + static int check_abs_references(struct objtool_file *file) 4656 + { 4657 + struct section *sec; 4658 + struct reloc *reloc; 4659 + int ret = 0; 4660 + 4661 + for_each_sec(file, sec) { 4662 + /* absolute references in non-loadable sections are fine */ 4663 + if (!(sec->sh.sh_flags & SHF_ALLOC)) 4664 + continue; 4665 + 4666 + /* section must have an associated .rela section */ 4667 + if (!sec->rsec) 4668 + continue; 4669 + 4670 + /* 4671 + * Special case for compiler generated metadata that is not 4672 + * consumed until after boot. 4673 + */ 4674 + if (!strcmp(sec->name, "__patchable_function_entries")) 4675 + continue; 4676 + 4677 + for_each_reloc(sec->rsec, reloc) { 4678 + if (arch_absolute_reloc(file->elf, reloc)) { 4679 + WARN("section %s has absolute relocation at offset 0x%lx", 4680 + sec->name, reloc_offset(reloc)); 4681 + ret++; 4682 + } 4683 + } 4684 + } 4685 + return ret; 4686 + } 4687 + 4647 4688 struct insn_chunk { 4648 4689 void *addr; 4649 4690 struct insn_chunk *next; ··· 4817 4776 if (ret) 4818 4777 goto out; 4819 4778 } 4779 + 4780 + if (opts.noabs) 4781 + warnings += check_abs_references(file); 4820 4782 4821 4783 if (opts.orc && nr_insns) { 4822 4784 ret = orc_create(file);
+1
tools/objtool/include/objtool/arch.h
··· 97 97 int arch_rewrite_retpolines(struct objtool_file *file); 98 98 99 99 bool arch_pc_relative_reloc(struct reloc *reloc); 100 + bool arch_absolute_reloc(struct elf *elf, struct reloc *reloc); 100 101 101 102 unsigned int arch_reloc_size(struct reloc *reloc); 102 103 unsigned long arch_jump_table_sym_offset(struct reloc *reloc, struct reloc *table);
+1
tools/objtool/include/objtool/builtin.h
··· 26 26 bool uaccess; 27 27 int prefix; 28 28 bool cfi; 29 + bool noabs; 29 30 30 31 /* options: */ 31 32 bool backtrace;