]> git.ipfire.org Git - thirdparty/kernel/stable-queue.git/blame - releases/4.4.140/kprobes-x86-do-not-modify-singlestep-buffer-while-resuming.patch
4.14-stable patches
[thirdparty/kernel/stable-queue.git] / releases / 4.4.140 / kprobes-x86-do-not-modify-singlestep-buffer-while-resuming.patch
CommitLineData
819edbe1
GKH
1From 804dec5bda9b4fcdab5f67fe61db4a0498af5221 Mon Sep 17 00:00:00 2001
2From: Masami Hiramatsu <mhiramat@kernel.org>
3Date: Wed, 29 Mar 2017 14:00:25 +0900
4Subject: kprobes/x86: Do not modify singlestep buffer while resuming
5
6From: Masami Hiramatsu <mhiramat@kernel.org>
7
8commit 804dec5bda9b4fcdab5f67fe61db4a0498af5221 upstream.
9
10Do not modify singlestep execution buffer (kprobe.ainsn.insn)
11while resuming from single-stepping, instead, modifies
12the buffer to add a jump back instruction at preparing
13buffer.
14
15Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
16Cc: Ananth N Mavinakayanahalli <ananth@linux.vnet.ibm.com>
17Cc: Andrey Ryabinin <aryabinin@virtuozzo.com>
18Cc: Anil S Keshavamurthy <anil.s.keshavamurthy@intel.com>
19Cc: Borislav Petkov <bp@alien8.de>
20Cc: Brian Gerst <brgerst@gmail.com>
21Cc: David S . Miller <davem@davemloft.net>
22Cc: Denys Vlasenko <dvlasenk@redhat.com>
23Cc: H. Peter Anvin <hpa@zytor.com>
24Cc: Josh Poimboeuf <jpoimboe@redhat.com>
25Cc: Linus Torvalds <torvalds@linux-foundation.org>
26Cc: Peter Zijlstra <peterz@infradead.org>
27Cc: Thomas Gleixner <tglx@linutronix.de>
28Cc: Ye Xiaolong <xiaolong.ye@intel.com>
29Link: http://lkml.kernel.org/r/149076361560.22469.1610155860343077495.stgit@devbox
30Signed-off-by: Ingo Molnar <mingo@kernel.org>
31Reviewed-by: "Steven Rostedt (VMware)" <rostedt@goodmis.org>
32Signed-off-by: Alexey Makhalov <amakhalov@vmware.com>
33Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
34---
35 arch/x86/kernel/kprobes/core.c | 42 +++++++++++++++++++----------------------
36 1 file changed, 20 insertions(+), 22 deletions(-)
37
38--- a/arch/x86/kernel/kprobes/core.c
39+++ b/arch/x86/kernel/kprobes/core.c
40@@ -411,25 +411,38 @@ void free_insn_page(void *page)
41 module_memfree(page);
42 }
43
44+/* Prepare reljump right after instruction to boost */
45+static void prepare_boost(struct kprobe *p, int length)
46+{
47+ if (can_boost(p->ainsn.insn, p->addr) &&
48+ MAX_INSN_SIZE - length >= RELATIVEJUMP_SIZE) {
49+ /*
50+ * These instructions can be executed directly if it
51+ * jumps back to correct address.
52+ */
53+ synthesize_reljump(p->ainsn.insn + length, p->addr + length);
54+ p->ainsn.boostable = 1;
55+ } else {
56+ p->ainsn.boostable = -1;
57+ }
58+}
59+
60 static int arch_copy_kprobe(struct kprobe *p)
61 {
62- int ret;
63+ int len;
64
65 set_memory_rw((unsigned long)p->ainsn.insn & PAGE_MASK, 1);
66
67 /* Copy an instruction with recovering if other optprobe modifies it.*/
68- ret = __copy_instruction(p->ainsn.insn, p->addr);
69- if (!ret)
70+ len = __copy_instruction(p->ainsn.insn, p->addr);
71+ if (!len)
72 return -EINVAL;
73
74 /*
75 * __copy_instruction can modify the displacement of the instruction,
76 * but it doesn't affect boostable check.
77 */
78- if (can_boost(p->ainsn.insn, p->addr))
79- p->ainsn.boostable = 0;
80- else
81- p->ainsn.boostable = -1;
82+ prepare_boost(p, len);
83
84 set_memory_ro((unsigned long)p->ainsn.insn & PAGE_MASK, 1);
85
86@@ -894,21 +907,6 @@ static void resume_execution(struct kpro
87 break;
88 }
89
90- if (p->ainsn.boostable == 0) {
91- if ((regs->ip > copy_ip) &&
92- (regs->ip - copy_ip) + 5 < MAX_INSN_SIZE) {
93- /*
94- * These instructions can be executed directly if it
95- * jumps back to correct address.
96- */
97- synthesize_reljump((void *)regs->ip,
98- (void *)orig_ip + (regs->ip - copy_ip));
99- p->ainsn.boostable = 1;
100- } else {
101- p->ainsn.boostable = -1;
102- }
103- }
104-
105 regs->ip += orig_ip - copy_ip;
106
107 no_change: