]>
Commit | Line | Data |
---|---|---|
b74db2ac GKH |
1 | From 75013fb16f8484898eaa8d0b08fed942d790f029 Mon Sep 17 00:00:00 2001 |
2 | From: Masami Hiramatsu <mhiramat@kernel.org> | |
3 | Date: Wed, 1 Mar 2017 01:23:24 +0900 | |
4 | Subject: kprobes/x86: Fix kernel panic when certain exception-handling addresses are probed | |
5 | ||
6 | From: Masami Hiramatsu <mhiramat@kernel.org> | |
7 | ||
8 | commit 75013fb16f8484898eaa8d0b08fed942d790f029 upstream. | |
9 | ||
10 | Fix to the exception table entry check by using probed address | |
11 | instead of the address of copied instruction. | |
12 | ||
13 | This bug may cause unexpected kernel panic if user probe an address | |
14 | where an exception can happen which should be fixup by __ex_table | |
15 | (e.g. copy_from_user.) | |
16 | ||
17 | Unless user puts a kprobe on such address, this doesn't | |
18 | cause any problem. | |
19 | ||
20 | This bug has been introduced years ago, by commit: | |
21 | ||
22 | 464846888d9a ("x86/kprobes: Fix a bug which can modify kernel code permanently"). | |
23 | ||
24 | Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org> | |
25 | Cc: Borislav Petkov <bp@alien8.de> | |
26 | Cc: Linus Torvalds <torvalds@linux-foundation.org> | |
27 | Cc: Peter Zijlstra <peterz@infradead.org> | |
28 | Cc: Thomas Gleixner <tglx@linutronix.de> | |
29 | Fixes: 464846888d9a ("x86/kprobes: Fix a bug which can modify kernel code permanently") | |
30 | Link: http://lkml.kernel.org/r/148829899399.28855.12581062400757221722.stgit@devbox | |
31 | Signed-off-by: Ingo Molnar <mingo@kernel.org> | |
32 | Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> | |
33 | ||
34 | --- | |
35 | arch/x86/kernel/kprobes/common.h | 2 +- | |
36 | arch/x86/kernel/kprobes/core.c | 6 +++--- | |
37 | arch/x86/kernel/kprobes/opt.c | 2 +- | |
38 | 3 files changed, 5 insertions(+), 5 deletions(-) | |
39 | ||
40 | --- a/arch/x86/kernel/kprobes/common.h | |
41 | +++ b/arch/x86/kernel/kprobes/common.h | |
42 | @@ -67,7 +67,7 @@ | |
43 | #endif | |
44 | ||
45 | /* Ensure if the instruction can be boostable */ | |
46 | -extern int can_boost(kprobe_opcode_t *instruction); | |
47 | +extern int can_boost(kprobe_opcode_t *instruction, void *addr); | |
48 | /* Recover instruction if given address is probed */ | |
49 | extern unsigned long recover_probed_instruction(kprobe_opcode_t *buf, | |
50 | unsigned long addr); | |
51 | --- a/arch/x86/kernel/kprobes/core.c | |
52 | +++ b/arch/x86/kernel/kprobes/core.c | |
53 | @@ -166,12 +166,12 @@ NOKPROBE_SYMBOL(skip_prefixes); | |
54 | * Returns non-zero if opcode is boostable. | |
55 | * RIP relative instructions are adjusted at copying time in 64 bits mode | |
56 | */ | |
57 | -int can_boost(kprobe_opcode_t *opcodes) | |
58 | +int can_boost(kprobe_opcode_t *opcodes, void *addr) | |
59 | { | |
60 | kprobe_opcode_t opcode; | |
61 | kprobe_opcode_t *orig_opcodes = opcodes; | |
62 | ||
63 | - if (search_exception_tables((unsigned long)opcodes)) | |
64 | + if (search_exception_tables((unsigned long)addr)) | |
65 | return 0; /* Page fault may occur on this address. */ | |
66 | ||
67 | retry: | |
68 | @@ -416,7 +416,7 @@ static int arch_copy_kprobe(struct kprob | |
69 | * __copy_instruction can modify the displacement of the instruction, | |
70 | * but it doesn't affect boostable check. | |
71 | */ | |
72 | - if (can_boost(p->ainsn.insn)) | |
73 | + if (can_boost(p->ainsn.insn, p->addr)) | |
74 | p->ainsn.boostable = 0; | |
75 | else | |
76 | p->ainsn.boostable = -1; | |
77 | --- a/arch/x86/kernel/kprobes/opt.c | |
78 | +++ b/arch/x86/kernel/kprobes/opt.c | |
79 | @@ -178,7 +178,7 @@ static int copy_optimized_instructions(u | |
80 | ||
81 | while (len < RELATIVEJUMP_SIZE) { | |
82 | ret = __copy_instruction(dest + len, src + len); | |
83 | - if (!ret || !can_boost(dest + len)) | |
84 | + if (!ret || !can_boost(dest + len, src + len)) | |
85 | return -EINVAL; | |
86 | len += ret; | |
87 | } |