Re: [REGRESSION 5.8] x86/entry: DR0 break-on-write not working
From: Andy Lutomirski
Date: Wed Aug 19 2020 - 20:14:38 EST
On Wed, Aug 19, 2020 at 3:47 PM Josh Poimboeuf <jpoimboe@xxxxxxxxxx> wrote:
>
> On Wed, Aug 19, 2020 at 11:35:34PM +0200, Peter Zijlstra wrote:
> > On Wed, Aug 19, 2020 at 12:28:16PM -0700, Kyle Huey wrote:
> >
> > > > I'm guess that is not the expected outcome, is that the same failure you
> > > > saw?
> > >
> > > Yes. Is status also 0x4d00 for you?
> >
> > Indeed.
> >
> > > The program is expected to complete with no assertions firing.
> >
> > When I comment out the break-on-exec test, the break-on-write test
> > succeeds.
> >
> > When I add a few printk()'s to our #DB handler (6) the program will
> > magically work again.
>
> I added some trace_printk()'s and I think the #DB handler is calling
> schedule????
>
> exc_debug_user()
> irqentry_exit_to_user_mode()
> exit_to_user_mode_prepare()
> exit_to_user_mode_loop()
> schedule()
>
> So #DB schedules out, then the process scheduls in and tells ptrace to
> set the data breakpoint in DR7. Then the #DB handler schedules back in
> and overwrites DR7 with the original value.
>
> What amazes me is that it successfully schedules back to the end of the
> #DB handler finish and everything keeps working.
>
> Do we not have assertions in the scheduler to catch this?
You almost nailed it.
I'm pretty sure you have the buggy sequence of events right, but for
the wrong reason. There's nothing wrong with scheduling when
delivering SIGTRAP, but it's definitely wrong to blindly save and
restore DR7 around scheduling and around ptrace invocations. Remember
this is an entry from user mode, so it runs on the user stack.
Patch coming.
--Andy