Skip to content

ntdll: Ensure %cs is correct in sigcontext on x86_64 macOS.

On x86_64 macOS (real Intel/not under Rosetta), a signal delivered to a thread inside a syscall will have CS in sigcontext set to the kernel's selector (0x07, SYSCALL_CS in xnu source) instead of the user selector (cs64_sel: 0x2b, USER64_CS).

This causes crashes when running a 32-bit CEF sample or Steam: those do lots of async I/O, SIGUSR1 is received often, and CS_sig is 0x07 if received while in _thread_set_tsd_base. get_wow_context() later compares SegCs to cs64_sel, sees that it's different, assumes that we are in 32-bit code, and the 32-bit context is used. The top 32-bits of RIP and every register are stripped off, and the thread crashes when it tries to return after handling the signal.

To fix this, set CS_sig to cs64_sel if it's set to 0x07/SYSCALL_CS. We only make macOS syscalls from 64-bit code.

It appears that macOS has always done this (I tested back to 10.12), but it wasn't an issue until 3a16aabb/!6866 (merged) started doing _thread_set_tsd_base() outside of a Wine/NT syscall.

Edited by Brendan Shanks

Merge request reports

Loading