[PATCH v2 2/2] test: net: add regression test for IP reassembly overflow

Shahriyar Jalayeri <[email protected]>
Newsgroups gmane.comp.boot-loaders.u-boot
Message-ID <[email protected]>
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]>
---
 test/dm/net_defrag.c | 36 ++++++++++++++++++++++++++++++++++++
 1 file changed, 36 insertions(+)

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);

-- 
2.43.0
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.