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 <shahriyar@byteray.co.uk>
Acked-by: Jerome Forissier <jerome.forissier@arm.com>
This commit is contained in:
Shahriyar Jalayeri
2026-07-30 13:56:26 +02:00
committed by Jerome Forissier
parent 04ca915d5b
commit 7946774a0f
+36
View File
@@ -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);