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