mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 10:42:45 +00:00 
			
		
		
		
	Kernel: Ignore closed fd's when considering select() unblock
This fixes a null RefPtr deref (which asserts) in the scheduler if a file descriptor being select()'ed is closed by a second thread while blocked in select(). Test: Kernel/null-deref-close-during-select.cpp
This commit is contained in:
		
							parent
							
								
									e23f05a157
								
							
						
					
					
						commit
						76c20642f0
					
				
					 2 changed files with 40 additions and 0 deletions
				
			
		|  | @ -179,10 +179,14 @@ bool Thread::SelectBlocker::should_unblock(Thread& thread, time_t now_sec, long | ||||||
| 
 | 
 | ||||||
|     auto& process = thread.process(); |     auto& process = thread.process(); | ||||||
|     for (int fd : m_select_read_fds) { |     for (int fd : m_select_read_fds) { | ||||||
|  |         if (!process.m_fds[fd]) | ||||||
|  |             continue; | ||||||
|         if (process.m_fds[fd].description->can_read()) |         if (process.m_fds[fd].description->can_read()) | ||||||
|             return true; |             return true; | ||||||
|     } |     } | ||||||
|     for (int fd : m_select_write_fds) { |     for (int fd : m_select_write_fds) { | ||||||
|  |         if (!process.m_fds[fd]) | ||||||
|  |             continue; | ||||||
|         if (process.m_fds[fd].description->can_write()) |         if (process.m_fds[fd].description->can_write()) | ||||||
|             return true; |             return true; | ||||||
|     } |     } | ||||||
|  |  | ||||||
							
								
								
									
										36
									
								
								Tests/Kernel/null-deref-close-during-select.cpp
									
										
									
									
									
										Normal file
									
								
							
							
						
						
									
										36
									
								
								Tests/Kernel/null-deref-close-during-select.cpp
									
										
									
									
									
										Normal file
									
								
							|  | @ -0,0 +1,36 @@ | ||||||
|  | #include <pthread.h> | ||||||
|  | #include <stdio.h> | ||||||
|  | #include <sys/select.h> | ||||||
|  | #include <unistd.h> | ||||||
|  | 
 | ||||||
|  | int pipefds[2]; | ||||||
|  | 
 | ||||||
|  | int main(int, char**) | ||||||
|  | { | ||||||
|  |     pipe(pipefds); | ||||||
|  | 
 | ||||||
|  |     pthread_t tid; | ||||||
|  |     pthread_create( | ||||||
|  |         &tid, nullptr, [](void*) -> void* { | ||||||
|  |             sleep(1); | ||||||
|  |             printf("ST: close()\n"); | ||||||
|  |             close(pipefds[1]); | ||||||
|  |             pthread_exit(nullptr); | ||||||
|  |             return nullptr; | ||||||
|  |         }, | ||||||
|  |         nullptr); | ||||||
|  | 
 | ||||||
|  |     fd_set rfds; | ||||||
|  |     FD_ZERO(&rfds); | ||||||
|  |     FD_SET(pipefds[1], &rfds); | ||||||
|  | 
 | ||||||
|  |     printf("MT: select()\n"); | ||||||
|  |     int rc = select(pipefds[1] + 1, &rfds, nullptr, nullptr, nullptr); | ||||||
|  |     if (rc < 0) { | ||||||
|  |         perror("select"); | ||||||
|  |         return 1; | ||||||
|  |     } | ||||||
|  | 
 | ||||||
|  |     printf("ok\n"); | ||||||
|  |     return 0; | ||||||
|  | } | ||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 Andreas Kling
						Andreas Kling