Build 32bit x86 compressed kernels as PIE (rhbz 1302071)
This commit is contained in:
parent
59c51515fb
commit
5e92138405
|
@ -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 <jforbes@fedoraproject.org> - 4.5.2-301
|
||||
- Build 32bit x86 compressed kernels as PIE (rhbz 1302071)
|
||||
|
||||
* Wed Apr 20 2016 Laura Abbott <labbott@fedoraproject.org>
|
||||
- Allow antenna selection for rtl8723be (rhbz 1309487)
|
||||
|
||||
|
|
|
@ -0,0 +1,159 @@
|
|||
From 6d92bc9d483aa1751755a66fee8fb39dffb088c0 Mon Sep 17 00:00:00 2001
|
||||
From: "H.J. Lu" <hjl.tools@gmail.com>
|
||||
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 <hjl.tools@gmail.com>
|
||||
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 <hjl.tools@gmail.com>
|
||||
Cc: Andy Lutomirski <luto@amacapital.net>
|
||||
Cc: Borislav Petkov <bp@alien8.de>
|
||||
Cc: Brian Gerst <brgerst@gmail.com>
|
||||
Cc: Denys Vlasenko <dvlasenk@redhat.com>
|
||||
Cc: H. Peter Anvin <hpa@zytor.com>
|
||||
Cc: Linus Torvalds <torvalds@linux-foundation.org>
|
||||
Cc: Peter Zijlstra <peterz@infradead.org>
|
||||
Cc: Thomas Gleixner <tglx@linutronix.de>
|
||||
Cc: linux-kernel@vger.kernel.org
|
||||
[ Edited the changelog and comments. ]
|
||||
Signed-off-by: Ingo Molnar <mingo@kernel.org>
|
||||
---
|
||||
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 <asm/asm-offsets.h>
|
||||
#include <asm/bootparam.h>
|
||||
|
||||
+/*
|
||||
+ * 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 <asm/asm-offsets.h>
|
||||
#include <asm/bootparam.h>
|
||||
|
||||
+/*
|
||||
+ * Locally defined symbols should be marked hidden:
|
||||
+ */
|
||||
+ .hidden _bss
|
||||
+ .hidden _ebss
|
||||
+ .hidden _got
|
||||
+ .hidden _egot
|
||||
+
|
||||
__HEAD
|
||||
.code32
|
||||
ENTRY(startup_32)
|
||||
--
|
||||
2.7.3
|
||||
|
Loading…
Reference in New Issue