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>