From d9d1f1cffbc9ae3caed379c44130adf05dd654a8 Mon Sep 17 00:00:00 2001 From: James Rouzier Date: Tue, 28 Oct 2014 17:13:43 -0400 Subject: [PATCH] Lock thread_pool.wait_mutex before forking to avoid a race condition between rad_fork, rad_waitpid and reap_children. There is a race condition that can occur under high load where a child is reaped before being added to the waiters list. --- src/main/threads.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/main/threads.c b/src/main/threads.c index 72d849fc03..d4de4ff436 100644 --- a/src/main/threads.c +++ b/src/main/threads.c @@ -1142,6 +1142,7 @@ pid_t rad_fork(void) /* * Fork & save the PID for later reaping. */ + pthread_mutex_lock(&thread_pool.wait_mutex); child_pid = fork(); if (child_pid > 0) { int rcode; @@ -1152,9 +1153,7 @@ pid_t rad_fork(void) tf->pid = child_pid; - pthread_mutex_lock(&thread_pool.wait_mutex); rcode = fr_hash_table_insert(thread_pool.waiters, tf); - pthread_mutex_unlock(&thread_pool.wait_mutex); if (!rcode) { radlog(L_ERR, "Failed to store PID, creating what will be a zombie process %d", @@ -1162,6 +1161,12 @@ pid_t rad_fork(void) free(tf); } } + /* + * Do not unlock in child process + */ + if(child_pid != 0 ) { + pthread_mutex_unlock(&thread_pool.wait_mutex); + } /* * Return whatever we were told. -- 2.47.2