All of lore.kernel.org
 help / color / mirror / Atom feed
From: Masami Hiramatsu <mhiramat@kernel.org>
To: Ingo Molnar <mingo@kernel.org>
Cc: Ingo Molnar <mingo@redhat.com>,
	Steven Rostedt <rostedt@goodmis.org>,
	Ravi Bangoria <ravi.bangoria@linux.ibm.com>,
	Arnaldo Carvalho de Melo <acme@kernel.org>,
	Michael Rodin <michael@rodin.online>,
	linux-kernel@vger.kernel.org
Subject: Re: [BUGFIX PATCH -tip] kprobes/x86: Fix to copy RIP relative instruction correctly
Date: Tue, 4 Dec 2018 22:49:58 +0900	[thread overview]
Message-ID: <20181204224958.30d1080d4c4e795953e1588f@kernel.org> (raw)
In-Reply-To: <20181204081335.GB67285@gmail.com>

On Tue, 4 Dec 2018 09:13:35 +0100
Ingo Molnar <mingo@kernel.org> wrote:

> 
> * Masami Hiramatsu <mhiramat@kernel.org> wrote:
> 
> > 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);
> 
> I applied this, except that I unbroke the line: please ignore checkpatch 
> in such cases where the cure is worse than the disease ...

Thanks Ingo!

> 
> I.e. even if slightly over 80 cols, this is more readable:
> 
> 		ret = __copy_instruction(dest + len, src + len, real + len, &insn);

Got it.

BTW, this ugry "+ len" repeat would be avoided. I would better make a new inline
function to wrap it.


Thank you,

-- 
Masami Hiramatsu <mhiramat@kernel.org>

  reply	other threads:[~2018-12-04 13:50 UTC|newest]

Thread overview: 7+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
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 [this message]
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

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20181204224958.30d1080d4c4e795953e1588f@kernel.org \
    --to=mhiramat@kernel.org \
    --cc=acme@kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=michael@rodin.online \
    --cc=mingo@kernel.org \
    --cc=mingo@redhat.com \
    --cc=ravi.bangoria@linux.ibm.com \
    --cc=rostedt@goodmis.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
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.