From: Greg Kroah-Hartman Date: Fri, 16 Mar 2018 12:50:11 +0000 (+0100) Subject: 4.9-stable patches X-Git-Tag: v3.18.100~13 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=7a6c93a7045ba40d8fb677acae687b0a2abb7a56;p=thirdparty%2Fkernel%2Fstable-queue.git 4.9-stable patches added patches: x86-module-detect-and-skip-invalid-relocations.patch x86-treat-r_x86_64_plt32-as-r_x86_64_pc32.patch --- diff --git a/queue-4.9/series b/queue-4.9/series index f89315a3ecb..9b833c89c78 100644 --- a/queue-4.9/series +++ b/queue-4.9/series @@ -66,3 +66,5 @@ ubi-fix-race-condition-between-ubi-volume-creation-and-udev.patch scsi-qla2xxx-replace-fcport-alloc-with-qla2x00_alloc_fcport.patch nfs-fix-an-incorrect-type-in-struct-nfs_direct_req.patch nfs-fix-unstable-write-completion.patch +x86-module-detect-and-skip-invalid-relocations.patch +x86-treat-r_x86_64_plt32-as-r_x86_64_pc32.patch diff --git a/queue-4.9/x86-module-detect-and-skip-invalid-relocations.patch b/queue-4.9/x86-module-detect-and-skip-invalid-relocations.patch new file mode 100644 index 00000000000..7b2a9368d48 --- /dev/null +++ b/queue-4.9/x86-module-detect-and-skip-invalid-relocations.patch @@ -0,0 +1,75 @@ +From eda9cec4c9a12208a6f69fbe68f72a6311d50032 Mon Sep 17 00:00:00 2001 +From: Josh Poimboeuf +Date: Fri, 3 Nov 2017 07:58:54 -0500 +Subject: x86/module: Detect and skip invalid relocations + +From: Josh Poimboeuf + +commit eda9cec4c9a12208a6f69fbe68f72a6311d50032 upstream. + +There have been some cases where external tooling (e.g., kpatch-build) +creates a corrupt relocation which targets the wrong address. This is a +silent failure which can corrupt memory in unexpected places. + +On x86, the bytes of data being overwritten by relocations are always +initialized to zero beforehand. Use that knowledge to add sanity checks +to detect such cases before they corrupt memory. + +Signed-off-by: Josh Poimboeuf +Cc: Linus Torvalds +Cc: Peter Zijlstra +Cc: Thomas Gleixner +Cc: jeyu@kernel.org +Cc: live-patching@vger.kernel.org +Link: http://lkml.kernel.org/r/37450d6c6225e54db107fba447ce9e56e5f758e9.1509713553.git.jpoimboe@redhat.com +[ Restructured the messages, as it's unclear whether the relocation or the target is corrupted. ] +Signed-off-by: Ingo Molnar +Cc: Matthias Kaehlcke +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/module.c | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +--- a/arch/x86/kernel/module.c ++++ b/arch/x86/kernel/module.c +@@ -171,19 +171,27 @@ int apply_relocate_add(Elf64_Shdr *sechd + case R_X86_64_NONE: + break; + case R_X86_64_64: ++ if (*(u64 *)loc != 0) ++ goto invalid_relocation; + *(u64 *)loc = val; + break; + case R_X86_64_32: ++ if (*(u32 *)loc != 0) ++ goto invalid_relocation; + *(u32 *)loc = val; + if (val != *(u32 *)loc) + goto overflow; + break; + case R_X86_64_32S: ++ if (*(s32 *)loc != 0) ++ goto invalid_relocation; + *(s32 *)loc = val; + if ((s64)val != *(s32 *)loc) + goto overflow; + break; + case R_X86_64_PC32: ++ if (*(u32 *)loc != 0) ++ goto invalid_relocation; + val -= (u64)loc; + *(u32 *)loc = val; + #if 0 +@@ -199,6 +207,11 @@ int apply_relocate_add(Elf64_Shdr *sechd + } + return 0; + ++invalid_relocation: ++ pr_err("x86/modules: Skipping invalid relocation target, existing value is nonzero for type %d, loc %p, val %Lx\n", ++ (int)ELF64_R_TYPE(rel[i].r_info), loc, val); ++ return -ENOEXEC; ++ + overflow: + pr_err("overflow in relocation type %d val %Lx\n", + (int)ELF64_R_TYPE(rel[i].r_info), val); diff --git a/queue-4.9/x86-treat-r_x86_64_plt32-as-r_x86_64_pc32.patch b/queue-4.9/x86-treat-r_x86_64_plt32-as-r_x86_64_pc32.patch new file mode 100644 index 00000000000..72f29934559 --- /dev/null +++ b/queue-4.9/x86-treat-r_x86_64_plt32-as-r_x86_64_pc32.patch @@ -0,0 +1,88 @@ +From b21ebf2fb4cde1618915a97cc773e287ff49173e Mon Sep 17 00:00:00 2001 +From: "H.J. Lu" +Date: Wed, 7 Feb 2018 14:20:09 -0800 +Subject: x86: Treat R_X86_64_PLT32 as R_X86_64_PC32 + +From: H.J. Lu + +commit b21ebf2fb4cde1618915a97cc773e287ff49173e upstream. + +On i386, there are 2 types of PLTs, PIC and non-PIC. PIE and shared +objects must use PIC PLT. To use PIC PLT, you need to load +_GLOBAL_OFFSET_TABLE_ into EBX first. There is no need for that on +x86-64 since x86-64 uses PC-relative PLT. + +On x86-64, for 32-bit PC-relative branches, we can generate PLT32 +relocation, instead of PC32 relocation, which can also be used as +a marker for 32-bit PC-relative branches. Linker can always reduce +PLT32 relocation to PC32 if function is defined locally. Local +functions should use PC32 relocation. As far as Linux kernel is +concerned, R_X86_64_PLT32 can be treated the same as R_X86_64_PC32 +since Linux kernel doesn't use PLT. + +R_X86_64_PLT32 for 32-bit PC-relative branches has been enabled in +binutils master branch which will become binutils 2.31. + +[ hjl is working on having better documentation on this all, but a few + more notes from him: + + "PLT32 relocation is used as marker for PC-relative branches. Because + of EBX, it looks odd to generate PLT32 relocation on i386 when EBX + doesn't have GOT. + + As for symbol resolution, PLT32 and PC32 relocations are almost + interchangeable. But when linker sees PLT32 relocation against a + protected symbol, it can resolved locally at link-time since it is + used on a branch instruction. Linker can't do that for PC32 + relocation" + + but for the kernel use, the two are basically the same, and this + commit gets things building and working with the current binutils + master - Linus ] + +Signed-off-by: H.J. Lu +Signed-off-by: Linus Torvalds +Cc: Matthias Kaehlcke +Signed-off-by: Greg Kroah-Hartman + +--- + arch/x86/kernel/machine_kexec_64.c | 1 + + arch/x86/kernel/module.c | 1 + + arch/x86/tools/relocs.c | 3 +++ + 3 files changed, 5 insertions(+) + +--- a/arch/x86/kernel/machine_kexec_64.c ++++ b/arch/x86/kernel/machine_kexec_64.c +@@ -524,6 +524,7 @@ int arch_kexec_apply_relocations_add(con + goto overflow; + break; + case R_X86_64_PC32: ++ case R_X86_64_PLT32: + value -= (u64)address; + *(u32 *)location = value; + break; +--- a/arch/x86/kernel/module.c ++++ b/arch/x86/kernel/module.c +@@ -190,6 +190,7 @@ int apply_relocate_add(Elf64_Shdr *sechd + goto overflow; + break; + case R_X86_64_PC32: ++ case R_X86_64_PLT32: + if (*(u32 *)loc != 0) + goto invalid_relocation; + val -= (u64)loc; +--- a/arch/x86/tools/relocs.c ++++ b/arch/x86/tools/relocs.c +@@ -769,9 +769,12 @@ static int do_reloc64(struct section *se + break; + + case R_X86_64_PC32: ++ case R_X86_64_PLT32: + /* + * PC relative relocations don't need to be adjusted unless + * referencing a percpu symbol. ++ * ++ * NB: R_X86_64_PLT32 can be treated as R_X86_64_PC32. + */ + if (is_percpu_sym(sym, symname)) + add_reloc(&relocs32neg, offset);