public inbox for linux-kernel@vger.kernel.org
 help / color / mirror / Atom feed
From: Peter Zijlstra <peterz@infradead.org>
To: Andy Lutomirski <luto@amacapital.net>
Cc: Masami Hiramatsu <mhiramat@kernel.org>,
	x86@kernel.org, linux-kernel@vger.kernel.org,
	Ard Biesheuvel <ard.biesheuvel@linaro.org>,
	Andy Lutomirski <luto@kernel.org>,
	Steven Rostedt <rostedt@goodmis.org>,
	Ingo Molnar <mingo@kernel.org>,
	Thomas Gleixner <tglx@linutronix.de>,
	Linus Torvalds <torvalds@linux-foundation.org>,
	Jason Baron <jbaron@akamai.com>, Jiri Kosina <jkosina@suse.cz>,
	David Laight <David.Laight@aculab.com>,
	Borislav Petkov <bp@alien8.de>, Julia Cartwright <julia@ni.com>,
	Jessica Yu <jeyu@kernel.org>, "H. Peter Anvin" <hpa@zytor.com>,
	Nadav Amit <namit@vmware.com>,
	Rasmus Villemoes <linux@rasmusvillemoes.dk>,
	Edward Cree <ecree@solarflare.com>,
	Daniel Bristot de Oliveira <bristot@redhat.com>
Subject: Re: [PATCH 08/15] x86/alternatives: Teach text_poke_bp() to emulate instructions
Date: Tue, 11 Jun 2019 14:34:02 +0200	[thread overview]
Message-ID: <20190611123402.GH3463@hirez.programming.kicks-ass.net> (raw)
In-Reply-To: <20190611120834.GG3463@hirez.programming.kicks-ass.net>

On Tue, Jun 11, 2019 at 02:08:34PM +0200, Peter Zijlstra wrote:
> On Tue, Jun 11, 2019 at 10:03:07AM +0200, Peter Zijlstra wrote:
> > On Fri, Jun 07, 2019 at 11:10:19AM -0700, Andy Lutomirski wrote:
> 
> > > I am surely missing some kprobe context, but is it really safe to use
> > > this mechanism to replace more than one instruction?
> > 
> > I'm not entirely up-to-scratch here, so Masami, please correct me if I'm
> > wrong.
> > 
> > So what happens is that arch_prepare_optimized_kprobe() <-
> > copy_optimized_instructions() copies however much of the instruction
> > stream is required such that we can overwrite the instruction at @addr
> > with a 5 byte jump.
> > 
> > arch_optimize_kprobe() then does the text_poke_bp() that replaces the
> > instruction @addr with int3, copies the rel jump address and overwrites
> > the int3 with jmp.
> > 
> > And I'm thinking the problem is with something like:
> > 
> > @addr: nop nop nop nop nop
> > 
> > We copy out the nops into the trampoline, overwrite the first nop with
> > an INT3, overwrite the remaining nops with the rel addr, but oops,
> > another CPU can still be executing one of those NOPs, right?
> > 
> > I'm thinking we could fix this by first writing INT3 into all relevant
> > instructions, which is going to be messy, given the current code base.
> 
> Maybe not that bad; how's something like this?
> 
> (completely untested)
> 
> ---
>  arch/x86/kernel/alternative.c | 20 ++++++++++++++++++--
>  1 file changed, 18 insertions(+), 2 deletions(-)
> 
> diff --git a/arch/x86/kernel/alternative.c b/arch/x86/kernel/alternative.c
> index 0d57015114e7..8f643dabea72 100644
> --- a/arch/x86/kernel/alternative.c
> +++ b/arch/x86/kernel/alternative.c
> @@ -24,6 +24,7 @@
>  #include <asm/tlbflush.h>
>  #include <asm/io.h>
>  #include <asm/fixmap.h>
> +#include <asm/insn.h>
>  
>  int __read_mostly alternatives_patched;
>  
> @@ -849,6 +850,7 @@ static void do_sync_core(void *info)
>  
>  static bool bp_patching_in_progress;
>  static void *bp_int3_handler, *bp_int3_addr;
> +static unsigned int bp_int3_length;
>  
>  int poke_int3_handler(struct pt_regs *regs)
>  {
> @@ -867,7 +869,11 @@ int poke_int3_handler(struct pt_regs *regs)
>  	if (likely(!bp_patching_in_progress))
>  		return 0;
>  
> -	if (user_mode(regs) || regs->ip != (unsigned long)bp_int3_addr)
> +	if (user_mode(regs))
> +		return 0;
> +
> +	if (regs->ip < (unsigned long)bp_int3_addr ||
> +	    regs->ip >= (unsigned long)bp_int3_addr + bp_int3_length)
>  		return 0;

Bugger, this isn't right. It'll jump to the beginning of the trampoline,
even if it is multiple instructions in, which would lead to executing
instructions twice, which would be BAD.

_maybe_, depending on what the slot looks like, we could do something
like:

	offset = regs->ip - (unsigned long)bp_int3_addr;
	regs->ip = bp_int3_handler + offset;

That is; jump into the slot at the same offset we hit the INT3, but this
is quickly getting yuck.

>  	/* set up the specified breakpoint handler */
> @@ -900,9 +906,12 @@ NOKPROBE_SYMBOL(poke_int3_handler);
>  void text_poke_bp(void *addr, const void *opcode, size_t len, void *handler)
>  {
>  	unsigned char int3 = 0xcc;
> +	void *kaddr = addr;
> +	struct insn insn;
>  
>  	bp_int3_handler = handler;
>  	bp_int3_addr = (u8 *)addr + sizeof(int3);
> +	bp_int3_length = len - sizeof(int3);
>  	bp_patching_in_progress = true;
>  
>  	lockdep_assert_held(&text_mutex);
> @@ -913,7 +922,14 @@ void text_poke_bp(void *addr, const void *opcode, size_t len, void *handler)
>  	 */
>  	smp_wmb();
>  
> -	text_poke(addr, &int3, sizeof(int3));
> +	do {
> +		kernel_insn_init(&insn, kaddr, MAX_INSN_SIZE);
> +		insn_get_length(&insn);
> +
> +		text_poke(kaddr, &int3, sizeof(int3));
> +
> +		kaddr += insn.length;
> +	} while (kaddr < addr + len);
>  
>  	on_each_cpu(do_sync_core, NULL, 1);
>  

  reply	other threads:[~2019-06-11 12:34 UTC|newest]

Thread overview: 87+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-06-05 13:07 [PATCH 00/15] x86 cleanups and static_call() Peter Zijlstra
2019-06-05 13:07 ` [PATCH 01/15] x86/entry/32: Clean up return from interrupt preemption path Peter Zijlstra
2019-06-07 14:21   ` Josh Poimboeuf
2019-06-05 13:07 ` [PATCH 02/15] x86: Move ENCODE_FRAME_POINTER to asm/frame.h Peter Zijlstra
2019-06-07 14:24   ` Josh Poimboeuf
2019-06-05 13:07 ` [PATCH 03/15] x86/kprobes: Fix frame pointer annotations Peter Zijlstra
2019-06-07 13:02   ` Masami Hiramatsu
2019-06-07 13:36     ` Josh Poimboeuf
2019-06-07 15:21       ` Masami Hiramatsu
2019-06-11  8:12       ` Peter Zijlstra
2019-06-05 13:07 ` [PATCH 04/15] x86/ftrace: Add pt_regs frame annotations Peter Zijlstra
2019-06-07 14:45   ` Josh Poimboeuf
2019-06-05 13:07 ` [PATCH 05/15] x86_32: Provide consistent pt_regs Peter Zijlstra
2019-06-07 13:13   ` Masami Hiramatsu
2019-06-07 19:32   ` Josh Poimboeuf
2019-06-11  8:14     ` Peter Zijlstra
2019-06-05 13:07 ` [PATCH 06/15] x86_32: Allow int3_emulate_push() Peter Zijlstra
2019-06-05 13:08 ` [PATCH 07/15] x86: Add int3_emulate_call() selftest Peter Zijlstra
2019-06-10 16:52   ` Josh Poimboeuf
2019-06-10 16:57     ` Andy Lutomirski
2019-06-11  8:17       ` Peter Zijlstra
2019-06-05 13:08 ` [PATCH 08/15] x86/alternatives: Teach text_poke_bp() to emulate instructions Peter Zijlstra
2019-06-07  5:41   ` Nadav Amit
2019-06-07  8:20     ` Peter Zijlstra
2019-06-07 14:27       ` Masami Hiramatsu
2019-06-07 15:47   ` Masami Hiramatsu
2019-06-07 17:34     ` Peter Zijlstra
2019-06-07 17:48       ` Linus Torvalds
2019-06-11 10:44         ` Peter Zijlstra
2019-06-07 18:10       ` Andy Lutomirski
2019-06-07 20:22         ` hpa
2019-06-11  8:03         ` Peter Zijlstra
2019-06-11 12:08           ` Peter Zijlstra
2019-06-11 12:34             ` Peter Zijlstra [this message]
2019-06-11 12:42               ` Peter Zijlstra
2019-06-11 15:22           ` Steven Rostedt
2019-06-11 15:52             ` Steven Rostedt
2019-06-11 15:55             ` Peter Zijlstra
2019-06-12 19:44               ` Nadav Amit
2019-06-17 14:42                 ` Peter Zijlstra
2019-06-17 17:06                   ` Nadav Amit
2019-06-17 17:25                   ` Andy Lutomirski
2019-06-17 19:26                     ` Peter Zijlstra
2019-06-11 15:54           ` Andy Lutomirski
2019-06-11 16:11             ` Steven Rostedt
2019-06-17 14:31             ` Peter Zijlstra
2019-06-12 17:09       ` Peter Zijlstra
2019-06-10 16:57   ` Josh Poimboeuf
2019-06-11 15:14   ` Steven Rostedt
2019-06-11 15:52     ` Peter Zijlstra
2019-06-11 16:21       ` Peter Zijlstra
2019-06-12 14:44         ` Peter Zijlstra
2019-06-05 13:08 ` [PATCH 09/15] compiler.h: Make __ADDRESSABLE() symbol truly unique Peter Zijlstra
2019-06-05 13:08 ` [PATCH 10/15] static_call: Add basic static call infrastructure Peter Zijlstra
2019-06-06 22:44   ` Nadav Amit
2019-06-07  8:28     ` Peter Zijlstra
2019-06-07  8:49       ` Ard Biesheuvel
2019-06-07 16:33         ` Andy Lutomirski
2019-06-07 16:58         ` Nadav Amit
2019-10-02 13:54       ` Peter Zijlstra
2019-10-02 20:48         ` Josh Poimboeuf
2019-06-05 13:08 ` [PATCH 11/15] static_call: Add inline " Peter Zijlstra
2019-06-06 22:24   ` Nadav Amit
2019-06-07  8:37     ` Peter Zijlstra
2019-06-07 16:35       ` Nadav Amit
2019-06-07 17:41         ` Peter Zijlstra
2019-06-10 17:19       ` Josh Poimboeuf
2019-06-10 18:33         ` Nadav Amit
2019-06-10 18:42           ` Josh Poimboeuf
2019-10-01 12:00         ` Peter Zijlstra
2019-06-05 13:08 ` [PATCH 12/15] x86/static_call: Add out-of-line static call implementation Peter Zijlstra
2019-06-07  6:13   ` Nadav Amit
2019-06-07  7:51     ` Steven Rostedt
2019-06-07  8:38     ` Peter Zijlstra
2019-06-07  8:52       ` Peter Zijlstra
2019-06-05 13:08 ` [PATCH 13/15] x86/static_call: Add inline static call implementation for x86-64 Peter Zijlstra
2019-06-07  5:50   ` Nadav Amit
2019-06-10 18:33   ` Josh Poimboeuf
2019-06-10 18:45     ` Nadav Amit
2019-06-10 18:55       ` Josh Poimboeuf
2019-06-10 19:20         ` Nadav Amit
2019-10-01 14:43     ` Peter Zijlstra
2019-06-05 13:08 ` [PATCH 14/15] static_call: Simple self-test module Peter Zijlstra
2019-06-10 17:24   ` Josh Poimboeuf
2019-06-11  8:29     ` Peter Zijlstra
2019-06-11 13:02       ` Josh Poimboeuf
2019-06-05 13:08 ` [PATCH 15/15] tracepoints: Use static_call Peter Zijlstra

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=20190611123402.GH3463@hirez.programming.kicks-ass.net \
    --to=peterz@infradead.org \
    --cc=David.Laight@aculab.com \
    --cc=ard.biesheuvel@linaro.org \
    --cc=bp@alien8.de \
    --cc=bristot@redhat.com \
    --cc=ecree@solarflare.com \
    --cc=hpa@zytor.com \
    --cc=jbaron@akamai.com \
    --cc=jeyu@kernel.org \
    --cc=jkosina@suse.cz \
    --cc=julia@ni.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux@rasmusvillemoes.dk \
    --cc=luto@amacapital.net \
    --cc=luto@kernel.org \
    --cc=mhiramat@kernel.org \
    --cc=mingo@kernel.org \
    --cc=namit@vmware.com \
    --cc=rostedt@goodmis.org \
    --cc=tglx@linutronix.de \
    --cc=torvalds@linux-foundation.org \
    --cc=x86@kernel.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox