@@ -97,6 +97,13 @@ uint64_t run_in_user(usermode_func func, unsigned int fault_vector,
/* Kernel Mode */
"ret_to_kernel:\n\t"
"mov %[rsp0], %%rsp\n\t"
+#ifdef __x86_64__
+ /* Restore SS, as it forcibly gets loaded with NULL */
+ "push %%rax\n\t"
+ "mov %[kernel_ds], %%ax\n\t"
+ "mov %%ax, %%ss\n\t"
+ "pop %%rax\n\t"
+#endif
:
"+a"(rax),
[rsp0]"=m"(tss[0].rsp0)
@@ -108,6 +115,7 @@ uint64_t run_in_user(usermode_func func, unsigned int fault_vector,
[func]"m"(func),
[user_ds]"i"(USER_DS),
[user_cs]"i"(USER_CS),
+ [kernel_ds]"i"(KERNEL_DS),
[user_stack_top]"r"(user_stack +
sizeof(user_stack)),
[kernel_entry_vector]"i"(RET_TO_KERNEL_IRQ));
Complement commit 663f9e447b98 ("x86: Fix a #GP from occurring in usermode library's exception handlers") and restore SS on a regular return as well. The INT-based "syscall" will make it get loaded with the NULL selector (see SDM Vol. 1, Interrupt and Exception Behavior in 64-Bit Mode: "The new SS is set to NULL if there is a change in CPL.") which makes the "mov null, %%ss" test of emulator64.c dubious, as SS is already loaded with the NULL selector. Fix this by loading SS with KERNEL_DS after a successful userland function call as well, as we already do in case of exceptions. Signed-off-by: Mathias Krause <minipli@grsecurity.net> --- lib/x86/usermode.c | 8 ++++++++ 1 file changed, 8 insertions(+)