summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShahriyar Jalayeri <[email protected]>2026-07-28 08:50:08 +0200
committerJerome Forissier <[email protected]>2026-07-30 13:56:26 +0200
commit7946774a0feb40a4abc71e749e61071ffce56979 (patch)
tree4062ba1804ea34ce2c792d65191198c7150aa1c9
parent04ca915d5bf39dda5d1bce62d04d2b59d293c5b9 (diff)
test: net: add regression test for IP reassembly overflow
Add a DM test that feeds __net_defragment() a single crafted fragment whose trailing hole descriptor lands just past pkt_buff. Without the preceding fix the 8-byte hole write goes out of bounds; with it the fragment is dropped and no datagram is delivered. Signed-off-by: Shahriyar Jalayeri <[email protected]> Acked-by: Jerome Forissier <[email protected]>
-rw-r--r--test/dm/net_defrag.c36
1 files changed, 36 insertions, 0 deletions
diff --git a/test/dm/net_defrag.c b/test/dm/net_defrag.c
index 3fd40de90cd..7501b252db9 100644
--- a/test/dm/net_defrag.c
+++ b/test/dm/net_defrag.c
@@ -80,3 +80,39 @@ static int dm_test_net_ip_defrag_dup_last(struct unit_test_state *uts)
}
DM_TEST(dm_test_net_ip_defrag_dup_last, 0);
+
+/*
+ * A fragment placed at the very top of the reassembly buffer takes the
+ * split-hole branch, which writes an 8-byte "struct hole" at
+ * pkt_buff + IP_HDR_SIZE + (offset8 + len / 8) * 8. With start + len equal to
+ * IP_MAXUDP that write reaches the end of pkt_buff and spills past it. pkt_buff
+ * is a static array, so this is flagged under AddressSanitizer; the fix rejects
+ * such a fragment instead. The datagram is incomplete, so nothing is delivered
+ * either way.
+ */
+static int dm_test_net_ip_defrag_oob(struct unit_test_state *uts)
+{
+ rxhand_f *saved_handler = net_get_udp_handler();
+ uchar frame[FRAME_LEN];
+ struct ip_udp_hdr *ip = (struct ip_udp_hdr *)(frame + ETHER_HDR_SIZE);
+ u16 payload[4] = { 0, 0, 0, 0 };
+ /* Offset (8-byte units) so that start + FRAG_LEN == IP_MAXUDP. */
+ u16 off8 = (CONFIG_NET_MAXDEFRAG - IP_HDR_SIZE - FRAG_LEN) / 8;
+
+ udp_rx_count = 0;
+ net_set_udp_handler(defrag_udp_handler);
+
+ build_frag(frame, IP_FLAGS_MFRAG | off8, payload);
+ /* A distinct id forces a fresh reassembly independent of earlier tests. */
+ ip->ip_id = htons(0x7abc);
+ ip->ip_sum = 0;
+ ip->ip_sum = compute_ip_checksum(ip, IP_HDR_SIZE);
+ net_process_received_packet(frame, FRAME_LEN);
+
+ ut_asserteq(0, udp_rx_count);
+
+ net_set_udp_handler(saved_handler);
+
+ return 0;
+}
+DM_TEST(dm_test_net_ip_defrag_oob, 0);