From: Alexander Shaikhulin iwtcex@gmail.com
On AMD CPUs the cached SS descriptor attributes could be invalid after return to the userspace with SYSRET, which doesn't matter in the long mode, but would easily crash programs in the compatibility mode. Reloading %ss avoids that.
Note that Linux already has X86_BUG_SYSRET_SS_ATTRS as the workaround for this issue. --- dlls/ntdll/unix/signal_x86_64.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
diff --git a/dlls/ntdll/unix/signal_x86_64.c b/dlls/ntdll/unix/signal_x86_64.c index 7bb41b7910a..9354d4645b1 100644 --- a/dlls/ntdll/unix/signal_x86_64.c +++ b/dlls/ntdll/unix/signal_x86_64.c @@ -2971,6 +2971,11 @@ __ASM_GLOBAL_FUNC( __wine_syscall_dispatcher, "testl $4,%r14d\n\t" /* SYSCALL_HAVE_PTHREAD_TEB */ "jz 1f\n\t" "movw 0x338(%r13),%fs\n" /* amd64_thread_data()->fs */ +# ifdef __FreeBSD__ + /* reset %ss (after sysret) for AMD */ + "movq $0x3b,%rsi\n\t" /* GSEL(GUDATA_SEL, SEL_UPL) */ + "movq %rsi,%ss\n\t" +# endif "1:\n\t" #elif defined __APPLE__ "movq %rax,%r8\n\t" @@ -3258,6 +3263,11 @@ __ASM_GLOBAL_FUNC( __wine_unix_call_dispatcher, "testl $4,%r14d\n\t" /* SYSCALL_HAVE_PTHREAD_TEB */ "jz 1f\n\t" "movw 0x338(%r13),%fs\n" /* amd64_thread_data()->fs */ +# ifdef __FreeBSD__ + /* reset %ss (after sysret) for AMD */ + "movq $0x3b,%rsi\n\t" /* GSEL(GUDATA_SEL, SEL_UPL) */ + "movq %rsi,%ss\n\t" +# endif "1:\n\t" #elif defined __APPLE__ "movq %rax,%rdx\n\t"