diff options
Diffstat (limited to 'common/recipes-kernel/linux/linux-yocto-4.9.21/0002-x86-module-Detect-and-skip-invalid-relocations.patch')
-rw-r--r-- | common/recipes-kernel/linux/linux-yocto-4.9.21/0002-x86-module-Detect-and-skip-invalid-relocations.patch | 77 |
1 files changed, 77 insertions, 0 deletions
diff --git a/common/recipes-kernel/linux/linux-yocto-4.9.21/0002-x86-module-Detect-and-skip-invalid-relocations.patch b/common/recipes-kernel/linux/linux-yocto-4.9.21/0002-x86-module-Detect-and-skip-invalid-relocations.patch new file mode 100644 index 00000000..3035344f --- /dev/null +++ b/common/recipes-kernel/linux/linux-yocto-4.9.21/0002-x86-module-Detect-and-skip-invalid-relocations.patch @@ -0,0 +1,77 @@ +From 23f4b6492ade30e2f7fc21acfb162e46851cf0f0 Mon Sep 17 00:00:00 2001 +From: Josh Poimboeuf <jpoimboe@redhat.com> +Date: Fri, 3 Nov 2017 07:58:54 -0500 +Subject: [PATCH 02/93] x86/module: Detect and skip invalid relocations + +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(+) + +diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c +index 477ae80..87f30a8 100644 +--- a/arch/x86/kernel/module.c ++++ b/arch/x86/kernel/module.c +@@ -171,19 +171,27 @@ int apply_relocate_add(Elf64_Shdr *sechdrs, + 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 *sechdrs, + } + 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); +-- +2.7.4 + |