Skip to content

Commit c25cf5f

Browse files
committed
Kernel: Panic if we're about to switch to a user thread with IOPL!=0
This is a crude protection against IOPL elevation attacks. If for any reason we find ourselves about to switch to a user mode thread with IOPL != 0, we'll now simply panic the kernel. If this happens, it basically means that something tricked the kernel into incorrectly modifying the IOPL of a thread, so it's no longer safe to trust the kernel anyway.
1 parent 488a613 commit c25cf5f

File tree

2 files changed

+14
-0
lines changed

2 files changed

+14
-0
lines changed

Kernel/Arch/i386/CPU.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,12 @@ class PageDirectory;
4444
class PageTableEntry;
4545

4646
static constexpr u32 safe_eflags_mask = 0xdff;
47+
static constexpr u32 iopl_mask = 3u << 12;
48+
49+
inline u32 get_iopl_from_eflags(u32 eflags)
50+
{
51+
return (eflags & iopl_mask) >> 12;
52+
}
4753

4854
struct [[gnu::packed]] DescriptorTablePointer
4955
{

Kernel/Scheduler.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -356,6 +356,14 @@ bool Scheduler::context_switch(Thread* thread)
356356
enter_current(*from_thread, false);
357357
ASSERT(thread == Thread::current());
358358

359+
#if ARCH(I386)
360+
auto iopl = get_iopl_from_eflags(Thread::current()->get_register_dump_from_stack().eflags);
361+
if (thread->process().is_user_process() && iopl != 0) {
362+
dbgln("PANIC: Switched to thread {} with non-zero IOPL={}", Thread::current()->tid().value(), iopl);
363+
Processor::halt();
364+
}
365+
#endif
366+
359367
return true;
360368
}
361369

0 commit comments

Comments
 (0)