[PATCH RFC 35/43] x86/pie: Build the kernel as PIE

From: Hou Wenlong
Date: Fri Apr 28 2023 - 06:02:39 EST


The kernel is currently build with mcmode=kernel option which forces it
to stay on the top 2G of the virtual address space. For PIE, use -fPIE
option to build the kernel as a Position Independent Executable (PIE),
which uses RIP-relative addressing and could be able to move below the
top 2G.

The --emit-relocs linker option was kept instead of using -pie to limit
the impact on mapped sections. Any incompatible relocation will be catch
by the objtool at compile time.

Suggested-by: Lai Jiangshan <jiangshan.ljs@xxxxxxxxxxxx>
Signed-off-by: Hou Wenlong <houwenlong.hwl@xxxxxxxxxxxx>
Cc: Thomas Garnier <thgarnie@xxxxxxxxxxxx>
Cc: Kees Cook <keescook@xxxxxxxxxxxx>
---
arch/x86/Kconfig | 8 ++++++--
arch/x86/Makefile | 9 +++++++--
2 files changed, 13 insertions(+), 4 deletions(-)

diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index 5ac5f335855e..9f8020991184 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -2222,10 +2222,14 @@ config RELOCATABLE
(CONFIG_PHYSICAL_START) is used as the minimum location.

config X86_PIE
- def_bool n
- depends on X86_64
+ bool "Build a PIE kernel"
+ default n
+ depends on X86_64 && !XEN
select OBJTOOL if HAVE_OBJTOOL
select DYNAMIC_FTRACE if FUNCTION_TRACER && RETPOLINE
+ help
+ This builds a PIE kernel image that could be put at any
+ virtual address.

config RANDOMIZE_BASE
bool "Randomize the address of the kernel image (KASLR)"
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 81500011396d..6631974e2003 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -160,10 +160,15 @@ else
KBUILD_CFLAGS += -mno-red-zone

ifdef CONFIG_X86_PIE
- PIE_CFLAGS := -include $(srctree)/include/linux/hidden.h
+ PIE_CFLAGS := -fPIE -include $(srctree)/include/linux/hidden.h
KBUILD_CFLAGS += $(PIE_CFLAGS)
-endif
+ # Relax relocation in both CFLAGS and LDFLAGS to support older compilers
+ KBUILD_CFLAGS += $(call cc-option,-Wa$(comma)-mrelax-relocations=no)
+ LDFLAGS_vmlinux += $(call ld-option,--no-relax)
+ KBUILD_LDFLAGS_MODULE += $(call ld-option,--no-relax)
+else
KBUILD_CFLAGS += -mcmodel=kernel
+endif
KBUILD_RUSTFLAGS += -Cno-redzone=y
KBUILD_RUSTFLAGS += -Ccode-model=kernel

--
2.31.1