Re: [PATCH] x86_64, asm: Work around AMD SYSRET SS descriptor attribute issue

Borislav Petkov
2015-04-27T08:53:26Z

On Sun, Apr 26, 2015 at 04:39:38PM -0700, Andy Lutomirski wrote:
> > +#define X86_BUG_CANONICAL_RCX X86_BUG(8) /* SYSRET #GPs when %RCX non-canonical */
>
> I think that "sysret" should appear in the name.

Yeah, I thought about it too, will fix.

> Oh no! My laptop is currently bug-free, and you're breaking it! :)

Muahahahhahaha...

> > +
> > + /*
> > + * On Intel CPUs, SYSRET with non-canonical RCX/RIP will #GP
> > + * in kernel space. This essentially lets the user take over
> > + * the kernel, since userspace controls RSP.
> > + */
> > + ALTERNATIVE "jmp 1f", "", X86_BUG_CANONICAL_RCX
> > +
>
> I know it would be ugly, but would it be worth saving two bytes by
> using ALTERNATIVE "jmp 1f", "shl ...", ...?
>
> > /* Change top 16 bits to be the sign-extension of 47th bit */
> > shl $(64 - (__VIRTUAL_MASK_SHIFT+1)), %rcx
> > sar $(64 - (__VIRTUAL_MASK_SHIFT+1)), %rcx
> > @@ -432,6 +436,7 @@ syscall_return:
> > cmpq %rcx, %r11
> > jne opportunistic_sysret_failed

You want to stick all 4 insns in the alternative? Yeah, it should work
but it might even more unreadable than it is now.

Btw, we can do this too:

ALTERNATIVE "",
"shl $(64 - (__VIRTUAL_MASK_SHIFT+1)), %rcx \
sar $(64 - (__VIRTUAL_MASK_SHIFT+1)), %rcx \
cmpq %rcx, %r11 \
jne opportunistic_sysret_failed"
X86_BUG_SYSRET_CANONICAL_RCX

which will replace the 2-byte JMP with a lot of NOPs on AMD.

I'll trace it again to see which one is worse :-)

Thanks.

--
Regards/Gruss,
Boris.

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