Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1421445 > unrolled thread

Re: [PATCH tip/master] [BUGFIX] kprobes/x86: Fix to clear TF bit in fault-on-single-stepping

Started bySteven Rostedt <rostedt@goodmis.org>
First post2016-06-14 01:20 +0200
Last post2016-06-14 12:00 +0200
Articles 4 — 3 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: [PATCH tip/master] [BUGFIX] kprobes/x86: Fix to clear TF bit in  fault-on-single-stepping Steven Rostedt <rostedt@goodmis.org> - 2016-06-14 01:20 +0200
    Re: [PATCH tip/master] [BUGFIX] kprobes/x86: Fix to clear TF bit in  fault-on-single-stepping Steven Rostedt <rostedt@goodmis.org> - 2016-06-14 01:30 +0200
      Re: [PATCH tip/master] [BUGFIX] kprobes/x86: Fix to clear TF bit in  fault-on-single-stepping Masami Hiramatsu <mhiramat@kernel.org> - 2016-06-14 03:30 +0200
      Re: [PATCH tip/master] [BUGFIX] kprobes/x86: Fix to clear TF bit in  fault-on-single-stepping Ingo Molnar <mingo@kernel.org> - 2016-06-14 12:00 +0200

#1421445 — Re: [PATCH tip/master] [BUGFIX] kprobes/x86: Fix to clear TF bit in fault-on-single-stepping

FromSteven Rostedt <rostedt@goodmis.org>
Date2016-06-14 01:20 +0200
SubjectRe: [PATCH tip/master] [BUGFIX] kprobes/x86: Fix to clear TF bit in fault-on-single-stepping
Message-ID<rJJjb-4NW-5@gated-at.bofh.it>
On Sat, 11 Jun 2016 23:06:53 +0900
Masami Hiramatsu <mhiramat@kernel.org> wrote:

> Fix kprobe_fault_handler to clear TF (trap flag) bit of
> flags register in the case of fault fixup on single-stepping.
> 
> If we put a kprobe on the instruction which can cause a
> page fault (e.g. actual mov instructions in copy_user_*),
> that fault happens on a single-stepping buffer. In this
> case, kprobes resets running instance so that the CPU can
> retry execution on the original ip address.
> However, current code forgets reset TF bit. Since this
> fault happens with TF bit set for enabling single-stepping,
> when it retries, it causes a debug exception and kprobes
> can not handle it because it already reset itself.
> 
> On the most of x86-64 platform, it can be easily reproduced
> by using kprobe tracer. E.g.
> 
>   # cd /sys/kernel/debug/tracing
>   # echo p copy_user_enhanced_fast_string+5 > kprobe_events
>   # echo 1 > events/kprobes/enable
> 
> And you'll see a kernel panic on do_debug(), since the debug
> trap is not handled by kprobes.
> 
> To fix this problem, we just need to clear the TF bit when
> resetting running kprobe.
> 

This should definitely be marked for stable, and I bisected it all the
way down to this commit: f4cb1cc18f364d "x86-64, copy_user: Remove zero
byte check before copy user buffer."

I reverted that commit and sure enough, this bug goes away. I'm not
saying the revert should be done. I'm just doing an FYI, and showing how
changes that appear to be a nice clean up can have subtle effects. I'm
not even sure how that change caused this to be a problem with kprobes.

The proper fix is this patch.

Acked-by: Steven Rostedt <rostedt@goodmis.org>

Please add:

Cc: stable@vger.kernel.org # v3.14+

-- Steve


> Signed-off-by: Masami Hiramatsu <mhiramat@kernel.org>
> ---
>  arch/x86/kernel/kprobes/core.c |    7 +++++++
>  1 file changed, 7 insertions(+)
> 
> diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
> index 38cf7a7..856df81 100644
> --- a/arch/x86/kernel/kprobes/core.c
> +++ b/arch/x86/kernel/kprobes/core.c
> @@ -961,6 +961,13 @@ int kprobe_fault_handler(struct pt_regs *regs, int trapnr)
>  		 * normal page fault.
>  		 */
>  		regs->ip = (unsigned long)cur->addr;
> +		/*
> +		 * Trap flag has been set here because this fault happened
> +		 * where the single stepping will be done. So clear it with
> +		 * resetting current kprobe.
> +		 */
> +		regs->flags &= ~X86_EFLAGS_TF;
> +		/* If the TF was set before the kprobe hit, don't touch it */
>  		regs->flags |= kcb->kprobe_old_flags;
>  		if (kcb->kprobe_status == KPROBE_REENTER)
>  			restore_previous_kprobe(kcb);

[toc] | [next] | [standalone]


#1421447

FromSteven Rostedt <rostedt@goodmis.org>
Date2016-06-14 01:30 +0200
Message-ID<rJJsR-4Sr-9@gated-at.bofh.it>
In reply to#1421445
On Mon, 13 Jun 2016 19:13:45 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:


> >   # cd /sys/kernel/debug/tracing
> >   # echo p copy_user_enhanced_fast_string+5 > kprobe_events
> >   # echo 1 > events/kprobes/enable
> > 
> > And you'll see a kernel panic on do_debug(), since the debug
> > trap is not handled by kprobes.
> > 
> > To fix this problem, we just need to clear the TF bit when
> > resetting running kprobe.
> >   
> 
> This should definitely be marked for stable, and I bisected it all the
> way down to this commit: f4cb1cc18f364d "x86-64, copy_user: Remove zero
> byte check before copy user buffer."
> 
> I reverted that commit and sure enough, this bug goes away. I'm not
> saying the revert should be done. I'm just doing an FYI, and showing how
> changes that appear to be a nice clean up can have subtle effects. I'm
> not even sure how that change caused this to be a problem with kprobes.
> 

Nevermind, reverting that commit only moved the location of the
"rep movsb" that you were placing the kprobe on. When I do:

  echo "p copy_user_enhanced_fast_string+9" > kprobe_events

I get the same result.

That means we need to make that stable tag even earlier.

-- Steve

[toc] | [prev] | [next] | [standalone]


#1421483

FromMasami Hiramatsu <mhiramat@kernel.org>
Date2016-06-14 03:30 +0200
Message-ID<rJLkZ-65u-3@gated-at.bofh.it>
In reply to#1421447
On Mon, 13 Jun 2016 19:20:19 -0400
Steven Rostedt <rostedt@goodmis.org> wrote:

> On Mon, 13 Jun 2016 19:13:45 -0400
> Steven Rostedt <rostedt@goodmis.org> wrote:
> 
> 
> > >   # cd /sys/kernel/debug/tracing
> > >   # echo p copy_user_enhanced_fast_string+5 > kprobe_events
> > >   # echo 1 > events/kprobes/enable
> > > 
> > > And you'll see a kernel panic on do_debug(), since the debug
> > > trap is not handled by kprobes.
> > > 
> > > To fix this problem, we just need to clear the TF bit when
> > > resetting running kprobe.
> > >   
> > 
> > This should definitely be marked for stable, and I bisected it all the
> > way down to this commit: f4cb1cc18f364d "x86-64, copy_user: Remove zero
> > byte check before copy user buffer."

I agree this is for stable.

> > I reverted that commit and sure enough, this bug goes away. I'm not
> > saying the revert should be done. I'm just doing an FYI, and showing how
> > changes that appear to be a nice clean up can have subtle effects. I'm
> > not even sure how that change caused this to be a problem with kprobes.
> > 
> 
> Nevermind, reverting that commit only moved the location of the
> "rep movsb" that you were placing the kprobe on. When I do:
> 
>   echo "p copy_user_enhanced_fast_string+9" > kprobe_events
> 
> I get the same result.
> 
> That means we need to make that stable tag even earlier.

Yeah, I think it may never be tested from beginning,
so more thant 10 years we have this issue on the kernel.
I recommend this for all the stable/long term support kernels.

Thank you,

-- 
Masami Hiramatsu <mhiramat@kernel.org>

[toc] | [prev] | [next] | [standalone]


#1421724

FromIngo Molnar <mingo@kernel.org>
Date2016-06-14 12:00 +0200
Message-ID<rJTix-37S-7@gated-at.bofh.it>
In reply to#1421447
* Steven Rostedt <rostedt@goodmis.org> wrote:

> On Mon, 13 Jun 2016 19:13:45 -0400
> Steven Rostedt <rostedt@goodmis.org> wrote:
> 
> 
> > >   # cd /sys/kernel/debug/tracing
> > >   # echo p copy_user_enhanced_fast_string+5 > kprobe_events
> > >   # echo 1 > events/kprobes/enable
> > > 
> > > And you'll see a kernel panic on do_debug(), since the debug
> > > trap is not handled by kprobes.
> > > 
> > > To fix this problem, we just need to clear the TF bit when
> > > resetting running kprobe.
> > >   
> > 
> > This should definitely be marked for stable, and I bisected it all the
> > way down to this commit: f4cb1cc18f364d "x86-64, copy_user: Remove zero
> > byte check before copy user buffer."
> > 
> > I reverted that commit and sure enough, this bug goes away. I'm not
> > saying the revert should be done. I'm just doing an FYI, and showing how
> > changes that appear to be a nice clean up can have subtle effects. I'm
> > not even sure how that change caused this to be a problem with kprobes.
> > 
> 
> Nevermind, reverting that commit only moved the location of the
> "rep movsb" that you were placing the kprobe on. When I do:
> 
>   echo "p copy_user_enhanced_fast_string+9" > kprobe_events
> 
> I get the same result.
> 
> That means we need to make that stable tag even earlier.

I added:

  Cc: stable@vger.kernel.org # All the way back to ancient kernels

Thanks,

	Ingo

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web