mirror of
				https://github.com/RGBCube/serenity
				synced 2025-10-31 04:12:43 +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(); | ||||
|     for (int fd : m_select_read_fds) { | ||||
|         if (!process.m_fds[fd]) | ||||
|             continue; | ||||
|         if (process.m_fds[fd].description->can_read()) | ||||
|             return true; | ||||
|     } | ||||
|     for (int fd : m_select_write_fds) { | ||||
|         if (!process.m_fds[fd]) | ||||
|             continue; | ||||
|         if (process.m_fds[fd].description->can_write()) | ||||
|             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