Re: [tip:x86/vdso] x86/vdso32/syscall.S: Do not load __USER32_DS to %ss

Borislav Petkov
2015-04-23T09:47:20Z

On Thu, Apr 23, 2015 at 01:49:50AM -0700, Andy Lutomirski wrote:
> I'm pretty sure that this is at least a little bit wrong. It makes no
> sense for me for syscall to set SS.DPL=0 and for sysret to leave
> SS.DPL=0. It had better at least change DPL to 3. (Except... don't
> they mean RPL? Why is the DPL cached at all? But RPL is clearly
> changed, since it's part of the selector.)

I think this should explain it a bit:

"• STAR—The STAR register has the following fields (unless otherwise
noted, all bits are read/write):

- SYSRET CS and SS Selectors—Bits 63:48. This field is used to specify
both the CS and SS selectors loaded into CS and SS during SYSRET. If
SYSRET is returning to 32-bit mode (either legacy or compatibility),
this field is copied directly into the CS selector field. If SYSRET is
returning to 64-bit mode, the CS selector is set to this field + 16.
SS.Sel is set to this field + 8, regardless of the target mode. Because
SYSRET always returns to CPL 3, the RPL bits 49:48 should be initialized
to 11b.

- SYSCALL CS and SS Selectors—Bits 47:32. This field is used to
specify both the CS and SS selectors loaded into CS and SS during
SYSCALL. This field is copied directly into CS.Sel. SS.Sel is set to
this field + 8. Because SYSCALL always switches to CPL 0, the RPL bits
33:32 should be initialized to 00b."

So I'm reading "SYSRET always returns to CPL3" and "SYSCALL always
switches to CPL 0" as those are being enforced. And this is also
mentioned in the SYSCALL/SYSRET documentation:

"SYSCALL sets the CPL to 0, regardless of the values of bits 33:32 of
the STAR register."

and

"SYSRET sets the CPL to 3, regardless of the values of bits 49:48 of the
star register."

BUT(!)

"It is also assumed (but not checked) that the RPL of the SYSCALL and
SYSRET target selectors are set to 0 and 3, respectively."

>
> > Not changing base or limit is no big deal, but not changing attributes
> > could be the problem. It might be leaving the "64-bit stack"
> > attribute set, for whatever that means.
>
> Hmm. I don't know if I believe that explanation. For one thing, the
> APM says "Executing SYSRET in non-64-bit mode or with a 16- or 32-bit
> operand size returns to 32-bit mode with a 32-bit stack pointer."
>
> We can revert this patch or fix it, but I'd like to at least try to
> understand what's wrong first. Borislav, any ideas?

Right, so according to the documentation, SYSRET does load SS from
MSR_STAR[63:48] and forces the RPL bits [49:48] to 3.

So if we really do have a bad %ss, then something is changing it in
MSR_STAR.

But that sounds really far-fetched and implausible so it must be
something else.

/me scratches head...

--
Regards/Gruss,
Boris.

ECO tip #101: Trim your mails when you reply.
--