mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 15:32:46 +00:00 
			
		
		
		
	Kernel: Allow relaxing cleanup task rules during system shutdown
Once we move to a more proper shutdown procedure, processes other than the finalizer task must be able to perform cleanup and finalization duties, not only because the finalizer task itself needs to be cleaned up by someone. This global variable, mirroring the early boot flags, allows a future shutdown process to perform cleanup on its own. Note that while this *could* be considered a weakening in security, the attack surface is minimal and the results are not dramatic. To exploit this, an attacker would have to gain a Kernel write primitive to this global variable (bypassing KASLR among other things) and then gain some way of calling the relevant functions, all of this only to destroy some other running process. The same effect can be achieved with LPE which can often be gained with significantly simpler userspace exploits (e.g. of setuid binaries).
This commit is contained in:
		
							parent
							
								
									021fb3ea05
								
							
						
					
					
						commit
						2fd23745a9
					
				
					 6 changed files with 39 additions and 5 deletions
				
			
		|  | @ -350,6 +350,7 @@ set(KERNEL_SOURCES | ||||||
|     Tasks/FinalizerTask.cpp |     Tasks/FinalizerTask.cpp | ||||||
|     Tasks/FutexQueue.cpp |     Tasks/FutexQueue.cpp | ||||||
|     Tasks/PerformanceEventBuffer.cpp |     Tasks/PerformanceEventBuffer.cpp | ||||||
|  |     Tasks/PowerStateSwitchTask.cpp | ||||||
|     Tasks/Process.cpp |     Tasks/Process.cpp | ||||||
|     Tasks/ProcessGroup.cpp |     Tasks/ProcessGroup.cpp | ||||||
|     Tasks/ProcessList.cpp |     Tasks/ProcessList.cpp | ||||||
|  |  | ||||||
|  | @ -14,6 +14,7 @@ | ||||||
| #include <Kernel/Memory/MemoryManager.h> | #include <Kernel/Memory/MemoryManager.h> | ||||||
| #include <Kernel/Security/Random.h> | #include <Kernel/Security/Random.h> | ||||||
| #include <Kernel/Tasks/PerformanceManager.h> | #include <Kernel/Tasks/PerformanceManager.h> | ||||||
|  | #include <Kernel/Tasks/PowerStateSwitchTask.h> | ||||||
| #include <Kernel/Tasks/Process.h> | #include <Kernel/Tasks/Process.h> | ||||||
| #include <Kernel/Tasks/Scheduler.h> | #include <Kernel/Tasks/Scheduler.h> | ||||||
| 
 | 
 | ||||||
|  | @ -323,7 +324,9 @@ void AddressSpace::dump_regions() | ||||||
| 
 | 
 | ||||||
| void AddressSpace::remove_all_regions(Badge<Process>) | void AddressSpace::remove_all_regions(Badge<Process>) | ||||||
| { | { | ||||||
|     VERIFY(Thread::current() == g_finalizer); |     if (!g_in_system_shutdown) | ||||||
|  |         VERIFY(Thread::current() == g_finalizer); | ||||||
|  | 
 | ||||||
|     { |     { | ||||||
|         SpinlockLocker pd_locker(m_page_directory->get_lock()); |         SpinlockLocker pd_locker(m_page_directory->get_lock()); | ||||||
|         for (auto& region : m_region_tree.regions()) |         for (auto& region : m_region_tree.regions()) | ||||||
|  |  | ||||||
							
								
								
									
										11
									
								
								Kernel/Tasks/PowerStateSwitchTask.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Kernel/Tasks/PowerStateSwitchTask.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org> | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-2-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace Kernel { | ||||||
|  | 
 | ||||||
|  | bool g_in_system_shutdown { false }; | ||||||
|  | 
 | ||||||
|  | } | ||||||
							
								
								
									
										11
									
								
								Kernel/Tasks/PowerStateSwitchTask.h
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										11
									
								
								Kernel/Tasks/PowerStateSwitchTask.h
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,11 @@ | ||||||
|  | /*
 | ||||||
|  |  * Copyright (c) 2023, kleines Filmröllchen <filmroellchen@serenityos.org> | ||||||
|  |  * | ||||||
|  |  * SPDX-License-Identifier: BSD-2-Clause | ||||||
|  |  */ | ||||||
|  | 
 | ||||||
|  | namespace Kernel { | ||||||
|  | 
 | ||||||
|  | extern bool g_in_system_shutdown; | ||||||
|  | 
 | ||||||
|  | } | ||||||
|  | @ -46,6 +46,7 @@ namespace Kernel { | ||||||
| static void create_signal_trampoline(); | static void create_signal_trampoline(); | ||||||
| 
 | 
 | ||||||
| extern ProcessID g_init_pid; | extern ProcessID g_init_pid; | ||||||
|  | extern bool g_in_system_shutdown; | ||||||
| 
 | 
 | ||||||
| RecursiveSpinlock<LockRank::None> g_profiling_lock {}; | RecursiveSpinlock<LockRank::None> g_profiling_lock {}; | ||||||
| static Atomic<pid_t> next_pid; | static Atomic<pid_t> next_pid; | ||||||
|  | @ -749,7 +750,8 @@ ErrorOr<void> Process::dump_perfcore() | ||||||
| 
 | 
 | ||||||
| void Process::finalize() | void Process::finalize() | ||||||
| { | { | ||||||
|     VERIFY(Thread::current() == g_finalizer); |     if (!g_in_system_shutdown) | ||||||
|  |         VERIFY(Thread::current() == g_finalizer); | ||||||
| 
 | 
 | ||||||
|     dbgln_if(PROCESS_DEBUG, "Finalizing process {}", *this); |     dbgln_if(PROCESS_DEBUG, "Finalizing process {}", *this); | ||||||
| 
 | 
 | ||||||
|  | @ -759,8 +761,12 @@ void Process::finalize() | ||||||
|         }); |         }); | ||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     if (g_init_pid != 0 && pid() == g_init_pid) |     if (g_init_pid != 0 && pid() == g_init_pid) { | ||||||
|         PANIC("Init process quit unexpectedly. Exit code: {}", termination_status()); |         if (g_in_system_shutdown) | ||||||
|  |             dbgln("Init process quitting for shutdown."); | ||||||
|  |         else | ||||||
|  |             PANIC("Init process quit unexpectedly. Exit code: {}", termination_status()); | ||||||
|  |     } | ||||||
| 
 | 
 | ||||||
|     if (is_dumpable()) { |     if (is_dumpable()) { | ||||||
|         if (m_should_generate_coredump) { |         if (m_should_generate_coredump) { | ||||||
|  |  | ||||||
|  | @ -23,6 +23,7 @@ | ||||||
| #include <Kernel/Memory/ScopedAddressSpaceSwitcher.h> | #include <Kernel/Memory/ScopedAddressSpaceSwitcher.h> | ||||||
| #include <Kernel/Sections.h> | #include <Kernel/Sections.h> | ||||||
| #include <Kernel/Tasks/PerformanceEventBuffer.h> | #include <Kernel/Tasks/PerformanceEventBuffer.h> | ||||||
|  | #include <Kernel/Tasks/PowerStateSwitchTask.h> | ||||||
| #include <Kernel/Tasks/Process.h> | #include <Kernel/Tasks/Process.h> | ||||||
| #include <Kernel/Tasks/Scheduler.h> | #include <Kernel/Tasks/Scheduler.h> | ||||||
| #include <Kernel/Tasks/Thread.h> | #include <Kernel/Tasks/Thread.h> | ||||||
|  | @ -537,7 +538,8 @@ StringView Thread::state_string() const | ||||||
| 
 | 
 | ||||||
| void Thread::finalize() | void Thread::finalize() | ||||||
| { | { | ||||||
|     VERIFY(Thread::current() == g_finalizer); |     if (!g_in_system_shutdown) | ||||||
|  |         VERIFY(Thread::current() == g_finalizer); | ||||||
|     VERIFY(Thread::current() != this); |     VERIFY(Thread::current() != this); | ||||||
| 
 | 
 | ||||||
| #if LOCK_DEBUG | #if LOCK_DEBUG | ||||||
|  |  | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 kleines Filmröllchen
						kleines Filmröllchen