Skip site navigation (1)Skip section navigation (2)
Date:      Thu, 12 Apr 2001 16:33:11 +0100
From:      Ian Dowse <iedowse@maths.tcd.ie>
To:        Stas Kisel <stask@tiger.unisquad.com>
Cc:        freebsd-bugs@freebsd.org, iedowse@maths.tcd.ie
Subject:   Re: kern/24608: FreeBSD 4.2 Panics in Realtek rl driver 
Message-ID:   <200104121633.aa05357@salmon.maths.tcd.ie>
In-Reply-To: Your message of "Thu, 12 Apr 2001 08:00:13 PDT." <200104121500.f3CF0DY97211@freefall.freebsd.org> 

next in thread | previous in thread | raw e-mail | index | archive | help
In message <200104121500.f3CF0DY97211@freefall.freebsd.org>, Stas Kisel writes:

> 3. Here is the offending mbuf:
> (kgdb) p *mmbfree
> $3 = {m_hdr = {mh_next = 0x5ac08d00, mh_nextpkt = 0x0, 
>                          ^^^^^^^^^^ - here is wrong value

This looks like the symptoms of the icmp_error problem that was
fixed recently. This bug caused the two upper bytes of mh_next to
get swapped, i.e. 0xc05a8d00->0x5ac08d00. Try either updating to
a more recent -stable, or apply the following patch in
/usr/src/sys/netinet:

Ian

--- ip_icmp.c	2001/02/23 20:51:46	1.53
+++ ip_icmp.c	2001/03/08 19:03:26	1.54
@@ -164,6 +164,8 @@
 	if (m == NULL)
 		goto freeit;
 	icmplen = min(oiplen + 8, oip->ip_len);
+	if (icmplen < sizeof(struct ip))
+		panic("icmp_error: bad length");
 	m->m_len = icmplen + ICMP_MINLEN;
 	MH_ALIGN(m, m->m_len);
 	icp = mtod(m, struct icmp *);
@@ -189,7 +191,7 @@
 	}
 
 	icp->icmp_code = code;
-	bcopy((caddr_t)oip, (caddr_t)&icp->icmp_ip, icmplen);
+	m_copydata(n, 0, icmplen, (caddr_t)&icp->icmp_ip);
 	nip = &icp->icmp_ip;
 
 	/*
--- ip_input.c	2001/03/05 22:40:27	1.161
+++ ip_input.c	2001/03/08 19:03:26	1.162
@@ -1563,12 +1563,21 @@
 	}
 
 	/*
-	 * Save at most 64 bytes of the packet in case
-	 * we need to generate an ICMP message to the src.
-	 */
-	mcopy = m_copy(m, 0, imin((int)ip->ip_len, 64));
-	if (mcopy && (mcopy->m_flags & M_EXT))
-		m_copydata(mcopy, 0, sizeof(struct ip), mtod(mcopy, caddr_t));
+	 * Save the IP header and at most 8 bytes of the payload,
+	 * in case we need to generate an ICMP message to the src.
+	 *
+	 * We don't use m_copy() because it might return a reference
+	 * to a shared cluster. Both this function and ip_output()
+	 * assume exclusive access to the IP header in `m', so any
+	 * data in a cluster may change before we reach icmp_error().
+	 */
+	MGET(mcopy, M_DONTWAIT, m->m_type);
+	if (mcopy != NULL) {
+		M_COPY_PKTHDR(mcopy, m);
+		mcopy->m_len = imin((IP_VHL_HL(ip->ip_vhl) << 2) + 8,
+		    (int)ip->ip_len);
+		m_copydata(m, 0, mcopy->m_len, mtod(mcopy, caddr_t));
+	}
 
 #ifdef IPSTEALTH
 	if (!ipstealth) {
@@ -1715,8 +1724,6 @@
 		m_freem(mcopy);
 		return;
 	}
-	if (mcopy->m_flags & M_EXT)
-		m_copyback(mcopy, 0, sizeof(struct ip), mtod(mcopy, caddr_t));
 	icmp_error(mcopy, type, code, dest, destifp);
 }
 



To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-bugs" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi? <200104121633.aa05357>