diff --git a/kernel.spec b/kernel.spec index 8dbaa58..d2e3420 100644 --- a/kernel.spec +++ b/kernel.spec @@ -42,7 +42,7 @@ Summary: The Linux kernel # For non-released -rc kernels, this will be appended after the rcX and # gitX tags, so a 3 here would become part of release "0.rcX.gitX.3" # -%global baserelease 300 +%global baserelease 301 %global fedora_build %{baserelease} # base_sublevel is the kernel version we're starting with and patching @@ -647,6 +647,9 @@ Patch700: USB-usbip-fix-potential-out-of-bounds-write.patch #rhbz 1309487 Patch701: antenna_select.patch +#rhbz 1302071 +Patch702: x86-build-Build-compressed-x86-kernels-as-PIE.patch + # END OF PATCH DEFINITIONS %endif @@ -2168,6 +2171,9 @@ fi # # %changelog +* Thu Apr 21 2016 Justin M. Forbes - 4.5.2-301 +- Build 32bit x86 compressed kernels as PIE (rhbz 1302071) + * Wed Apr 20 2016 Laura Abbott - Allow antenna selection for rtl8723be (rhbz 1309487) diff --git a/x86-build-Build-compressed-x86-kernels-as-PIE.patch b/x86-build-Build-compressed-x86-kernels-as-PIE.patch new file mode 100644 index 0000000..064cb48 --- /dev/null +++ b/x86-build-Build-compressed-x86-kernels-as-PIE.patch @@ -0,0 +1,159 @@ +From 6d92bc9d483aa1751755a66fee8fb39dffb088c0 Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 16 Mar 2016 20:04:35 -0700 +Subject: [PATCH] x86/build: Build compressed x86 kernels as PIE + +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 +--- + 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(-) + +diff --git a/arch/x86/boot/compressed/Makefile b/arch/x86/boot/compressed/Makefile +index 6915ff2..8774cb2 100644 +--- a/arch/x86/boot/compressed/Makefile ++++ b/arch/x86/boot/compressed/Makefile +@@ -26,7 +26,7 @@ targets := vmlinux vmlinux.bin vmlinux.bin.gz vmlinux.bin.bz2 vmlinux.bin.lzma \ + 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 +@@ -40,6 +40,18 @@ GCOV_PROFILE := n + UBSAN_SANITIZE :=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 +diff --git a/arch/x86/boot/compressed/head_32.S b/arch/x86/boot/compressed/head_32.S +index 8ef964d..0256064 100644 +--- 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 +diff --git a/arch/x86/boot/compressed/head_64.S b/arch/x86/boot/compressed/head_64.S +index b0c0d16..86558a1 100644 +--- 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) +-- +2.7.3 +