]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
packetpool: improve thread safety 13518/head
authorVictor Julien <vjulien@oisf.net>
Sat, 21 Jun 2025 14:10:47 +0000 (16:10 +0200)
committerVictor Julien <victor@inliniac.net>
Sat, 21 Jun 2025 19:32:54 +0000 (21:32 +0200)
 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.

src/tmqh-packetpool.c

index 9a812c644adba276cfb5d77a7f6e63b10f5062a5..f3b387e12fe8eaf04fae55dc9951fbc00b2e6084 100644 (file)
@@ -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