mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 15:02:46 +00:00 
			
		
		
		
	 4b2651ddab
			
		
	
	
		4b2651ddab
		
	
	
	
	
		
			
			The way the Process::FileDescriptions::allocate() API works today means that two callers who allocate back to back without associating a FileDescription with the allocated FD, will receive the same FD and thus one will stomp over the other. Naively tracking which FileDescriptions are allocated and moving onto the next would introduce other bugs however, as now if you "allocate" a fd and then return early further down the control flow of the syscall you would leak that fd. This change modifies this behavior by tracking which descriptions are allocated and then having an RAII type to "deallocate" the fd if the association is not setup the end of it's scope.
		
			
				
	
	
		
			29 lines
		
	
	
	
		
			756 B
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			29 lines
		
	
	
	
		
			756 B
		
	
	
	
		
			C++
		
	
	
	
	
	
| /*
 | |
|  * Copyright (c) 2018-2020, Andreas Kling <kling@serenityos.org>
 | |
|  *
 | |
|  * SPDX-License-Identifier: BSD-2-Clause
 | |
|  */
 | |
| 
 | |
| #include <Kernel/FileSystem/FileDescription.h>
 | |
| #include <Kernel/Process.h>
 | |
| 
 | |
| namespace Kernel {
 | |
| 
 | |
| KResultOr<FlatPtr> Process::sys$dup2(int old_fd, int new_fd)
 | |
| {
 | |
|     VERIFY_PROCESS_BIG_LOCK_ACQUIRED(this);
 | |
|     REQUIRE_PROMISE(stdio);
 | |
|     auto description = fds().file_description(old_fd);
 | |
|     if (!description)
 | |
|         return EBADF;
 | |
|     if (old_fd == new_fd)
 | |
|         return new_fd;
 | |
|     if (new_fd < 0 || static_cast<size_t>(new_fd) >= fds().max_open())
 | |
|         return EINVAL;
 | |
|     if (!m_fds.m_fds_metadatas[new_fd].is_allocated())
 | |
|         m_fds.m_fds_metadatas[new_fd].allocate();
 | |
|     m_fds[new_fd].set(*description);
 | |
|     return new_fd;
 | |
| }
 | |
| 
 | |
| }
 |