]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
nfq: be sure to always verdict packets
authorEric Leblond <eric@regit.org>
Wed, 19 Jun 2013 09:14:22 +0000 (11:14 +0200)
committerVictor Julien <victor@inliniac.net>
Thu, 4 Jul 2013 16:00:13 +0000 (18:00 +0200)
To be sure to always verdict packets (bug #769), this patch adds
a ReleaseData function to NFQ packets. The release function simply
drop the packet if it has not been verdicted before.

src/source-nfq.c
src/source-nfq.h

index 89d4e48c3fbde491bd16959763d2118ecd813e5e..9d637a9aeea4f359f7bddeb52edace35eab60ef3 100644 (file)
@@ -149,6 +149,8 @@ TmEcode VerdictNFQThreadDeinit(ThreadVars *, void *);
 TmEcode DecodeNFQ(ThreadVars *, Packet *, void *, PacketQueue *, PacketQueue *);
 TmEcode DecodeNFQThreadInit(ThreadVars *, void *, void **);
 
+TmEcode NFQSetVerdict(Packet *p);
+
 typedef enum NFQMode_ {
     NFQ_ACCEPT_MODE,
     NFQ_REPEAT_MODE,
@@ -392,7 +394,13 @@ static inline void NFQMutexInit(NFQQueueVars *nq)
         SCMutexUnlock(&(nq)->mutex_qh); \
 } while (0)
 
-
+/**
+ * \brief Read data from nfq message and setup Packet
+ *
+ * \note
+ * In case of error, this function verdict the packet
+ * to avoid skb to get stuck in kernel.
+ */
 int NFQSetupPkt (Packet *p, struct nfq_q_handle *qh, void *data)
 {
     struct nfq_data *tb = (struct nfq_data *)data;
@@ -427,6 +435,7 @@ int NFQSetupPkt (Packet *p, struct nfq_q_handle *qh, void *data)
     }
     p->nfq_v.ifi  = nfq_get_indev(tb);
     p->nfq_v.ifo  = nfq_get_outdev(tb);
+    p->nfq_v.verdicted = 0;
 
 #ifdef NFQ_GET_PAYLOAD_SIGNED
     ret = nfq_get_payload(tb, &pktdata);
@@ -464,6 +473,15 @@ int NFQSetupPkt (Packet *p, struct nfq_q_handle *qh, void *data)
     return 0;
 }
 
+TmEcode NFQReleaseData(ThreadVars *t, Packet *p)
+{
+    if (unlikely(!p->nfq_v.verdicted)) {
+        PACKET_UPDATE_ACTION(p, ACTION_DROP);
+        NFQSetVerdict(p);
+    }
+    return TM_ECODE_OK;
+}
+
 static int NFQCallBack(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
                        struct nfq_data *nfa, void *data)
 {
@@ -487,11 +505,14 @@ static int NFQCallBack(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
         nfq_q->pkts++;
         nfq_q->bytes += GET_PKT_LEN(p);
 #endif /* COUNTERS */
-        /* recycle Packet and leave */
+        /* NFQSetupPkt is issuing a verdict
+           so we only recycle Packet and leave */
         TmqhOutputPacketpool(tv, p);
         return 0;
     }
 
+    p->ReleaseData = NFQReleaseData;
+
 #ifdef COUNTERS
     NFQQueueVars *nfq_q = NFQGetQueue(ntv->nfq_index);
     nfq_q->pkts++;
@@ -1000,6 +1021,8 @@ TmEcode NFQSetVerdict(Packet *p) {
      *  wipeout
      */
 
+    p->nfq_v.verdicted = 1;
+
     /* can't verdict a "fake" packet */
     if (p->flags & PKT_PSEUDO_STREAM_END) {
         return TM_ECODE_OK;
index b392add2094e70380f3ec123f8f987e35db31805..41a54b78d1959a193dd397f72d17662170279da7 100644 (file)
@@ -43,6 +43,7 @@ typedef struct NFQPacketVars_
 {
     int id; /* this nfq packets id */
     uint16_t nfq_index; /* index in NFQ array */
+    uint8_t verdicted;
 
     uint32_t mark;
     uint32_t ifi;