mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 01:12:44 +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; | ||||
| 
 | ||||
| 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 | ||||
| { | ||||
|  |  | |||
|  | @ -356,6 +356,14 @@ bool Scheduler::context_switch(Thread* thread) | |||
|     enter_current(*from_thread, false); | ||||
|     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; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling