aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorIan Dowse <iedowse@FreeBSD.org>2001-03-08 19:03:26 +0000
committerIan Dowse <iedowse@FreeBSD.org>2001-03-08 19:03:26 +0000
commitbfef7ed45cbdee30b500a702fd7b02c530d8c7df (patch)
treec5e5fa45525021a5fea23bd1d5247d24eafc15fb /sys
parent2239c07de9a32eb84e9974c25e2d3ba364b30ea8 (diff)
Notes
Diffstat (limited to 'sys')
-rw-r--r--sys/netinet/ip_icmp.c4
-rw-r--r--sys/netinet/ip_input.c21
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);
}