Re: [PATCH v2] x86/entry_32: Move CLEAR_CPU_BUFFERS before restoring segments
From: Brian Gerst
Date: Sat Jun 29 2024 - 11:41:32 EST
On Thu, Jun 27, 2024 at 10:57 PM Pawan Gupta
<pawan.kumar.gupta@xxxxxxxxxxxxxxx> wrote:
>
> Robert Gill reported below #GP when dosemu software was executing vm86()
> system call:
>
> general protection fault: 0000 [#1] PREEMPT SMP
> CPU: 4 PID: 4610 Comm: dosemu.bin Not tainted 6.6.21-gentoo-x86 #1
> Hardware name: Dell Inc. PowerEdge 1950/0H723K, BIOS 2.7.0 10/30/2010
> EIP: restore_all_switch_stack+0xbe/0xcf
> EAX: 00000000 EBX: 00000000 ECX: 00000000 EDX: 00000000
> ESI: 00000000 EDI: 00000000 EBP: 00000000 ESP: ff8affdc
> DS: 0000 ES: 0000 FS: 0000 GS: 0033 SS: 0068 EFLAGS: 00010046
> CR0: 80050033 CR2: 00c2101c CR3: 04b6d000 CR4: 000406d0
> Call Trace:
> show_regs+0x70/0x78
> die_addr+0x29/0x70
> exc_general_protection+0x13c/0x348
> exc_bounds+0x98/0x98
> handle_exception+0x14d/0x14d
> exc_bounds+0x98/0x98
> restore_all_switch_stack+0xbe/0xcf
> exc_bounds+0x98/0x98
> restore_all_switch_stack+0xbe/0xcf
>
> This only happens when VERW based mitigations like MDS, RFDS are enabled.
> This is because segment registers can have funky values with vm86() that
> can result in #GP when executing VERW. Intel SDM vol. 2C documents the
> following behavior for VERW instruction:
>
> #GP(0) - If a memory operand effective address is outside the CS, DS, ES,
> FS, or GS segment limit.
This isn't limited to just VM86 mode, since any user DS that isn't a
flat segment can also cause problems.
> CLEAR_CPU_BUFFERS macro executes VERW instruction before returning to
> user space. Add CLEAR_CPU_BUFFERS to the macro RESTORE_REGS before it
> restores segment registers. In vm86 mode kernel does not support SYSCALL
> and SYSENTER instructions, so the problem is only limited to int80 path
> in 32-bit mode. In the opportunistic SYSEXIT path use
> CLEAR_CPU_BUFFERS_SAFE that ensures a sane %ds value.
The simpler fix is to use an SS segment override (verw
%ss:mds_verw_sel), since the stack segment is still valid right up to
the IRET/SYSEXIT.
Brian Gerst