All of lore.kernel.org
 help / color / mirror / Atom feed
* [BUGFIX PATCH -tip] kprobes/x86: Fix to copy RIP relative instruction correctly
@ 2018-08-23 17:16 Masami Hiramatsu
  2018-08-24  1:41 ` Steven Rostedt
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Masami Hiramatsu @ 2018-08-23 17:16 UTC (permalink / raw)
  To: Ingo Molnar
  Cc: Steven Rostedt, Masami Hiramatsu, Ravi Bangoria,
	Arnaldo Carvalho de Melo, Michael Rodin, linux-kernel

Since copy_optimized_instructions() misses to update real RIP
address while copying several instructions to working buffer,
it adjusts RIP-relative instruction with wrong RIP address for
the 2nd and subsequent instructions.

This may break the kernel (like kernel freeze) because
probed instruction can refer a wrong data. For example,
putting kprobes on cpumask_next hit this bug.

cpumask_next is normally like below if CONFIG_CPUMASK_OFFSTACK=y
(in this case nr_cpumask_bits is an alias of nr_cpu_ids)

 <cpumask_next>:
       48 89 f0                mov    %rsi,%rax
       8b 35 7b fb e2 00       mov    0xe2fb7b(%rip),%esi
        # ffffffff82db9e64 <nr_cpu_ids>
       55                      push   %rbp
...

If we put a kprobe on it and optimized with jump, it becomes
like this.

	e9 95 7d 07 1e	jmpq   0xffffffffa000207a
	7b fb	jnp    0xffffffff81f8a2e2 <cpumask_next+2>
	e2 00	loop   0xffffffff81f8a2e9 <cpumask_next+9>
	55	push   %rbp

This shows first 2 "mov" instructions are copied to trampoline
buffer at 0xffffffffa000207a. Here is the disassembled result.
(skipped optprobe template instructions)

Dump of assembler code from 0xffffffffa000207a to 0xffffffffa00020ea:
	54	push   %rsp
...
	48 83 c4 08	add    $0x8,%rsp
	9d	popfq
	48 89 f0	mov    %rsi,%rax
	8b 35 82 7d db e2	mov    -0x1d24827e(%rip),%esi
        # 0xffffffff82db9e67 <nr_cpu_ids+3>

As it shows, the 2nd mov accesses *(nr_cpu_ids+3) instead of
*nr_cpu_ids. This leads a kernel freeze because cpumask_next()
always returns 0 and for_each_cpu() never ended.

Fixing this by adding len correctly to real RIP address while
copying.

Fixes: 63fef14fc98a ("kprobes/x86: Make insn buffer always ROX and use text_poke()")
Reported-by: Michael Rodin <michael@rodin.online>
Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
Cc: stable@vger.kernel.org
---
 arch/x86/kernel/kprobes/opt.c |    3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/arch/x86/kernel/kprobes/opt.c b/arch/x86/kernel/kprobes/opt.c
index eaf02f2e7300..e92672b8b490 100644
--- a/arch/x86/kernel/kprobes/opt.c
+++ b/arch/x86/kernel/kprobes/opt.c
@@ -189,7 +189,8 @@ static int copy_optimized_instructions(u8 *dest, u8 *src, u8 *real)
 	int len = 0, ret;
 
 	while (len < RELATIVEJUMP_SIZE) {
-		ret = __copy_instruction(dest + len, src + len, real, &insn);
+		ret = __copy_instruction(dest + len, src + len, real + len,
+			&insn);
 		if (!ret || !can_boost(&insn, src + len))
 			return -EINVAL;
 		len += ret;


^ permalink raw reply related	[flat|nested] 7+ messages in thread

end of thread, other threads:[~2018-12-04 23:06 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2018-08-23 17:16 [BUGFIX PATCH -tip] kprobes/x86: Fix to copy RIP relative instruction correctly Masami Hiramatsu
2018-08-24  1:41 ` Steven Rostedt
2018-08-24  7:57   ` Masami Hiramatsu
2018-09-03  3:38     ` Masami Hiramatsu
2018-12-04  8:13 ` Ingo Molnar
2018-12-04 13:49   ` Masami Hiramatsu
2018-12-04 23:05 ` [tip:perf/urgent] kprobes/x86: Fix instruction patching corruption when copying more than one RIP-relative instruction tip-bot for Masami Hiramatsu

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.