mirror of
https://github.com/RGBCube/serenity
synced 2025-05-20 18:15:07 +00:00
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.
This commit is contained in:
parent
488a613858
commit
c25cf5fb56
2 changed files with 14 additions and 0 deletions
|
@ -44,6 +44,12 @@ class PageDirectory;
|
||||||
class PageTableEntry;
|
class PageTableEntry;
|
||||||
|
|
||||||
static constexpr u32 safe_eflags_mask = 0xdff;
|
static constexpr u32 safe_eflags_mask = 0xdff;
|
||||||
|
static constexpr u32 iopl_mask = 3u << 12;
|
||||||
|
|
||||||
|
inline u32 get_iopl_from_eflags(u32 eflags)
|
||||||
|
{
|
||||||
|
return (eflags & iopl_mask) >> 12;
|
||||||
|
}
|
||||||
|
|
||||||
struct [[gnu::packed]] DescriptorTablePointer
|
struct [[gnu::packed]] DescriptorTablePointer
|
||||||
{
|
{
|
||||||
|
|
|
@ -356,6 +356,14 @@ bool Scheduler::context_switch(Thread* thread)
|
||||||
enter_current(*from_thread, false);
|
enter_current(*from_thread, false);
|
||||||
ASSERT(thread == Thread::current());
|
ASSERT(thread == Thread::current());
|
||||||
|
|
||||||
|
#if ARCH(I386)
|
||||||
|
auto iopl = get_iopl_from_eflags(Thread::current()->get_register_dump_from_stack().eflags);
|
||||||
|
if (thread->process().is_user_process() && iopl != 0) {
|
||||||
|
dbgln("PANIC: Switched to thread {} with non-zero IOPL={}", Thread::current()->tid().value(), iopl);
|
||||||
|
Processor::halt();
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue