]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/commitdiff
4.9-stable patches
authorGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 16 Mar 2018 12:50:11 +0000 (13:50 +0100)
committerGreg Kroah-Hartman <gregkh@linuxfoundation.org>
Fri, 16 Mar 2018 12:50:11 +0000 (13:50 +0100)
added patches:
x86-module-detect-and-skip-invalid-relocations.patch
x86-treat-r_x86_64_plt32-as-r_x86_64_pc32.patch

queue-4.9/series
queue-4.9/x86-module-detect-and-skip-invalid-relocations.patch [new file with mode: 0644]
queue-4.9/x86-treat-r_x86_64_plt32-as-r_x86_64_pc32.patch [new file with mode: 0644]

index f89315a3ecbe87d0d53700c4aedcad3ed84a7a06..9b833c89c780788073db3e2c11d055597e17147a 100644 (file)
@@ -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 (file)
index 0000000..7b2a936
--- /dev/null
@@ -0,0 +1,75 @@
+From eda9cec4c9a12208a6f69fbe68f72a6311d50032 Mon Sep 17 00:00:00 2001
+From: Josh Poimboeuf <jpoimboe@redhat.com>
+Date: Fri, 3 Nov 2017 07:58:54 -0500
+Subject: x86/module: Detect and skip invalid relocations
+
+From: Josh Poimboeuf <jpoimboe@redhat.com>
+
+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 <jpoimboe@redhat.com>
+Cc: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Peter Zijlstra <peterz@infradead.org>
+Cc: Thomas Gleixner <tglx@linutronix.de>
+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 <mingo@kernel.org>
+Cc: Matthias Kaehlcke <mka@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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 (file)
index 0000000..72f2993
--- /dev/null
@@ -0,0 +1,88 @@
+From b21ebf2fb4cde1618915a97cc773e287ff49173e Mon Sep 17 00:00:00 2001
+From: "H.J. Lu" <hjl.tools@gmail.com>
+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 <hjl.tools@gmail.com>
+
+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 <hjl.tools@gmail.com>
+Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
+Cc: Matthias Kaehlcke <mka@chromium.org>
+Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
+
+---
+ 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);