From: Greg Kroah-Hartman Date: Tue, 18 Oct 2016 15:38:45 +0000 (+0200) Subject: 4.4-stable patches X-Git-Tag: v4.4.26~6 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=4e6b3d9223d716aa9064aba1f2ef8a32134084d2;p=thirdparty%2Fkernel%2Fstable-queue.git 4.4-stable patches added patches: x86-build-build-compressed-x86-kernels-as-pie.patch --- diff --git a/queue-4.4/series b/queue-4.4/series new file mode 100644 index 00000000000..a131addfdd0 --- /dev/null +++ b/queue-4.4/series @@ -0,0 +1 @@ +x86-build-build-compressed-x86-kernels-as-pie.patch diff --git a/queue-4.4/x86-build-build-compressed-x86-kernels-as-pie.patch b/queue-4.4/x86-build-build-compressed-x86-kernels-as-pie.patch new file mode 100644 index 00000000000..424f555e5af --- /dev/null +++ b/queue-4.4/x86-build-build-compressed-x86-kernels-as-pie.patch @@ -0,0 +1,157 @@ +From 6d92bc9d483aa1751755a66fee8fb39dffb088c0 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 16 Mar 2016 20:04:35 -0700 +Subject: x86/build: Build compressed x86 kernels as PIE + +From: H.J. Lu + +commit 6d92bc9d483aa1751755a66fee8fb39dffb088c0 upstream. + +The 32-bit x86 assembler in binutils 2.26 will generate R_386_GOT32X +relocation to get the symbol address in PIC. When the compressed x86 +kernel isn't built as PIC, the linker optimizes R_386_GOT32X relocations +to their fixed symbol addresses. However, when the compressed x86 +kernel is loaded at a different address, it leads to the following +load failure: + + Failed to allocate space for phdrs + +during the decompression stage. + +If the compressed x86 kernel is relocatable at run-time, it should be +compiled with -fPIE, instead of -fPIC, if possible and should be built as +Position Independent Executable (PIE) so that linker won't optimize +R_386_GOT32X relocation to its fixed symbol address. + +Older linkers generate R_386_32 relocations against locally defined +symbols, _bss, _ebss, _got and _egot, in PIE. It isn't wrong, just less +optimal than R_386_RELATIVE. But the x86 kernel fails to properly handle +R_386_32 relocations when relocating the kernel. To generate +R_386_RELATIVE relocations, we mark _bss, _ebss, _got and _egot as +hidden in both 32-bit and 64-bit x86 kernels. + +To build a 64-bit compressed x86 kernel as PIE, we need to disable the +relocation overflow check to avoid relocation overflow errors. We do +this with a new linker command-line option, -z noreloc-overflow, which +got added recently: + + commit 4c10bbaa0912742322f10d9d5bb630ba4e15dfa7 + Author: H.J. Lu + Date: Tue Mar 15 11:07:06 2016 -0700 + + Add -z noreloc-overflow option to x86-64 ld + + Add -z noreloc-overflow command-line option to the x86-64 ELF linker to + disable relocation overflow check. This can be used to avoid relocation + overflow check if there will be no dynamic relocation overflow at + run-time. + +The 64-bit compressed x86 kernel is built as PIE only if the linker supports +-z noreloc-overflow. So far 64-bit relocatable compressed x86 kernel +boots fine even when it is built as a normal executable. + +Signed-off-by: H.J. Lu +Cc: Andy Lutomirski +Cc: Borislav Petkov +Cc: Brian Gerst +Cc: Denys Vlasenko +Cc: H. Peter Anvin +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: linux-kernel@vger.kernel.org +[ Edited the changelog and comments. ] +Signed-off-by: Ingo Molnar +Cc: Paul Bolle +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/boot/compressed/Makefile | 14 +++++++++++++- + arch/x86/boot/compressed/head_32.S | 28 ++++++++++++++++++++++++++++ + arch/x86/boot/compressed/head_64.S | 8 ++++++++ + 3 files changed, 49 insertions(+), 1 deletion(-) + +--- a/arch/x86/boot/compressed/Makefile ++++ b/arch/x86/boot/compressed/Makefile +@@ -22,7 +22,7 @@ targets := vmlinux vmlinux.bin vmlinux.b + vmlinux.bin.xz vmlinux.bin.lzo vmlinux.bin.lz4 + + KBUILD_CFLAGS := -m$(BITS) -D__KERNEL__ $(LINUX_INCLUDE) -O2 +-KBUILD_CFLAGS += -fno-strict-aliasing -fPIC ++KBUILD_CFLAGS += -fno-strict-aliasing $(call cc-option, -fPIE, -fPIC) + KBUILD_CFLAGS += -DDISABLE_BRANCH_PROFILING + cflags-$(CONFIG_X86_32) := -march=i386 + cflags-$(CONFIG_X86_64) := -mcmodel=small +@@ -35,6 +35,18 @@ KBUILD_AFLAGS := $(KBUILD_CFLAGS) -D__A + GCOV_PROFILE := n + + LDFLAGS := -m elf_$(UTS_MACHINE) ++ifeq ($(CONFIG_RELOCATABLE),y) ++# If kernel is relocatable, build compressed kernel as PIE. ++ifeq ($(CONFIG_X86_32),y) ++LDFLAGS += $(call ld-option, -pie) $(call ld-option, --no-dynamic-linker) ++else ++# To build 64-bit compressed kernel as PIE, we disable relocation ++# overflow check to avoid relocation overflow error with a new linker ++# command-line option, -z noreloc-overflow. ++LDFLAGS += $(shell $(LD) --help 2>&1 | grep -q "\-z noreloc-overflow" \ ++ && echo "-z noreloc-overflow -pie --no-dynamic-linker") ++endif ++endif + LDFLAGS_vmlinux := -T + + hostprogs-y := mkpiggy +--- a/arch/x86/boot/compressed/head_32.S ++++ b/arch/x86/boot/compressed/head_32.S +@@ -31,6 +31,34 @@ + #include + #include + ++/* ++ * The 32-bit x86 assembler in binutils 2.26 will generate R_386_GOT32X ++ * relocation to get the symbol address in PIC. When the compressed x86 ++ * kernel isn't built as PIC, the linker optimizes R_386_GOT32X ++ * relocations to their fixed symbol addresses. However, when the ++ * compressed x86 kernel is loaded at a different address, it leads ++ * to the following load failure: ++ * ++ * Failed to allocate space for phdrs ++ * ++ * during the decompression stage. ++ * ++ * If the compressed x86 kernel is relocatable at run-time, it should be ++ * compiled with -fPIE, instead of -fPIC, if possible and should be built as ++ * Position Independent Executable (PIE) so that linker won't optimize ++ * R_386_GOT32X relocation to its fixed symbol address. Older ++ * linkers generate R_386_32 relocations against locally defined symbols, ++ * _bss, _ebss, _got and _egot, in PIE. It isn't wrong, just less ++ * optimal than R_386_RELATIVE. But the x86 kernel fails to properly handle ++ * R_386_32 relocations when relocating the kernel. To generate ++ * R_386_RELATIVE relocations, we mark _bss, _ebss, _got and _egot as ++ * hidden: ++ */ ++ .hidden _bss ++ .hidden _ebss ++ .hidden _got ++ .hidden _egot ++ + __HEAD + ENTRY(startup_32) + #ifdef CONFIG_EFI_STUB +--- a/arch/x86/boot/compressed/head_64.S ++++ b/arch/x86/boot/compressed/head_64.S +@@ -33,6 +33,14 @@ + #include + #include + ++/* ++ * Locally defined symbols should be marked hidden: ++ */ ++ .hidden _bss ++ .hidden _ebss ++ .hidden _got ++ .hidden _egot ++ + __HEAD + .code32 + ENTRY(startup_32)