From: Mark Rutland <mark.rutland@arm.com>
To: Will Deacon <will@kernel.org>
Cc: Luis Machado <luis.machado@linaro.org>,
linux-arm-kernel@lists.infradead.org
Subject: Re: [arm64, debug] PTRACE_SINGLESTEP does not single-step a valid instruction
Date: Fri, 21 Feb 2020 11:16:53 +0000 [thread overview]
Message-ID: <20200221111652.GB45022@lakrids.cambridge.arm.com> (raw)
In-Reply-To: <20200220132941.GB14459@willie-the-truck>
On Thu, Feb 20, 2020 at 01:29:42PM +0000, Will Deacon wrote:
> Hi Mark,
>
> Thanks for having a look.
>
> On Thu, Feb 20, 2020 at 01:02:22PM +0000, Mark Rutland wrote:
> > On Thu, Feb 13, 2020 at 12:01:16PM +0000, Will Deacon wrote:
> > > diff --git a/arch/arm64/kernel/ptrace.c b/arch/arm64/kernel/ptrace.c
> > > index cd6e5fa48b9c..d479fbcbd0d2 100644
> > > --- a/arch/arm64/kernel/ptrace.c
> > > +++ b/arch/arm64/kernel/ptrace.c
> > > @@ -1934,8 +1934,8 @@ static int valid_native_regs(struct user_pt_regs *regs)
> > > */
> > > int valid_user_regs(struct user_pt_regs *regs, struct task_struct *task)
> > > {
> > > - if (!test_tsk_thread_flag(task, TIF_SINGLESTEP))
> > > - regs->pstate &= ~DBG_SPSR_SS;
> > > + /* https://lore.kernel.org/lkml/20191118131525.GA4180@willie-the-truck */
> > > + user_regs_reset_single_step(regs, task);
> >
> > I think this change means we do the right thing for signal entry/return
> > and ptrace messing with the regs. Instruction emulation seems to do the
> > right thing via skip_faulting_instruction().
> >
> > I think there are a few more single-step edge cases lying around (e.g.
> > uprobes, rseq), but it looks like those have to be fixed separately. I
> > fear fixing uprobes might require a largler structural change to single
> > step, but ignoring uprobes the changes above seem to be sound.
>
> Rseq should just abort when delivering the step signal and I'm not sure I
> see the issue with uprobes. Can you elaborate on your concerns a bit,
> please?
For rseq I wasn't sure what state PSTATE.SS should be when we head to
the abort handler -- I think the sensible thing would be that it
immediately triggers a single-step exception, but I don't see where we'd
clear PSTATE.SS to ensure that.
For uprobes I fear that the uprobes xol single-stepping might end up
conflicting with the regular ptrace single-stepping, and that the
uprobes emulation might not always advance the state machine correctly.
> > If userspace doesn't consume the SS value today, I wonder if we should
> > hide it when dumping the SPSR to userspace, so that userspace has a
> > consistent view regardless of whether it's being stepped.
>
> You can't really hide it though, because '0' has a meaning so I don't think
> it gains us a lot other than increasing the scope of the change.
I think that it reduces the likelihood that single-stepping a program
changes its behaviour unexpectedly. This patch makes the kernel
disregard the PSTATE.SS value provided by userspace, so what is gained
by exposing PSTATE.SS to userspace at all?
I do agree that there are potentially subtle landmines here; I just
can't see a legitimate reason for userspace to need the value.
> > I'll try to dig into the uprobes stuff this afternoon, just in case
> > that
> > needs us to do something substantially different.
>
> Thanks.
I didn't get the chance to do this yesterday, but I did think of another
potential problem.
I *think* that when attempting to single-step a syscall, if prior to
return from the syscall the tracer messed with the tracee's regs (e.g.
to mess with arguments or the retun value) then valid_user_regs() will
set the SS bit, and upon return from the syscall the next instruction
would be executed rather than first raising a single-step exception.
This patch relies on valid_user_regs() being a signal that PSTATE.SS is
stale, but that's not always the case. To handle that generally I
suspect we need two bits of state rather than just TIF_SINGLESTEP.
> > The existing logic in valid_user_regs() doesn't make sense to me, given
> > SPSR_EL1.SS is immaterial unless MSCDR_EL1.SS == 1. I'm not sure if that
> > was overzealous or I've forgotten an edge case that we cared about in
> > the past.
>
> I think it was just part of sanitising the registers to a consistent value,
> but I agree that it wouldn't have a functional impact.
Thanks for confirming my understanding. I guess this may have minimized
the cases where userspace saw PSTATE.SS set.
> > > diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c
> > > index 339882db5a91..bc54bdbfd760 100644
> > > --- a/arch/arm64/kernel/signal.c
> > > +++ b/arch/arm64/kernel/signal.c
> > > @@ -505,8 +505,12 @@ static int restore_sigframe(struct pt_regs *regs,
> > > forget_syscall(regs);
> > >
> > > err |= !valid_user_regs(®s->user_regs, current);
> > > - if (err == 0)
> > > +
> > > + if (err == 0) {
> > > + /* Make it look like we stepped the sigreturn system call */
> > > + user_fastforward_single_step(current);
> > > err = parse_user_sigframe(&user, sf);
> > > + }
> >
> > I don't understand this. AFAICT we don't likewise for other SVCs, so
> > either I'm missing that, or there's something else I'm missing.
> >
> > Why do we need to step sigreturn but not SVC generally?
>
> Because we restore the SPSR from the sigframe during sigreturn, so we will
> end up with PSTATE.SS set when it should be cleared.
Ah, I see. As above, I think we can hit a similar case when
single-stepping an SVC for a regular syscall.
Thanks,
Mark.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2020-02-21 11:17 UTC|newest]
Thread overview: 17+ messages / expand[flat|nested] mbox.gz Atom feed top
2019-11-12 23:22 [arm64, debug] PTRACE_SINGLESTEP does not single-step a valid instruction Luis Machado
2019-11-18 13:15 ` Will Deacon
2019-11-18 14:54 ` Luis Machado
2019-11-26 16:35 ` Luis Machado
2019-12-10 20:00 ` Luis Machado
2020-02-13 12:01 ` Will Deacon
2020-02-13 17:07 ` Luis Machado
2020-02-14 15:45 ` Luis Machado
2020-02-18 8:44 ` Will Deacon
2020-02-18 10:33 ` Luis Machado
2020-02-26 13:01 ` Luis Machado
2020-02-20 13:02 ` Mark Rutland
2020-02-20 13:29 ` Will Deacon
2020-02-21 11:16 ` Mark Rutland [this message]
2020-05-27 14:39 ` Luis Machado
2020-05-31 9:52 ` Will Deacon
2020-01-13 18:13 ` Luis Machado
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=20200221111652.GB45022@lakrids.cambridge.arm.com \
--to=mark.rutland@arm.com \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=luis.machado@linaro.org \
--cc=will@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;
as well as URLs for NNTP newsgroup(s).