Module Name:    src
Committed By:   maxv
Date:           Tue Jan 23 07:02:57 UTC 2018

Modified Files:
        src/sys/netinet6: icmp6.c

Log Message:
Style, and four fixes:

 * Remove the (disabled) IPPROTO_ESP check. If the packet was decrypted it
   will have M_DECRYPTED, and this is already checked.

 * Memory leaks in icmp6_error2. They seem hardly triggerable.

 * Fix miscomputation in _icmp6_input, the ICMP6 header is not guaranteed
   to be located right after the IP6 header. ok mlelstv@

 * Memory leak in _icmp6_input. This one seems to be impossible to trigger.


To generate a diff of this commit:
cvs rdiff -u -r1.214 -r1.215 src/sys/netinet6/icmp6.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: src/sys/netinet6/icmp6.c
diff -u src/sys/netinet6/icmp6.c:1.214 src/sys/netinet6/icmp6.c:1.215
--- src/sys/netinet6/icmp6.c:1.214	Sun Nov  5 07:03:37 2017
+++ src/sys/netinet6/icmp6.c	Tue Jan 23 07:02:57 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: icmp6.c,v 1.214 2017/11/05 07:03:37 ozaki-r Exp $	*/
+/*	$NetBSD: icmp6.c,v 1.215 2018/01/23 07:02:57 maxv Exp $	*/
 /*	$KAME: icmp6.c,v 1.217 2001/06/20 15:03:29 jinmei Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.214 2017/11/05 07:03:37 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: icmp6.c,v 1.215 2018/01/23 07:02:57 maxv Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -292,8 +292,7 @@ icmp6_error2(struct mbuf *m, int type, i
 {
 	struct ip6_hdr *ip6;
 
-	if (ifp == NULL)
-		return;
+	KASSERT(ifp != NULL);
 
 	if (m->m_len < sizeof(struct ip6_hdr)) {
 		m = m_pullup(m, sizeof(struct ip6_hdr));
@@ -304,11 +303,15 @@ icmp6_error2(struct mbuf *m, int type, i
 	ip6 = mtod(m, struct ip6_hdr *);
 
 	if (in6_setscope(&ip6->ip6_src, ifp, NULL) != 0)
-		return;
+		goto out;
 	if (in6_setscope(&ip6->ip6_dst, ifp, NULL) != 0)
-		return;
+		goto out;
 
 	icmp6_error(m, type, code, param);
+	return;
+
+out:
+	m_freem(m);
 }
 
 /*
@@ -344,7 +347,7 @@ icmp6_error(struct mbuf *m, int type, in
 	 * we should basically suppress sending an error (RFC 2463, Section
 	 * 2.4).
 	 * We have two exceptions (the item e.2 in that section):
-	 * - the Pakcet Too Big message can be sent for path MTU discovery.
+	 * - the Packet Too Big message can be sent for path MTU discovery.
 	 * - the Parameter Problem Message that can be allowed an icmp6 error
 	 *   in the option type field.  This check has been done in
 	 *   ip6_unknown_opt(), so we can just check the type and code.
@@ -391,18 +394,7 @@ icmp6_error(struct mbuf *m, int type, in
 		} else {
 			/* ICMPv6 informational - send the error */
 		}
-	}
-#if 0 /* controversial */
-	else if (off >= 0 && nxt == IPPROTO_ESP) {
-		/*
-		 * It could be ICMPv6 error inside ESP.  Take a safer side,
-		 * don't respond.
-		 */
-		ICMP6_STATINC(ICMP6_STAT_CANTERROR);
-		goto freeit;
-	}
-#endif
-	else {
+	} else {
 		/* non-ICMPv6 - send the error */
 	}
 
@@ -452,11 +444,13 @@ icmp6_error(struct mbuf *m, int type, in
 	m_reset_rcvif(m);
 
 	ICMP6_STATINC(ICMP6_STAT_OUTHIST + type);
-	icmp6_reflect(m, sizeof(struct ip6_hdr)); /* header order: IPv6 - ICMPv6 */
+
+	/* header order: IPv6 - ICMPv6 */
+	icmp6_reflect(m, sizeof(struct ip6_hdr));
 
 	return;
 
-  freeit:
+freeit:
 	/*
 	 * If we can't tell whether or not we can generate ICMP6, free it.
 	 */
@@ -473,7 +467,7 @@ _icmp6_input(struct mbuf *m, int off, in
 	struct ip6_hdr *ip6, *nip6;
 	struct icmp6_hdr *icmp6, *nicmp6;
 	int icmp6len = m->m_pkthdr.len - off;
-	int code, sum, noff;
+	int code, sum;
 	struct ifnet *rcvif;
 	struct psref psref;
 	char ip6buf[INET6_ADDRSTRLEN], ip6buf2[INET6_ADDRSTRLEN];
@@ -513,6 +507,7 @@ _icmp6_input(struct mbuf *m, int off, in
 		icmp6_ifstat_inc(rcvif, ifs6_in_error);
 		goto freeit;
 	}
+
 	/*
 	 * Enforce alignment requirements that are violated in
 	 * some cases, see kern/50766 for details.
@@ -525,7 +520,7 @@ _icmp6_input(struct mbuf *m, int off, in
 			goto freeit;
 		}
 		ip6 = mtod(m, struct ip6_hdr *);
-		icmp6 = (struct icmp6_hdr *)(ip6 + 1);
+		icmp6 = (struct icmp6_hdr *)(mtod(m, char *) + off);
 	}
 	KASSERT(IP6_HDR_ALIGNED_P(icmp6));
 
@@ -739,8 +734,6 @@ _icmp6_input(struct mbuf *m, int off, in
 			n = m_copym(m, 0, M_COPYALL, M_DONTWAIT);
 			if (n)
 				n = ni6_input(n, off);
-			/* XXX meaningless if n == NULL */
-			noff = sizeof(struct ip6_hdr);
 		} else {
 			u_char *p;
 			int maxhlen;
@@ -765,34 +758,36 @@ _icmp6_input(struct mbuf *m, int off, in
 			m_reset_rcvif(n);
 			n->m_len = 0;
 			maxhlen = M_TRAILINGSPACE(n) - ICMP6_MAXLEN;
-			if (maxhlen < 0)
+			if (maxhlen < 0) {
+				m_free(n);
 				break;
+			}
 			if (maxhlen > hostnamelen)
 				maxhlen = hostnamelen;
 			/*
 			 * Copy IPv6 and ICMPv6 only.
 			 */
 			nip6 = mtod(n, struct ip6_hdr *);
-			bcopy(ip6, nip6, sizeof(struct ip6_hdr));
+			memcpy(nip6, ip6, sizeof(struct ip6_hdr));
 			nicmp6 = (struct icmp6_hdr *)(nip6 + 1);
-			bcopy(icmp6, nicmp6, sizeof(struct icmp6_hdr));
+			memcpy(nicmp6, icmp6, sizeof(struct icmp6_hdr));
+
 			p = (u_char *)(nicmp6 + 1);
 			memset(p, 0, 4);
-			bcopy(hostname, p + 4, maxhlen); /* meaningless TTL */
-			noff = sizeof(struct ip6_hdr);
+			memcpy(p + 4, hostname, maxhlen); /* meaningless TTL */
+
 			M_COPY_PKTHDR(n, m); /* just for rcvif */
 			n->m_pkthdr.len = n->m_len = sizeof(struct ip6_hdr) +
 				sizeof(struct icmp6_hdr) + 4 + maxhlen;
 			nicmp6->icmp6_type = ICMP6_WRUREPLY;
 			nicmp6->icmp6_code = 0;
 		}
-#undef hostnamelen
 		if (n) {
 			uint64_t *icmp6s = ICMP6_STAT_GETREF();
 			icmp6s[ICMP6_STAT_REFLECT]++;
 			icmp6s[ICMP6_STAT_OUTHIST + ICMP6_WRUREPLY]++;
 			ICMP6_STAT_PUTREF();
-			icmp6_reflect(n, noff);
+			icmp6_reflect(n, sizeof(struct ip6_hdr));
 		}
 		break;
 	    }
@@ -1128,7 +1123,7 @@ icmp6_notify_error(struct mbuf *m, int o
 		ctlfunc = (void (*)(int, struct sockaddr *, void *))
 			(inet6sw[ip6_protox[nxt]].pr_ctlinput);
 		if (ctlfunc) {
-			(void) (*ctlfunc)(code, sin6tosa(&icmp6dst),
+			(void)(*ctlfunc)(code, sin6tosa(&icmp6dst),
 					  &ip6cp);
 		}
 	}
@@ -1177,8 +1172,7 @@ icmp6_mtudisc_update(struct ip6ctlparam 
 		if (0 <= icmp6_mtudisc_hiwat && rtcount > icmp6_mtudisc_hiwat) {
 			mutex_exit(&icmp6_mtx);
 			return;
-		}
-		else if (0 <= icmp6_mtudisc_lowat &&
+		} else if (0 <= icmp6_mtudisc_lowat &&
 		    rtcount > icmp6_mtudisc_lowat) {
 			/*
 			 * XXX nuke a victim, install the new one.
@@ -2121,14 +2115,14 @@ icmp6_reflect(struct mbuf *m, size_t off
 				return;
 		}
 		bcopy((void *)&nip6, mtod(m, void *), sizeof(nip6));
-	} else /* off == sizeof(struct ip6_hdr) */ {
-		size_t l;
-		l = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr);
+	} else {
+		size_t l = sizeof(struct ip6_hdr) + sizeof(struct icmp6_hdr);
 		if (m->m_len < l) {
 			if ((m = m_pullup(m, l)) == NULL)
 				return;
 		}
 	}
+
 	plen = m->m_pkthdr.len - sizeof(struct ip6_hdr);
 	ip6 = mtod(m, struct ip6_hdr *);
 	ip6->ip6_nxt = IPPROTO_ICMPV6;

Reply via email to