svn commit: r297989 - head/sys/netinet
Michael Tuexen
tuexen at FreeBSD.org
Thu Apr 14 19:51:30 UTC 2016
Author: tuexen
Date: Thu Apr 14 19:51:29 2016
New Revision: 297989
URL: https://svnweb.freebsd.org/changeset/base/297989
Log:
When delivering an ICMP packet to the ctlinput function, ensure that
the outer IP header, the ICMP header, the inner IP header and the
first n bytes are stored in contgous memory. The ctlinput functions
currently rely on this for n = 8. This fixes a bug in case the inner IP
header had options.
While there, remove the options from the outer header and provide a
way to increase n to allow improved ICMP handling for SCTP. This will
be added in another commit.
MFC after: 1 week
Modified:
head/sys/netinet/ip_icmp.c
head/sys/netinet/ip_icmp.h
Modified: head/sys/netinet/ip_icmp.c
==============================================================================
--- head/sys/netinet/ip_icmp.c Thu Apr 14 19:29:35 2016 (r297988)
+++ head/sys/netinet/ip_icmp.c Thu Apr 14 19:51:29 2016 (r297989)
@@ -475,6 +475,23 @@ icmp_input(struct mbuf **mp, int *offp,
* XXX if the packet contains [IPv4 AH TCP], we can't make a
* notification to TCP layer.
*/
+ i = sizeof(struct ip) + min(icmplen, ICMP_ADVLENPREF(icp));
+ ip_stripoptions(m);
+ if (m->m_len < i && (m = m_pullup(m, i)) == NULL) {
+ /* This should actually not happen */
+ ICMPSTAT_INC(icps_tooshort);
+ return (IPPROTO_DONE);
+ }
+ ip = mtod(m, struct ip *);
+ icp = (struct icmp *)(ip + 1);
+ /*
+ * The upper layer handler can rely on:
+ * - The outer IP header has no options.
+ * - The outer IP header, the ICMP header, the inner IP header,
+ * and the first n bytes of the inner payload are contiguous.
+ * n is at least 8, but might be larger based on
+ * ICMP_ADVLENPREF. See its definition in ip_icmp.h.
+ */
ctlfunc = inetsw[ip_protox[icp->icmp_ip.ip_p]].pr_ctlinput;
if (ctlfunc)
(*ctlfunc)(code, (struct sockaddr *)&icmpsrc,
Modified: head/sys/netinet/ip_icmp.h
==============================================================================
--- head/sys/netinet/ip_icmp.h Thu Apr 14 19:29:35 2016 (r297988)
+++ head/sys/netinet/ip_icmp.h Thu Apr 14 19:51:29 2016 (r297989)
@@ -136,6 +136,12 @@ struct icmp {
#define ICMP_ADVLENMIN (8 + sizeof (struct ip) + 8) /* min */
#define ICMP_ADVLEN(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8)
/* N.B.: must separately check that ip_hl >= 5 */
+ /* This is the minimum length required by RFC 792. */
+/*
+ * ICMP_ADVLENPREF is the preferred number of bytes which should be contiguous.
+ * It currently reflects the required minimum.
+ */
+#define ICMP_ADVLENPREF(p) (8 + ((p)->icmp_ip.ip_hl << 2) + 8)
/*
* Definition of type and code field values.
More information about the svn-src-all
mailing list