x86-64 syscall: fix very specific triple fault

This commit is contained in:
Matheus
2023-09-09 13:28:04 -03:00
parent e8355df0b6
commit 63a051dd30
+11 -10
View File
@@ -99,19 +99,22 @@ global arch_syscall_entry
; rax has return value ; rax has return value
arch_syscall_entry: arch_syscall_entry:
swapgs swapgs
; save return address on user stack ; saving the syscall number on cr2 is cursed but we need this extra register
push rcx ; and taking a page fault here would result in a triple fault anyways
mov rcx, [gs:0x0] ; thread pointer ; because it's still using the user stack
mov rcx, [rcx] ; kernel stack top mov cr2, rax
xchg rsp, rcx ; switch stack pointers ; rax can be used just fine now
mov rax, [gs:0x0] ; thread pointer
mov rax, [rax] ; kernel stack top
xchg rsp, rax ; switch stack pointers
; push context ; push context
push qword 0x1b ; user SS push qword 0x1b ; user SS
push qword rcx ; user RSP push qword rax ; user RSP
add qword [rsp], 8 ; correct the old stack pointer to before the return address push mov rax, cr2 ; restore syscall number
push r11 ; rflags is stored in r11 push r11 ; rflags is stored in r11
push qword 0x23 ; user CS push qword 0x23 ; user CS
push qword [rcx] ; save return RIP push qword rcx ; save return RIP
push qword 0 ; error push qword 0 ; error
push rbp push rbp
push rsi push rsi
@@ -169,13 +172,11 @@ arch_syscall_entry:
cli cli
; call return logging function ; call return logging function
mov rdi, rax mov rdi, rax
mov rsi, rdx mov rsi, rdx
extern arch_syscall_log_return extern arch_syscall_log_return
call arch_syscall_log_return ; compiled with __attribute__((no_caller_saved_registers)) call arch_syscall_log_return ; compiled with __attribute__((no_caller_saved_registers))
; restore context ; restore context
add rsp, 32 ; r9 argument, cr2, gs, and fs are not popped. add rsp, 32 ; r9 argument, cr2, gs, and fs are not popped.
pop rbx pop rbx