This series is a follow-up to a series I sent a bit more than a year ago, to switch to PIE linking of x86_64 vmlinux, which is a prerequisite for further hardening measures, such as fg-kaslr [1], as well as further harmonization of the boot protocols between architectures [2].
The main sticking point is the fact that PIE linking on x86_64 requires PIE codegen, and that was shot down before on the basis that a) GOTs in fully linked binaries are stupid b) the code size increase would be prohibitive c) the performance would suffer. This series implements PIE codegen without permitting the use of GOT slots. The code size increase is between 0.2% (clang) and 0.5% (gcc), and I could not identify any performance regressions (using hackbench) on various different micro-architectures that I tried it on. (Suggestions for other benchmarks/test cases are welcome) So now that we have some actual numbers, I would like to try and revisit this discussion, and get a conclusion on whether this is really a non-starter. Note that only the KASLR kernel would rely on this, and disabling CONFIG_RANDOMIZE_BASE will revert to the current situation (provided that patch #4 is applied) Some minor asm tweaks are needed too (patches #9 - #17), but those all seem uncontroversial to me. The first 5 patches are general cleanup, and could be taken into consideration independently of the discussion around PIC codegen. [1] There have been a few attempts at landing fine grained KASLR for x86, but the main problem is that it was tied to the x86 relocation format, which deviates from how fully linked relocatable ELF binaries are generally constructed (using PIE). Implementing fgkaslr in the ELF domain would make it suitable for other architectures too, as well as other use cases (bare metal or hosted) where no dynamic linking is performed (firmware, hypervisors). In order to implement this properly, i.e., with debugging support etc, it needs support from the tooling side. (Fine grained KASLR in combination with execute-only code mappings makes it extremely difficult for an attacker to subvert the control flow in the kernel in a way that can be meaningfully exploited). [2] EFI zboot is already used by various architectures that have no decompressor stage at all (arm64, RISC-V, LoongArch), and this format can be combined with an ELF payload too. EFI zboot accommodates non-EFI boot chains by describing the size, offset, payload type and compression type in its header, so that it can be extracted and booted by other means. Cc: Thomas Gleixner <[email protected]> Cc: Ingo Molnar <[email protected]> Cc: Borislav Petkov <[email protected]> Cc: Dave Hansen <[email protected]> Cc: "H. Peter Anvin" <[email protected]> Cc: Josh Poimboeuf <[email protected]> Cc: Peter Zijlstra <[email protected]> Cc: Kees Cook <[email protected]> Cc: Uros Bizjak <[email protected]> Cc: Brian Gerst <[email protected]> Cc: [email protected] Ard Biesheuvel (19): x86/idt: Move idt_table to __ro_after_init section x86/sev: Don't emit BSS_DECRYPT section unless it is in use x86: Combine .data with .bss in kernel mapping x86: Make the 64-bit bzImage always physically relocatable x86/efistub: Simplify early remapping of kernel text alloc_tag: Use __ prefixed ELF section names tools/objtool: Treat indirect ftrace calls as direct calls x86: Use PIE codegen for the relocatable 64-bit kernel x86/pm-trace: Use RIP-relative accesses for .tracedata x86/kvm: Use RIP-relative addressing x86/rethook: Use RIP-relative reference for fake return address x86/sync_core: Use RIP-relative addressing x86/entry_64: Use RIP-relative addressing x86/hibernate: Prefer RIP-relative accesses x64/acpi: Use PIC-compatible references in wakeup_64.S x86/kexec: Use 64-bit wide absolute reference from relocated code x86/head64: Avoid absolute references in startup asm x86/boot: Implement support for RELA/RELR/REL runtime relocations x86/kernel: Switch to PIE linking for the relocatable kernel arch/x86/Kconfig | 45 ++++--- arch/x86/Makefile | 24 +++- arch/x86/boot/Makefile | 1 + arch/x86/boot/compressed/Makefile | 2 +- arch/x86/boot/compressed/head_64.S | 4 - arch/x86/boot/compressed/misc.c | 85 +++++++++++-- arch/x86/boot/header.S | 8 +- arch/x86/entry/calling.h | 9 +- arch/x86/entry/entry_64.S | 14 +-- arch/x86/entry/vdso/Makefile | 1 + arch/x86/include/asm/boot.h | 2 - arch/x86/include/asm/pm-trace.h | 4 +- arch/x86/include/asm/sync_core.h | 3 +- arch/x86/kernel/acpi/wakeup_64.S | 11 +- arch/x86/kernel/head_64.S | 17 +-- arch/x86/kernel/idt.c | 5 +- arch/x86/kernel/kvm.c | 5 +- arch/x86/kernel/relocate_kernel_64.S | 2 +- arch/x86/kernel/rethook.c | 6 +- arch/x86/kernel/vmlinux.lds.S | 132 ++++++++++++-------- arch/x86/mm/init_64.c | 5 +- arch/x86/mm/pat/set_memory.c | 2 +- arch/x86/power/hibernate_asm_64.S | 4 +- arch/x86/realmode/rm/Makefile | 1 + drivers/base/power/trace.c | 6 +- drivers/firmware/efi/libstub/x86-stub.c | 4 +- include/asm-generic/codetag.lds.h | 14 ++- include/asm-generic/vmlinux.lds.h | 1 + include/linux/alloc_tag.h | 11 +- include/linux/hidden.h | 2 + include/uapi/linux/elf.h | 3 + lib/alloc_tag.c | 6 +- tools/objtool/check.c | 32 ++++- 33 files changed, 315 insertions(+), 156 deletions(-) base-commit: 8f0b4cce4481fb22653697cced8d0d04027cb1e8 -- 2.47.3
