Merge pull request #40 from primeseven1/rewrite

Fix sysret with a non-canonical return RIP
This commit is contained in:
Matheus
2026-09-22 17:51:42 -03:00
committed by GitHub
+42 -24
View File
@@ -217,6 +217,32 @@ dq syscall_eventfd
syscallcount equ 107 syscallcount equ 107
section .text section .text
global arch_syscall_entry global arch_syscall_entry
%macro restore_context 0
add rsp, 32 ; r9 argument, cr2, gs, and fs are not popped.
pop rbx
mov es,rbx
pop rbx
mov ds,rbx
pop rax
pop rbx
pop rcx
pop rdx
pop r8
pop r9
pop r10
pop r11
pop r12
pop r13
pop r14
pop r15
pop rdi
pop rsi
add rsp, 8 ; remove irq
pop rbp
add rsp, 8 ; remove error code
%endmacro
; on entry: ; on entry:
; rcx has the return address ; rcx has the return address
; r11 has the old rflags ; r11 has the old rflags
@@ -329,32 +355,24 @@ arch_syscall_entry:
call sched_userspacecheck ; compiled with __attribute__((no_caller_saved_registers)) call sched_userspacecheck ; compiled with __attribute__((no_caller_saved_registers))
cli cli
; restore context ; on intel cpu's, a non-canonical rip will cause a #GP in ring 0 on the user stack when sysret is used
add rsp, 32 ; r9 argument, cr2, gs, and fs are not popped. mov rax, [rdi + 176] ; context->rip
pop rbx mov rbx, rax
mov es,rbx shl rax, 64 - 48 ; this breaks if LA57 is enabled (it's not)
pop rbx sar rax, 64 - 48
mov ds,rbx cmp rax, rbx
pop rax jne .gpf
pop rbx
pop rcx restore_context
pop rdx
pop r8
pop r9
pop r10
pop r11
pop r12
pop r13
pop r14
pop r15
pop rdi
pop rsi
add rsp, 8 ; remove irq
pop rbp
add rsp, 8 ; remove error code
pop rcx pop rcx
add rsp, 8 ; user CS add rsp, 8 ; user CS
pop r11 ; rflags pop r11 ; rflags
pop rsp pop rsp
swapgs swapgs
o64 sysret o64 sysret
.gpf:
restore_context
push 0 ; error code
swapgs
extern isr_table
jmp [isr_table + 13 * 8] ; jump to the #GP handler with the user interrupt frame