diff options
| author | Shahriyar Jalayeri <[email protected]> | 2026-07-28 08:50:08 +0200 |
|---|---|---|
| committer | Jerome Forissier <[email protected]> | 2026-07-30 13:56:26 +0200 |
| commit | 7946774a0feb40a4abc71e749e61071ffce56979 (patch) | |
| tree | 4062ba1804ea34ce2c792d65191198c7150aa1c9 | |
| parent | 04ca915d5bf39dda5d1bce62d04d2b59d293c5b9 (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.c | 36 |
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); |
