summaryrefslogtreecommitdiffstats
path: root/arch/x86/kernel/module.c
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2017-11-05 12:14:50 -0800
committerLinus Torvalds <torvalds@linux-foundation.org>2017-11-05 12:14:50 -0800
commit9b3499d752fc292f37503e5c3a5e5df4f7e76d42 (patch)
tree07f2c8c9d191be7b2b0ad836136be1ef753697fa /arch/x86/kernel/module.c
parentb21172cf6dc6e2af21346e774ea2e7c784de30bd (diff)
parenteda9cec4c9a12208a6f69fbe68f72a6311d50032 (diff)
downloadlinux-9b3499d752fc292f37503e5c3a5e5df4f7e76d42.tar.gz
linux-9b3499d752fc292f37503e5c3a5e5df4f7e76d42.tar.bz2
linux-9b3499d752fc292f37503e5c3a5e5df4f7e76d42.zip
Merge branch 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip
Pull x86 fixes from Ingo Molnar: "Two fixes: - A PCID related revert that fixes power management and performance regressions. - The module loader robustization and sanity check commit is rather fresh, but it looked like a good idea to apply because of the hidden data corruption problem such invalid modules could cause" * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86/module: Detect and skip invalid relocations Revert "x86/mm: Stop calling leave_mm() in idle code"
Diffstat (limited to 'arch/x86/kernel/module.c')
-rw-r--r--arch/x86/kernel/module.c13
1 files changed, 13 insertions, 0 deletions
diff --git a/arch/x86/kernel/module.c b/arch/x86/kernel/module.c
index 62e7d70aadd5..da0c160e5589 100644
--- a/arch/x86/kernel/module.c
+++ b/arch/x86/kernel/module.c
@@ -172,19 +172,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
@@ -200,6 +208,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);