diff options
| author | Ian Dowse <iedowse@FreeBSD.org> | 2001-03-08 19:03:26 +0000 |
|---|---|---|
| committer | Ian Dowse <iedowse@FreeBSD.org> | 2001-03-08 19:03:26 +0000 |
| commit | bfef7ed45cbdee30b500a702fd7b02c530d8c7df (patch) | |
| tree | c5e5fa45525021a5fea23bd1d5247d24eafc15fb /sys | |
| parent | 2239c07de9a32eb84e9974c25e2d3ba364b30ea8 (diff) | |
Notes
Diffstat (limited to 'sys')
| -rw-r--r-- | sys/netinet/ip_icmp.c | 4 | ||||
| -rw-r--r-- | sys/netinet/ip_input.c | 21 |
2 files changed, 17 insertions, 8 deletions
diff --git a/sys/netinet/ip_icmp.c b/sys/netinet/ip_icmp.c index 5b9aa086971ab..bdcc88438ab67 100644 --- a/sys/netinet/ip_icmp.c +++ b/sys/netinet/ip_icmp.c @@ -164,6 +164,8 @@ icmp_error(n, type, code, dest, destifp) 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 @@ icmp_error(n, type, code, dest, destifp) } 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; /* diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index 9d1fe463d34e9..78753dde135be 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1563,12 +1563,21 @@ ip_forward(m, srcrt) } /* - * Save at most 64 bytes of the packet in case - * we need to generate an ICMP message to the src. + * 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(). */ - 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)); + 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 @@ ip_forward(m, srcrt) 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); } |
