Files
meta-security/recipes-ids/suricata/files/CVE-2024-32867-004.patch
Hitendra Prajapati 79a9354c92 suricata: Fix multiple CVEs
Backport fixes for:

* CVE-2024-32663 - Upstream-Status: Backport from e68ec4b227 && c0af92295e
* CVE-2024-32664 - Upstream-Status: Backport from d5ffecf11a
* CVE-2024-32867 - Upstream-Status: Backport from 2f39ba75f1 && 7137d5e7ab && 1e110d0a71 && e6267758ed

Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
Signed-off-by: Scott Murray <scott.murray@konsulko.com>
2025-11-24 19:04:14 +02:00

170 lines
5.3 KiB
Diff

From e6267758ed5da27f804f0c1c07f9423bdf4d72b8 Mon Sep 17 00:00:00 2001
From: Jason Ish <jason.ish@oisf.net>
Date: Fri, 12 Jan 2024 11:09:59 -0600
Subject: [PATCH] defrag: fix check for complete packet
The list of fragments may still contain overlaps, so adding up the
fragment lengths is flawed. Instead track the largest size of
contiguous data that can be re-assembled.
Bug: #6675
(cherry picked from commit d226d0a3fce8837936e1bdfaee496c80d417e0a5)
CVE: CVE-2024-32867
Upstream-Status: Backport [https://github.com/OISF/suricata/commit/e6267758ed5da27f804f0c1c07f9423bdf4d72b8]
Signed-off-by: Hitendra Prajapati <hprajapati@mvista.com>
---
src/defrag.c | 116 ++++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 114 insertions(+), 2 deletions(-)
diff --git a/src/defrag.c b/src/defrag.c
index 28d085d..fc46411 100644
--- a/src/defrag.c
+++ b/src/defrag.c
@@ -276,7 +276,8 @@ Defrag4Reassemble(ThreadVars *tv, DefragTracker *tracker, Packet *p)
goto done;
}
else {
- len += frag->data_len;
+ /* Update the packet length to the largest known data offset. */
+ len = MAX(len, frag->offset + frag->data_len);
}
}
@@ -434,7 +435,7 @@ Defrag6Reassemble(ThreadVars *tv, DefragTracker *tracker, Packet *p)
goto done;
}
else {
- len += frag->data_len;
+ len = MAX(len, frag->offset + frag->data_len);
}
}
}
@@ -3000,6 +3001,115 @@ static int DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test(void)
PASS;
}
+/**
+ * Reassembly should fail.
+ *
+ * |0 |8 |16 |24 |32 |40 |48 |
+ * |========|========|========|========|========|========|========|
+ * | | |AABBCCDD|AABBDDCC| | | |
+ * | | | | | |AACCBBDD| |
+ * | |AACCDDBB|AADDBBCC| | | | |
+ * |ZZZZZZZZ| | | | | | |
+ * | | | | | | |DDCCBBAA|
+ */
+static int DefragBsdMissingFragmentIpv4Test(void)
+{
+ DefragInit();
+ default_policy = DEFRAG_POLICY_BSD;
+ Packet *packets[5];
+
+ packets[0] = BuildIpv4TestPacketWithContent(
+ IPPROTO_ICMP, 189, 16 >> 3, 1, (uint8_t *)"AABBCCDDAABBDDCC", 16);
+
+ packets[1] =
+ BuildIpv4TestPacketWithContent(IPPROTO_ICMP, 189, 40 >> 3, 1, (uint8_t *)"AACCBBDD", 8);
+
+ packets[2] = BuildIpv4TestPacketWithContent(
+ IPPROTO_ICMP, 189, 8 >> 3, 1, (uint8_t *)"AACCDDBBAADDBBCC", 16);
+
+ /* ICMP header. */
+ packets[3] = BuildIpv4TestPacketWithContent(IPPROTO_ICMP, 189, 0, 1, (uint8_t *)"ZZZZZZZZ", 8);
+
+ packets[4] =
+ BuildIpv4TestPacketWithContent(IPPROTO_ICMP, 189, 48 >> 3, 0, (uint8_t *)"DDCCBBAA", 8);
+
+ Packet *r = Defrag(NULL, NULL, packets[0]);
+ FAIL_IF_NOT_NULL(r);
+
+ r = Defrag(NULL, NULL, packets[1]);
+ FAIL_IF_NOT_NULL(r);
+
+ r = Defrag(NULL, NULL, packets[2]);
+ FAIL_IF_NOT_NULL(r);
+
+ r = Defrag(NULL, NULL, packets[3]);
+ FAIL_IF_NOT_NULL(r);
+
+ r = Defrag(NULL, NULL, packets[4]);
+ FAIL_IF_NOT_NULL(r);
+
+#if 0
+ PrintRawDataFp(stdout, GET_PKT_DATA(r) + 20, GET_PKT_LEN(r) - 20);
+#endif
+
+ for (int i = 0; i < 5; i++) {
+ SCFree(packets[i]);
+ }
+
+ DefragDestroy();
+
+ PASS;
+}
+
+static int DefragBsdMissingFragmentIpv6Test(void)
+{
+ DefragInit();
+ default_policy = DEFRAG_POLICY_BSD;
+ Packet *packets[5];
+
+ packets[0] = BuildIpv6TestPacketWithContent(
+ IPPROTO_ICMP, 189, 16 >> 3, 1, (uint8_t *)"AABBCCDDAABBDDCC", 16);
+
+ packets[1] =
+ BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 189, 40 >> 3, 1, (uint8_t *)"AACCBBDD", 8);
+
+ packets[2] = BuildIpv6TestPacketWithContent(
+ IPPROTO_ICMP, 189, 8 >> 3, 1, (uint8_t *)"AACCDDBBAADDBBCC", 16);
+
+ /* ICMP header. */
+ packets[3] = BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 189, 0, 1, (uint8_t *)"ZZZZZZZZ", 8);
+
+ packets[4] =
+ BuildIpv6TestPacketWithContent(IPPROTO_ICMP, 189, 48 >> 3, 0, (uint8_t *)"DDCCBBAA", 8);
+
+ Packet *r = Defrag(NULL, NULL, packets[0]);
+ FAIL_IF_NOT_NULL(r);
+
+ r = Defrag(NULL, NULL, packets[1]);
+ FAIL_IF_NOT_NULL(r);
+
+ r = Defrag(NULL, NULL, packets[2]);
+ FAIL_IF_NOT_NULL(r);
+
+ r = Defrag(NULL, NULL, packets[3]);
+ FAIL_IF_NOT_NULL(r);
+
+ r = Defrag(NULL, NULL, packets[4]);
+ FAIL_IF_NOT_NULL(r);
+
+#if 0
+ PrintRawDataFp(stdout, GET_PKT_DATA(r) + 40, GET_PKT_LEN(r) - 40);
+#endif
+
+ for (int i = 0; i < 5; i++) {
+ SCFree(packets[i]);
+ }
+
+ DefragDestroy();
+
+ PASS;
+}
+
#endif /* UNITTESTS */
void DefragRegisterTests(void)
@@ -3048,5 +3158,7 @@ void DefragRegisterTests(void)
DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test);
UtRegisterTest("DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test_2", DefragBsdSubsequentOverlapsStartOfOriginalIpv4Test_2);
UtRegisterTest("DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test_2", DefragBsdSubsequentOverlapsStartOfOriginalIpv6Test_2);
+ UtRegisterTest("DefragBsdMissingFragmentIpv4Test", DefragBsdMissingFragmentIpv4Test);
+ UtRegisterTest("DefragBsdMissingFragmentIpv6Test", DefragBsdMissingFragmentIpv6Test);
#endif /* UNITTESTS */
}
--
2.50.1