]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
stream: improve gap tests
authorVictor Julien <vjulien@oisf.net>
Mon, 9 Jan 2023 07:05:37 +0000 (08:05 +0100)
committerVictor Julien <vjulien@oisf.net>
Wed, 18 Jan 2023 14:28:19 +0000 (15:28 +0100)
src/stream-tcp-reassemble.c
src/tests/stream-tcp-inline.c

index 6178181a3ecb29a96604c2ae72a7fcb1a2ebd7a3..ce5f90309b2210bf684e9bb8ab453c23e413c65d 100644 (file)
@@ -2206,6 +2206,63 @@ static int VALIDATE(TcpStream *stream, uint8_t *data, uint32_t data_len)
     StreamTcpUTAddPayload(&tv, ra_ctx, &ssn, stream, (seq), (uint8_t *)(seg), (seglen));    \
     FAIL_IF(!(VALIDATE(stream, (uint8_t *)(buf), (buflen))));
 
+#define MISSED_ADD_PAYLOAD(seq, seg, seglen)                                                       \
+    StreamTcpUTAddPayload(&tv, ra_ctx, &ssn, stream, (seq), (uint8_t *)(seg), (seglen));
+
+int UTHCheckGapAtPostion(TcpStream *stream, int pos, uint64_t offset, uint32_t len);
+
+int UTHCheckGapAtPostion(TcpStream *stream, int pos, uint64_t offset, uint32_t len)
+{
+    int cnt = 0;
+    uint64_t last_re = 0;
+    StreamingBufferBlock *sbb = NULL;
+    RB_FOREACH(sbb, SBB, &stream->sb.sbb_tree)
+    {
+        if (sbb->offset != last_re) {
+            // gap before us
+            if (cnt == pos && last_re == offset && len == sbb->offset - last_re) {
+                return 1;
+            }
+            cnt++;
+        }
+        last_re = sbb->offset + sbb->len;
+        cnt++;
+    }
+    return 0;
+}
+
+int UTHCheckDataAtPostion(
+        TcpStream *stream, int pos, uint64_t offset, const char *data, uint32_t len);
+
+int UTHCheckDataAtPostion(
+        TcpStream *stream, int pos, uint64_t offset, const char *data, uint32_t len)
+{
+    int cnt = 0;
+    uint64_t last_re = 0;
+    StreamingBufferBlock *sbb = NULL;
+    RB_FOREACH(sbb, SBB, &stream->sb.sbb_tree)
+    {
+        if (sbb->offset != last_re) {
+            // gap before us
+            cnt++;
+        }
+
+        if (cnt == pos && sbb->offset == offset) {
+            const uint8_t *buf = NULL;
+            uint32_t buf_len = 0;
+            StreamingBufferSBBGetData(&stream->sb, sbb, &buf, &buf_len);
+
+            if (len == buf_len) {
+                return (memcmp(data, buf, len) == 0);
+            }
+        }
+
+        last_re = sbb->offset + sbb->len;
+        cnt++;
+    }
+    return 0;
+}
+
 /**
  *  \test   Test the handling of packets missed by both IDS and the end host.
  *          The packet is missed in the starting of the stream.
@@ -2216,10 +2273,15 @@ static int VALIDATE(TcpStream *stream, uint8_t *data, uint32_t data_len)
 static int StreamTcpReassembleTest25 (void)
 {
     MISSED_START(6);
-    MISSED_STEP(10, "BB", 2, "\0\0\0BB", 5);
-    MISSED_STEP(12, "CC", 2, "\0\0\0BBCC", 7);
+    MISSED_ADD_PAYLOAD(10, "BB", 2);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 0, 0, 3) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 1, 3, "BB", 2) == 1);
+    MISSED_ADD_PAYLOAD(12, "CC", 2);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 0, 0, 3) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 1, 3, "BBCC", 4) == 1);
     MISSED_STEP(7, "AAA", 3, "AAABBCC", 7);
     MISSED_END;
+    PASS;
 }
 
 /**
@@ -2233,7 +2295,10 @@ static int StreamTcpReassembleTest26 (void)
 {
     MISSED_START(9);
     MISSED_STEP(10, "AAA", 3, "AAA", 3);
-    MISSED_STEP(15, "CC", 2, "AAA\0\0CC", 7);
+    MISSED_ADD_PAYLOAD(15, "CC", 2);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 0, 0, "AAA", 3) == 1);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 1, 3, 2) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 2, 5, "CC", 2) == 1);
     MISSED_STEP(13, "BB", 2, "AAABBCC", 7);
     MISSED_END;
 }
@@ -2265,10 +2330,16 @@ static int StreamTcpReassembleTest27 (void)
 static int StreamTcpReassembleTest28 (void)
 {
     MISSED_START(6);
-    MISSED_STEP(10, "AAA", 3, "\0\0\0AAA", 6);
-    MISSED_STEP(13, "BB", 2, "\0\0\0AAABB", 8);
+    MISSED_ADD_PAYLOAD(10, "AAA", 3);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 0, 0, 3) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 1, 3, "AAA", 3) == 1);
+    MISSED_ADD_PAYLOAD(13, "BB", 2);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 0, 0, 3) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 1, 3, "AAABB", 5) == 1);
     ssn.state = TCP_TIME_WAIT;
-    MISSED_STEP(15, "CC", 2, "\0\0\0AAABBCC", 10);
+    MISSED_ADD_PAYLOAD(15, "CC", 2);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 0, 0, 3) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 1, 3, "AAABBCC", 7) == 1);
     MISSED_END;
 }
 
@@ -2285,7 +2356,10 @@ static int StreamTcpReassembleTest29 (void)
     MISSED_START(9);
     MISSED_STEP(10, "AAA", 3, "AAA", 3);
     ssn.state = TCP_TIME_WAIT;
-    MISSED_STEP(15, "CC", 2, "AAA\0\0CC", 7);
+    MISSED_ADD_PAYLOAD(15, "CC", 2);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 0, 0, "AAA", 3) == 1);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 1, 3, 2) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 2, 5, "CC", 2) == 1);
     MISSED_END;
 }
 
index 469889e95668a346ccdfd6ad021fd44a3ab23e20..3da4d44bf3615d832f171bc4cd6a21c4397dd82e 100644 (file)
@@ -59,16 +59,24 @@ static int VALIDATE(TcpStream *stream, uint8_t *data, uint32_t data_len)
     StreamTcpUTDeinit(ra_ctx);                  \
     PASS
 
-#define INLINE_STEP(rseq, seg, seglen, buf, buflen, packet, packetlen) \
-    p = UTHBuildPacketReal((uint8_t *)(seg), (seglen), IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);    \
-    FAIL_IF(p == NULL); \
-    p->tcph->th_seq = htonl(stream->isn + (rseq)); \
-    p->tcph->th_ack = htonl(31);  \
-    FAIL_IF (StreamTcpReassembleHandleSegmentHandleData(&tv, ra_ctx, &ssn, stream, p) < 0);   \
-    FAIL_IF (memcmp(p->payload, packet, MIN((packetlen),p->payload_len)) != 0); \
-    UTHFreePacket(p);   \
+#define INLINE_ADD_PAYLOAD(rseq, seg, seglen, packet, packetlen)                                   \
+    p = UTHBuildPacketReal(                                                                        \
+            (uint8_t *)(seg), (seglen), IPPROTO_TCP, "1.1.1.1", "2.2.2.2", 1024, 80);              \
+    FAIL_IF(p == NULL);                                                                            \
+    p->tcph->th_seq = htonl(stream->isn + (rseq));                                                 \
+    p->tcph->th_ack = htonl(31);                                                                   \
+    FAIL_IF(StreamTcpReassembleHandleSegmentHandleData(&tv, ra_ctx, &ssn, stream, p) < 0);         \
+    FAIL_IF(memcmp(p->payload, packet, MIN((packetlen), p->payload_len)) != 0);                    \
+    UTHFreePacket(p);
+
+#define INLINE_STEP(rseq, seg, seglen, buf, buflen, packet, packetlen)                             \
+    INLINE_ADD_PAYLOAD((rseq), (seg), (seglen), (packet), (packetlen));                            \
     FAIL_IF(!(VALIDATE(stream, (uint8_t *)(buf), (buflen))));
 
+int UTHCheckGapAtPostion(TcpStream *stream, int pos, uint64_t offset, uint32_t len);
+int UTHCheckDataAtPostion(
+        TcpStream *stream, int pos, uint64_t offset, const char *data, uint32_t len);
+
 /** \test full overlap */
 static int StreamTcpInlineTest01(void)
 {
@@ -100,7 +108,9 @@ static int StreamTcpInlineTest03(void)
 static int StreamTcpInlineTest04(void)
 {
     INLINE_START(0);
-    INLINE_STEP(3, "ABCDE", 5, "\0\0ABCDE", 7, "ABCDE", 5);
+    INLINE_ADD_PAYLOAD(3, "ABCDE", 5, "ABCDE", 5);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 0, 0, 2) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 1, 2, "ABCDE", 5) == 1);
     INLINE_STEP(1, "xxxxx", 5, "xxABCDE", 7, "xxABC", 5);
     INLINE_END;
 }
@@ -109,8 +119,13 @@ static int StreamTcpInlineTest04(void)
 static int StreamTcpInlineTest05(void)
 {
     INLINE_START(0);
-    INLINE_STEP(8, "ABCDE", 5, "\0\0\0\0\0\0\0ABCDE", 12, "ABCDE", 5);
-    INLINE_STEP(1, "xxxxx", 5, "xxxxx\0\0ABCDE", 12, "xxxxx", 5);
+    INLINE_ADD_PAYLOAD(8, "ABCDE", 5, "ABCDE", 5);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 0, 0, 7) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 1, 7, "ABCDE", 5) == 1);
+    INLINE_ADD_PAYLOAD(1, "xxxxx", 5, "xxxxx", 5);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 0, 0, "xxxxx", 5) == 1);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 1, 5, 2) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 2, 7, "ABCDE", 5) == 1);
     INLINE_END;
 }
 
@@ -118,10 +133,30 @@ static int StreamTcpInlineTest05(void)
 static int StreamTcpInlineTest06(void)
 {
     INLINE_START(0);
-    INLINE_STEP(2, "A", 1, "\0A", 2, "A", 1);
-    INLINE_STEP(4, "A", 1, "\0A\0A", 4, "A", 1);
-    INLINE_STEP(6, "A", 1, "\0A\0A\0A", 6, "A", 1);
-    INLINE_STEP(8, "A", 1, "\0A\0A\0A\0A", 8, "A", 1);
+    INLINE_ADD_PAYLOAD(2, "A", 1, "A", 1);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 0, 0, 1) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 1, 1, "A", 1) == 1);
+    INLINE_ADD_PAYLOAD(4, "A", 1, "A", 1);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 0, 0, 1) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 1, 1, "A", 1) == 1);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 2, 2, 1) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 3, 3, "A", 1) == 1);
+    INLINE_ADD_PAYLOAD(6, "A", 1, "A", 1);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 0, 0, 1) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 1, 1, "A", 1) == 1);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 2, 2, 1) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 3, 3, "A", 1) == 1);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 4, 4, 1) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 5, 5, "A", 1) == 1);
+    INLINE_ADD_PAYLOAD(8, "A", 1, "A", 1);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 0, 0, 1) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 1, 1, "A", 1) == 1);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 2, 2, 1) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 3, 3, "A", 1) == 1);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 4, 4, 1) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 5, 5, "A", 1) == 1);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 6, 6, 1) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 7, 7, "A", 1) == 1);
     INLINE_STEP(1, "xxxxxxxxx", 9, "xAxAxAxAx", 9, "xAxAxAxAx", 9);
     INLINE_END;
 }
@@ -130,7 +165,9 @@ static int StreamTcpInlineTest06(void)
 static int StreamTcpInlineTest07(void)
 {
     INLINE_START(0);
-    INLINE_STEP(3, "ABCDE", 5, "\0\0ABCDE", 7, "ABCDE", 5);
+    INLINE_ADD_PAYLOAD(3, "ABCDE", 5, "ABCDE", 5);
+    FAIL_IF_NOT(UTHCheckGapAtPostion(stream, 0, 0, 2) == 1);
+    FAIL_IF_NOT(UTHCheckDataAtPostion(stream, 1, 2, "ABCDE", 5) == 1);
     INLINE_STEP(1, "XXABC", 5, "XXABCDE", 7, "XXABC", 5);
     INLINE_END;
 }