From: Victor Julien Date: Sat, 21 Jun 2025 14:10:47 +0000 (+0200) Subject: packetpool: improve thread safety X-Git-Tag: suricata-8.0.0~36 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=refs%2Fpull%2F13518%2Fhead;p=thirdparty%2Fsuricata.git packetpool: improve thread safety lock_acquire: Calling pthread_mutex_lock acquires lock PktPoolLockedStack_.mutex. 87 SCMutexLock(&my_pool->return_stack.mutex); CID 1554228: (#1 of 1): Indefinite wait (BAD_CHECK_OF_WAIT_COND) dead_wait: A wait is performed without ensuring that the condition is not already satisfied while holding lock PktPoolLockedStack_.mutex. This can cause a deadlock if the notification happens before the lock is acquired. Acquire the lock, then check the wait condition in a loop, without releasing with the lock before the wait. This will prevent deadlocks and failed conditions from spurious wakeups. --- diff --git a/src/tmqh-packetpool.c b/src/tmqh-packetpool.c index 9a812c644a..f3b387e12f 100644 --- a/src/tmqh-packetpool.c +++ b/src/tmqh-packetpool.c @@ -59,15 +59,6 @@ void TmqhPacketpoolRegister (void) tmqh_table[TMQH_PACKETPOOL].OutHandler = TmqhOutputPacketpool; } -static int PacketPoolIsEmpty(PktPool *pool) -{ - /* Check local stack first. */ - if (pool->head || pool->return_stack.head) - return 0; - - return 1; -} - static void UpdateReturnThreshold(PktPool *pool) { const float perc = (float)pool->cnt / (float)max_pending_packets; @@ -81,18 +72,18 @@ void PacketPoolWait(void) { PktPool *my_pool = GetThreadPacketPool(); - if (PacketPoolIsEmpty(my_pool)) { + if (my_pool->head == NULL) { SC_ATOMIC_SET(my_pool->return_stack.return_threshold, 1); SCMutexLock(&my_pool->return_stack.mutex); - SCCondWait(&my_pool->return_stack.cond, &my_pool->return_stack.mutex); + int rc = 0; + while (my_pool->return_stack.cnt == 0 && rc == 0) { + rc = SCCondWait(&my_pool->return_stack.cond, &my_pool->return_stack.mutex); + } SCMutexUnlock(&my_pool->return_stack.mutex); UpdateReturnThreshold(my_pool); } - - while(PacketPoolIsEmpty(my_pool)) - cc_barrier(); } /** \brief a initialized packet