]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
af-packet: fix possible infinite loop. 154/head
authorEric Leblond <eric@regit.org>
Sun, 14 Oct 2012 17:24:22 +0000 (19:24 +0200)
committerEric Leblond <eric@regit.org>
Tue, 30 Oct 2012 15:56:11 +0000 (16:56 +0100)
If no packet arrives to a capture thread, it is possible that the
AFPReadLoop() function goes into an infinite loop. This could cause
suricata to hang at exit on non busy system.
This patch adds a counter to detect when Suricata start looping in
the ring to stop when it reaches this point.

src/source-af-packet.c

index 446c9749a9e38026e2e3ae6db779c64fe99bb6dc..2591ea20c9077fd030f77951f0ea93279bd999d5 100644 (file)
@@ -676,6 +676,7 @@ int AFPReadFromRing(AFPThreadVars *ptv)
     struct sockaddr_ll *from;
     uint8_t emergency_flush = 0;
     int read_pkts = 0;
+    int loop_start = -1;
 
 
     /* Loop till we have packets available */
@@ -688,10 +689,15 @@ int AFPReadFromRing(AFPThreadVars *ptv)
 
         if (h.h2->tp_status == TP_STATUS_KERNEL) {
             if (read_pkts == 0) {
-               if (++ptv->frame_offset >= ptv->req.tp_frame_nr) {
-                   ptv->frame_offset = 0;
-               }
-               continue;
+                if (loop_start == -1) {
+                    loop_start = ptv->frame_offset;
+                } else if (unlikely(loop_start == (int)ptv->frame_offset)) {
+                    SCReturnInt(AFP_READ_OK);
+                }
+                if (++ptv->frame_offset >= ptv->req.tp_frame_nr) {
+                    ptv->frame_offset = 0;
+                }
+                continue;
             }
             if ((emergency_flush) && (ptv->flags & AFP_EMERGENCY_MODE)) {
                 SCReturnInt(AFP_KERNEL_DROP);
@@ -701,6 +707,7 @@ int AFPReadFromRing(AFPThreadVars *ptv)
         }
 
         read_pkts++;
+        loop_start = -1;
 
         /* Our packet is still used by suricata, we exit read loop to
          * gain some time */