diff --git a/Kernel/Arch/i386/CPU.h b/Kernel/Arch/i386/CPU.h index c4d736dc15..39168b3be7 100644 --- a/Kernel/Arch/i386/CPU.h +++ b/Kernel/Arch/i386/CPU.h @@ -43,6 +43,8 @@ class MemoryManager; class PageDirectory; class PageTableEntry; +static constexpr u32 safe_eflags_mask = 0xdff; + struct [[gnu::packed]] DescriptorTablePointer { u16 limit; diff --git a/Kernel/Ptrace.cpp b/Kernel/Ptrace.cpp index 97066bf86a..61b6028670 100644 --- a/Kernel/Ptrace.cpp +++ b/Kernel/Ptrace.cpp @@ -183,7 +183,8 @@ void copy_ptrace_registers_into_kernel_registers(RegisterState& kernel_regs, con kernel_regs.esi = ptrace_regs.esi; kernel_regs.edi = ptrace_regs.edi; kernel_regs.eip = ptrace_regs.eip; - kernel_regs.eflags = ptrace_regs.eflags; + + kernel_regs.eflags = (kernel_regs.eflags & ~safe_eflags_mask) | (ptrace_regs.eflags & safe_eflags_mask); } } diff --git a/Kernel/Syscall.cpp b/Kernel/Syscall.cpp index 8e5cd2007b..20416753c2 100644 --- a/Kernel/Syscall.cpp +++ b/Kernel/Syscall.cpp @@ -161,6 +161,14 @@ void syscall_handler(TrapFrame* trap) asm volatile("" : "=m"(*ptr)); + static constexpr u32 iopl_mask = 3u << 12; + + if ((regs.eflags & (iopl_mask)) != 0) { + dbgln("Syscall from process with IOPL != 0"); + handle_crash(regs, "Non-zero IOPL on syscall entry", SIGSEGV); + ASSERT_NOT_REACHED(); + } + if (!MM.validate_user_stack(process, VirtualAddress(regs.userspace_esp))) { dbgln("Invalid stack pointer: {:p}", regs.userspace_esp); handle_crash(regs, "Bad stack on syscall entry", SIGSTKFLT); diff --git a/Kernel/Syscalls/sigaction.cpp b/Kernel/Syscalls/sigaction.cpp index a3151c6d1e..a3cfc9d1bf 100644 --- a/Kernel/Syscalls/sigaction.cpp +++ b/Kernel/Syscalls/sigaction.cpp @@ -109,7 +109,7 @@ int Process::sys$sigreturn(RegisterState& registers) registers.eip = *stack_ptr; stack_ptr++; - registers.eflags = *stack_ptr; + registers.eflags = (registers.eflags & ~safe_eflags_mask) | (*stack_ptr & safe_eflags_mask); stack_ptr++; registers.userspace_esp = registers.esp;