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>
