Messages in this thread | | | From | Andy Lutomirski <> | Date | Thu, 23 Apr 2015 08:50:10 -0700 | Subject | Re: [PATCH] x86/asm/entry/32: Restore %ss before SYSRETL if necessary |
| |
On Thu, Apr 23, 2015 at 8:22 AM, Linus Torvalds <torvalds@linux-foundation.org> wrote: > On Thu, Apr 23, 2015 at 5:34 AM, Denys Vlasenko <dvlasenk@redhat.com> wrote: >> >> It was observed to cause Wine crashes. Conjectured sequence of events >> causing it is as follows: >> >> 1. Wine process enters kernel via syscall insn. >> 2. Context switch to any other task. >> 3. Interrupt or exception happens, CPU loads %ss with 0. >> (This happens according to both Intel and AMD docs.) >> %ss cached descriptor is set to "invalid" state. >> 4. Context switch back to Wine. >> 5. sysret to 32-bit userspace. %ss selector has correct value but its >> cached descriptor is still invalid. > > I really don't like the patch, as it just feels very hacky to me. > > It is a bit scary to me that apparently we leak %ss values between > processes, so that while we run in the kernel we can randomly have the > ss descriptor either be 0 or __KERNEL_DS. That sounds like an > information leak to me, even in 64-bit mode. The value of %ss may not > *matter* in 64-bit mode, but leaking that difference between processes > sounds nasty. I can't offhand thing of any way to actually read the > present bit in the cached descriptor (I was thinking something like > the "LSL" instruction, but that takes a new segment selector, not the > segment itself), but it just smells odd to me.
How about, in 64-bit code: syscall; long jump to a 32-bit cs; mov with ss override (or push or pop).
> > Also, why does this only happen with Wine? In regular 32-bit mode the > segment valid bit in the cached descriptor should also matter. So how > come this doesn't trigger for any 32-bit user land on a 64-bit kernel?
See other thread. I bet we got poisoned by a concurrently running, preempted 16-bit or segmented process.
--Andy
| |