mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -05:00 
			
		
		
		
	support: loop_enter/leave hardening
This commit adds a counter for loop_enter/leave and checks: - consecutive enter are used on the same thread - leave is used on the same thread as enter - at destruction, the enter_count must be 0
This commit is contained in:
		
							parent
							
								
									834ecd733d
								
							
						
					
					
						commit
						0b637c3291
					
				
					 1 changed files with 24 additions and 2 deletions
				
			
		| 
						 | 
					@ -79,6 +79,7 @@ struct impl {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	int poll_fd;
 | 
						int poll_fd;
 | 
				
			||||||
	pthread_t thread;
 | 
						pthread_t thread;
 | 
				
			||||||
 | 
						int enter_count;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	struct spa_poll_event dispatching[MAX_EP];
 | 
						struct spa_poll_event dispatching[MAX_EP];
 | 
				
			||||||
	uint32_t n_dispatching;
 | 
						uint32_t n_dispatching;
 | 
				
			||||||
| 
						 | 
					@ -297,14 +298,31 @@ loop_add_hook(void *object,
 | 
				
			||||||
static void loop_enter(void *object)
 | 
					static void loop_enter(void *object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *impl = object;
 | 
						struct impl *impl = object;
 | 
				
			||||||
	impl->thread = pthread_self();
 | 
						pthread_t thread_id = pthread_self();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (impl->enter_count == 0) {
 | 
				
			||||||
 | 
							spa_return_if_fail(impl->thread == 0);
 | 
				
			||||||
 | 
							impl->thread = thread_id;
 | 
				
			||||||
 | 
							impl->enter_count = 1;
 | 
				
			||||||
 | 
						} else {
 | 
				
			||||||
 | 
							spa_return_if_fail(impl->enter_count > 0);
 | 
				
			||||||
 | 
							spa_return_if_fail(impl->thread == thread_id);
 | 
				
			||||||
 | 
							impl->enter_count++;
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
	spa_log_trace(impl->log, "%p: enter %lu", impl, impl->thread);
 | 
						spa_log_trace(impl->log, "%p: enter %lu", impl, impl->thread);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static void loop_leave(void *object)
 | 
					static void loop_leave(void *object)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
	struct impl *impl = object;
 | 
						struct impl *impl = object;
 | 
				
			||||||
 | 
						pthread_t thread_id = pthread_self();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						spa_return_if_fail(impl->enter_count > 0);
 | 
				
			||||||
 | 
						spa_return_if_fail(impl->thread == thread_id);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_log_trace(impl->log, "%p: leave %lu", impl, impl->thread);
 | 
						spa_log_trace(impl->log, "%p: leave %lu", impl, impl->thread);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (--impl->enter_count == 0)
 | 
				
			||||||
		impl->thread = 0;
 | 
							impl->thread = 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -755,6 +773,10 @@ static int impl_clear(struct spa_handle *handle)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	impl = (struct impl *) handle;
 | 
						impl = (struct impl *) handle;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						if (impl->enter_count != 0)
 | 
				
			||||||
 | 
							spa_log_warn(impl->log, "%p: loop is entered %d times",
 | 
				
			||||||
 | 
									impl, impl->enter_count);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	spa_list_consume(source, &impl->source_list, link)
 | 
						spa_list_consume(source, &impl->source_list, link)
 | 
				
			||||||
		loop_destroy_source(impl, &source->source);
 | 
							loop_destroy_source(impl, &source->source);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue