CVS commit: [netbsd-7-1] src/sys/netinet6

2020-04-15 Thread Martin Husemann
Module Name:src
Committed By:   martin
Date:   Wed Apr 15 14:58:41 UTC 2020

Modified Files:
src/sys/netinet6 [netbsd-7-1]: nd6_rtr.c

Log Message:
Pull up following revision(s) (requested by kim in ticket #1727):

sys/netinet6/nd6_rtr.c: revision 1.148 (via patch)

Fix default route selection

The primary issue was that in revision 1.79 a check was added in the
nd6_defrouter_select() search loop to ignore the entry if RA processing
is enabled on its interface.  In practice this results in all entries
being ignored.

This fix reverses the condition, so that an entry is ignored when RA
processing is NOT enabled on its interface.  Further, the entry is
only ignored for being selected as the default router.  The currently
installed router must be identified regardless of the (current) status
of its interface, so that we can delete the route before installing a
new one.

I also added error logging when adding or deleting a route fails. This
should help the administrator (or kernel developer) in noticing possible
problems.

Finally, if deleting a route fails, the corresponding default route
entry no longer has its "installed" flag cleared, so that deletion will
be retried.  At a minimum, this will cause repeated messages about the
failed deletion as opposed to only getting repeated messages about the
installation of a new default route failing.

Fixes PR kern/55091 and also PR bin/54997 as far as the behaviour
observed with ndp(8).


To generate a diff of this commit:
cvs rdiff -u -r1.93.2.3 -r1.93.2.3.6.1 src/sys/netinet6/nd6_rtr.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/nd6_rtr.c
diff -u src/sys/netinet6/nd6_rtr.c:1.93.2.3 src/sys/netinet6/nd6_rtr.c:1.93.2.3.6.1
--- src/sys/netinet6/nd6_rtr.c:1.93.2.3	Sat May  2 18:23:25 2015
+++ src/sys/netinet6/nd6_rtr.c	Wed Apr 15 14:58:41 2020
@@ -1,4 +1,4 @@
-/*	$NetBSD: nd6_rtr.c,v 1.93.2.3 2015/05/02 18:23:25 martin Exp $	*/
+/*	$NetBSD: nd6_rtr.c,v 1.93.2.3.6.1 2020/04/15 14:58:41 martin Exp $	*/
 /*	$KAME: nd6_rtr.c,v 1.95 2001/02/07 08:09:47 itojun Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.93.2.3 2015/05/02 18:23:25 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.93.2.3.6.1 2020/04/15 14:58:41 martin Exp $");
 
 #include 
 #include 
@@ -472,6 +472,10 @@ defrouter_addreq(struct nd_defrouter *ne
 	}
 	if (error == 0)
 		new->installed = 1;
+	else
+		log(LOG_ERR, "defrouter_addreq: "
+		"error %d adding default router %s on %s\n",
+		error, ip6_sprintf(>rtaddr), new->ifp->if_xname);
 	splx(s);
 	return;
 }
@@ -559,6 +563,7 @@ defrouter_delreq(struct nd_defrouter *dr
 		struct sockaddr sa;
 	} def, mask, gw;
 	struct rtentry *oldrt = NULL;
+	int error;
 
 #ifdef DIAGNOSTIC
 	if (dr == NULL)
@@ -577,7 +582,7 @@ defrouter_delreq(struct nd_defrouter *dr
 	gw.sin6.sin6_scope_id = 0;	/* XXX */
 #endif
 
-	rtrequest(RTM_DELETE, , , , RTF_GATEWAY, );
+	error = rtrequest(RTM_DELETE, , , , RTF_GATEWAY, );
 	if (oldrt) {
 		nd6_rtmsg(RTM_DELETE, oldrt);
 		if (oldrt->rt_refcnt <= 0) {
@@ -591,7 +596,12 @@ defrouter_delreq(struct nd_defrouter *dr
 		}
 	}
 
-	dr->installed = 0;
+	if (error == 0)
+		dr->installed = 0;
+	else
+		log(LOG_ERR, "defrouter_delreq: "
+		"error %d deleting default router %s on %s\n",
+		error, ip6_sprintf(>rtaddr), dr->ifp->if_xname);
 }
 
 /*
@@ -672,8 +682,16 @@ defrouter_select(void)
 	 */
 	for (dr = TAILQ_FIRST(_defrouter); dr;
 	 dr = TAILQ_NEXT(dr, dr_entry)) {
+		if (dr->installed && !installed_dr)
+			installed_dr = dr;
+		else if (dr->installed && installed_dr) {
+			/* this should not happen.  warn for diagnosis. */
+			log(LOG_ERR, "defrouter_select: more than one router"
+			" is installed\n");
+		}
+
 		ndi = ND_IFINFO(dr->ifp);
-		if (nd6_accepts_rtadv(ndi))
+		if (!nd6_accepts_rtadv(ndi))
 			continue;
 
 		if (selected_dr == NULL &&
@@ -682,14 +700,6 @@ defrouter_select(void)
 		ND6_IS_LLINFO_PROBREACH(ln)) {
 			selected_dr = dr;
 		}
-
-		if (dr->installed && !installed_dr)
-			installed_dr = dr;
-		else if (dr->installed && installed_dr) {
-			/* this should not happen.  warn for diagnosis. */
-			log(LOG_ERR, "defrouter_select: more than one router"
-			" is installed\n");
-		}
 	}
 	/*
 	 * If none of the default routers was found to be reachable,



CVS commit: [netbsd-7-1] src/sys/netinet6

2018-08-14 Thread Martin Husemann
Module Name:src
Committed By:   martin
Date:   Tue Aug 14 14:35:44 UTC 2018

Modified Files:
src/sys/netinet6 [netbsd-7-1]: frag6.c

Log Message:
Pull up following revision(s) (requested by maxv in ticket #1630):

sys/netinet6/frag6.c: revision 1.64

Kick zero-sized fragments. We can't allow them to enter; two fragments
could be put at the same offset.


To generate a diff of this commit:
cvs rdiff -u -r1.55.10.2 -r1.55.10.3 src/sys/netinet6/frag6.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/frag6.c
diff -u src/sys/netinet6/frag6.c:1.55.10.2 src/sys/netinet6/frag6.c:1.55.10.3
--- src/sys/netinet6/frag6.c:1.55.10.2	Thu Apr  5 11:50:17 2018
+++ src/sys/netinet6/frag6.c	Tue Aug 14 14:35:44 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: frag6.c,v 1.55.10.2 2018/04/05 11:50:17 martin Exp $	*/
+/*	$NetBSD: frag6.c,v 1.55.10.3 2018/08/14 14:35:44 martin Exp $	*/
 /*	$KAME: frag6.c,v 1.40 2002/05/27 21:40:31 itojun Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: frag6.c,v 1.55.10.2 2018/04/05 11:50:17 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: frag6.c,v 1.55.10.3 2018/08/14 14:35:44 martin Exp $");
 
 #include 
 #include 
@@ -152,13 +152,14 @@ frag6_input(struct mbuf **mp, int *offp,
 	}
 
 	/*
-	 * check whether fragment packet's fragment length is
+	 * Check whether fragment packet's fragment length is non-zero and
 	 * multiple of 8 octets.
 	 * sizeof(struct ip6_frag) == 8
 	 * sizeof(struct ip6_hdr) = 40
 	 */
 	if ((ip6f->ip6f_offlg & IP6F_MORE_FRAG) &&
-	(((ntohs(ip6->ip6_plen) - offset) & 0x7) != 0)) {
+	(((ntohs(ip6->ip6_plen) - offset) == 0) ||
+	 ((ntohs(ip6->ip6_plen) - offset) & 0x7) != 0)) {
 		icmp6_error(m, ICMP6_PARAM_PROB, ICMP6_PARAMPROB_HEADER,
 		offsetof(struct ip6_hdr, ip6_plen));
 		in6_ifstat_inc(dstifp, ifs6_reass_fail);



CVS commit: [netbsd-7-1] src/sys/netinet6

2018-04-01 Thread Martin Husemann
Module Name:src
Committed By:   martin
Date:   Sun Apr  1 09:13:46 UTC 2018

Modified Files:
src/sys/netinet6 [netbsd-7-1]: raw_ip6.c

Log Message:
Pull up following revision(s) (requested by maxv in ticket #1591):

sys/netinet6/raw_ip6.c: revision 1.161

Fix use-after-free, the first m_copyback_cow may have freed the mbuf, so
it is wrong to read ip6->ip6_nxt.


To generate a diff of this commit:
cvs rdiff -u -r1.136.2.1.2.1 -r1.136.2.1.2.2 src/sys/netinet6/raw_ip6.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/raw_ip6.c
diff -u src/sys/netinet6/raw_ip6.c:1.136.2.1.2.1 src/sys/netinet6/raw_ip6.c:1.136.2.1.2.2
--- src/sys/netinet6/raw_ip6.c:1.136.2.1.2.1	Tue Jan 30 18:30:31 2018
+++ src/sys/netinet6/raw_ip6.c	Sun Apr  1 09:13:46 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: raw_ip6.c,v 1.136.2.1.2.1 2018/01/30 18:30:31 martin Exp $	*/
+/*	$NetBSD: raw_ip6.c,v 1.136.2.1.2.2 2018/04/01 09:13:46 martin Exp $	*/
 /*	$KAME: raw_ip6.c,v 1.82 2001/07/23 18:57:56 jinmei Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.136.2.1.2.1 2018/01/30 18:30:31 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: raw_ip6.c,v 1.136.2.1.2.2 2018/04/01 09:13:46 martin Exp $");
 
 #include "opt_ipsec.h"
 
@@ -476,6 +476,7 @@ rip6_output(struct mbuf *m, struct socke
 
 	if (so->so_proto->pr_protocol == IPPROTO_ICMPV6 ||
 	in6p->in6p_cksum != -1) {
+		const uint8_t nxt = ip6->ip6_nxt;
 		int off;
 		u_int16_t sum;
 
@@ -497,7 +498,7 @@ rip6_output(struct mbuf *m, struct socke
 			error = ENOBUFS;
 			goto bad;
 		}
-		sum = in6_cksum(m, ip6->ip6_nxt, sizeof(*ip6), plen);
+		sum = in6_cksum(m, nxt, sizeof(*ip6), plen);
 		m = m_copyback_cow(m, off, sizeof(sum), (void *),
 		M_DONTWAIT);
 		if (m == NULL) {



CVS commit: [netbsd-7-1] src/sys/netinet6

2018-04-01 Thread Martin Husemann
Module Name:src
Committed By:   martin
Date:   Sun Apr  1 09:09:20 UTC 2018

Modified Files:
src/sys/netinet6 [netbsd-7-1]: ip6_forward.c

Log Message:
Pull up following revision(s) (requested by maxv in ticket #1590):

sys/netinet6/ip6_forward.c: revision 1.91 (via patch)

Fix two pretty bad mistakes. If ipsec6_check_policy fails m is not freed,
and a 'goto out' is missing after ipsec6_process_packet.


To generate a diff of this commit:
cvs rdiff -u -r1.73.2.1.6.1 -r1.73.2.1.6.2 src/sys/netinet6/ip6_forward.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/ip6_forward.c
diff -u src/sys/netinet6/ip6_forward.c:1.73.2.1.6.1 src/sys/netinet6/ip6_forward.c:1.73.2.1.6.2
--- src/sys/netinet6/ip6_forward.c:1.73.2.1.6.1	Mon Feb 12 18:37:49 2018
+++ src/sys/netinet6/ip6_forward.c	Sun Apr  1 09:09:20 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_forward.c,v 1.73.2.1.6.1 2018/02/12 18:37:49 snj Exp $	*/
+/*	$NetBSD: ip6_forward.c,v 1.73.2.1.6.2 2018/04/01 09:09:20 martin Exp $	*/
 /*	$KAME: ip6_forward.c,v 1.109 2002/09/11 08:10:17 sakane Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ip6_forward.c,v 1.73.2.1.6.1 2018/02/12 18:37:49 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_forward.c,v 1.73.2.1.6.2 2018/04/01 09:09:20 martin Exp $");
 
 #include "opt_gateway.h"
 #include "opt_ipsec.h"
@@ -166,6 +166,7 @@ ip6_forward(struct mbuf *m, int srcrt)
 			 */
 			if (error == -EINVAL)
 error = 0;
+			m_freem(m);
 			goto freecopy;
 		}
 	}
@@ -264,8 +265,10 @@ ip6_forward(struct mbuf *m, int srcrt)
 		int s = splsoftnet();
 		error = ipsec6_process_packet(m, sp->req);
 		splx(s);
+		/* m is freed */
 		if (mcopy)
 			goto freecopy;
+		return;
 	}
 #endif   
 



CVS commit: [netbsd-7-1] src/sys/netinet6

2018-02-25 Thread Soren Jacobsen
Module Name:src
Committed By:   snj
Date:   Sun Feb 25 23:17:37 UTC 2018

Modified Files:
src/sys/netinet6 [netbsd-7-1]: ip6_input.c

Log Message:
Pull up following revision(s) (requested by maxv in ticket #1572):
sys/netinet6/ip6_input.c: 1.188 via patch
Kick nested fragments.


To generate a diff of this commit:
cvs rdiff -u -r1.149.2.1.6.1 -r1.149.2.1.6.2 src/sys/netinet6/ip6_input.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/ip6_input.c
diff -u src/sys/netinet6/ip6_input.c:1.149.2.1.6.1 src/sys/netinet6/ip6_input.c:1.149.2.1.6.2
--- src/sys/netinet6/ip6_input.c:1.149.2.1.6.1	Tue Jan 30 18:30:31 2018
+++ src/sys/netinet6/ip6_input.c	Sun Feb 25 23:17:37 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_input.c,v 1.149.2.1.6.1 2018/01/30 18:30:31 martin Exp $	*/
+/*	$NetBSD: ip6_input.c,v 1.149.2.1.6.2 2018/02/25 23:17:37 snj Exp $	*/
 /*	$KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.149.2.1.6.1 2018/01/30 18:30:31 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.149.2.1.6.2 2018/02/25 23:17:37 snj Exp $");
 
 #include "opt_gateway.h"
 #include "opt_inet.h"
@@ -249,7 +249,7 @@ ip6_input(struct mbuf *m)
 	int hit, off = sizeof(struct ip6_hdr), nest;
 	u_int32_t plen;
 	u_int32_t rtalert = ~0;
-	int nxt, ours = 0, rh_present = 0;
+	int nxt, ours = 0, rh_present = 0, frg_present;
 	struct ifnet *deliverifp = NULL;
 	int srcrt = 0;
 	const struct rtentry *rt;
@@ -720,6 +720,7 @@ ip6_input(struct mbuf *m)
 	nest = 0;
 
 	rh_present = 0;
+	frg_present = 0;
 	while (nxt != IPPROTO_DONE) {
 		if (ip6_hdrnestlimit && (++nest > ip6_hdrnestlimit)) {
 			IP6_STATINC(IP6_STAT_TOOMANYHDR);
@@ -744,6 +745,13 @@ ip6_input(struct mbuf *m)
 IP6_STATINC(IP6_STAT_BADOPTIONS);
 goto bad;
 			}
+		} else if (nxt == IPPROTO_FRAGMENT) {
+			if (frg_present++) {
+in6_ifstat_inc(m->m_pkthdr.rcvif,
+ifs6_in_hdrerr);
+IP6_STATINC(IP6_STAT_BADOPTIONS);
+goto bad;
+			}
 		}
 
 #ifdef IPSEC



CVS commit: [netbsd-7-1] src/sys/netinet6

2018-02-12 Thread Soren Jacobsen
Module Name:src
Committed By:   snj
Date:   Mon Feb 12 18:37:50 UTC 2018

Modified Files:
src/sys/netinet6 [netbsd-7-1]: ip6_forward.c

Log Message:
Pull up following revision(s) (requested by ozaki-r in ticket #1551):
sys/netinet6/ip6_forward.c: 1.89-1.90 via patch
Fix use-after-free of mbuf by ip6flow_create
This fixes recent failures of some ATF tests such as t_ipsec_tunnel_odd.
--
Fix use-after-free of mbuf by ip6flow_create (one more)


To generate a diff of this commit:
cvs rdiff -u -r1.73.2.1 -r1.73.2.1.6.1 src/sys/netinet6/ip6_forward.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/ip6_forward.c
diff -u src/sys/netinet6/ip6_forward.c:1.73.2.1 src/sys/netinet6/ip6_forward.c:1.73.2.1.6.1
--- src/sys/netinet6/ip6_forward.c:1.73.2.1	Sat Jan 17 12:10:54 2015
+++ src/sys/netinet6/ip6_forward.c	Mon Feb 12 18:37:49 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_forward.c,v 1.73.2.1 2015/01/17 12:10:54 martin Exp $	*/
+/*	$NetBSD: ip6_forward.c,v 1.73.2.1.6.1 2018/02/12 18:37:49 snj Exp $	*/
 /*	$KAME: ip6_forward.c,v 1.109 2002/09/11 08:10:17 sakane Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ip6_forward.c,v 1.73.2.1 2015/01/17 12:10:54 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_forward.c,v 1.73.2.1.6.1 2018/02/12 18:37:49 snj Exp $");
 
 #include "opt_gateway.h"
 #include "opt_ipsec.h"
@@ -406,8 +406,8 @@ ip6_forward(struct mbuf *m, int srcrt)
 			IP6_STATINC(IP6_STAT_REDIRECTSENT);
 		else {
 #ifdef GATEWAY
-			if (m->m_flags & M_CANFASTFWD)
-ip6flow_create(_forward_rt, m);
+			if (mcopy->m_flags & M_CANFASTFWD)
+ip6flow_create(_forward_rt, mcopy);
 #endif
 			if (mcopy)
 goto freecopy;



CVS commit: [netbsd-7-1] src/sys/netinet6

2018-02-02 Thread Martin Husemann
Module Name:src
Committed By:   martin
Date:   Fri Feb  2 13:04:53 UTC 2018

Modified Files:
src/sys/netinet6 [netbsd-7-1]: nd6_nbr.c

Log Message:
Pull up following revision(s) (requested by maxv in ticket #1562):
sys/netinet6/nd6_nbr.c: revision 1.145 (patch)

Fix memory leak. Contrary to what the XXX indicates, this place is 100%
reachable remotely.


To generate a diff of this commit:
cvs rdiff -u -r1.100.2.2 -r1.100.2.2.6.1 src/sys/netinet6/nd6_nbr.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/nd6_nbr.c
diff -u src/sys/netinet6/nd6_nbr.c:1.100.2.2 src/sys/netinet6/nd6_nbr.c:1.100.2.2.6.1
--- src/sys/netinet6/nd6_nbr.c:1.100.2.2	Mon Apr  6 01:32:33 2015
+++ src/sys/netinet6/nd6_nbr.c	Fri Feb  2 13:04:53 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: nd6_nbr.c,v 1.100.2.2 2015/04/06 01:32:33 snj Exp $	*/
+/*	$NetBSD: nd6_nbr.c,v 1.100.2.2.6.1 2018/02/02 13:04:53 martin Exp $	*/
 /*	$KAME: nd6_nbr.c,v 1.61 2001/02/10 16:06:14 jinmei Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.100.2.2 2015/04/06 01:32:33 snj Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_nbr.c,v 1.100.2.2.6.1 2018/02/02 13:04:53 martin Exp $");
 
 #include "opt_inet.h"
 #include "opt_ipsec.h"
@@ -590,7 +590,7 @@ nd6_na_input(struct mbuf *m, int off, in
 
 	taddr6 = nd_na->nd_na_target;
 	if (in6_setscope(, ifp, NULL))
-		return;		/* XXX: impossible */
+		goto bad;
 
 	if (IN6_IS_ADDR_MULTICAST()) {
 		nd6log((LOG_ERR,



CVS commit: [netbsd-7-1] src/sys/netinet6

2018-02-02 Thread Martin Husemann
Module Name:src
Committed By:   martin
Date:   Fri Feb  2 11:01:46 UTC 2018

Modified Files:
src/sys/netinet6 [netbsd-7-1]: ip6_mroute.c

Log Message:
Pull up following revision(s) (requested by maxv in ticket #1561):
sys/netinet6/ip6_mroute.c: revision 1.120
Fix a pretty simple, yet pretty tragic typo: we should return IPPROTO_DONE,
not IPPROTO_NONE. With IPPROTO_NONE we will keep parsing the header chain
on an mbuf that was already freed.


To generate a diff of this commit:
cvs rdiff -u -r1.107 -r1.107.10.1 src/sys/netinet6/ip6_mroute.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/ip6_mroute.c
diff -u src/sys/netinet6/ip6_mroute.c:1.107 src/sys/netinet6/ip6_mroute.c:1.107.10.1
--- src/sys/netinet6/ip6_mroute.c:1.107	Sat May 17 21:26:20 2014
+++ src/sys/netinet6/ip6_mroute.c	Fri Feb  2 11:01:46 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_mroute.c,v 1.107 2014/05/17 21:26:20 rmind Exp $	*/
+/*	$NetBSD: ip6_mroute.c,v 1.107.10.1 2018/02/02 11:01:46 martin Exp $	*/
 /*	$KAME: ip6_mroute.c,v 1.49 2001/07/25 09:21:18 jinmei Exp $	*/
 
 /*
@@ -117,7 +117,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ip6_mroute.c,v 1.107 2014/05/17 21:26:20 rmind Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_mroute.c,v 1.107.10.1 2018/02/02 11:01:46 martin Exp $");
 
 #include "opt_inet.h"
 #include "opt_mrouting.h"
@@ -1861,7 +1861,7 @@ pim6_input(struct mbuf **mp, int *offp, 
 			(eip6->ip6_vfc & IPV6_VERSION));
 #endif
 			m_freem(m);
-			return (IPPROTO_NONE);
+			return (IPPROTO_DONE);
 		}
 
 		/* verify the inner packet is destined to a mcast group */



CVS commit: [netbsd-7-1] src/sys/netinet6

2018-01-30 Thread Martin Husemann
Module Name:src
Committed By:   martin
Date:   Tue Jan 30 18:30:31 UTC 2018

Modified Files:
src/sys/netinet6 [netbsd-7-1]: frag6.c ip6_input.c ip6_var.h raw_ip6.c

Log Message:
Pull up following revision(s) (requested by maxv in ticket #1560):
sys/netinet6/frag6.c: revision 1.65
sys/netinet6/ip6_input.c: revision 1.187
sys/netinet6/ip6_var.h: revision 1.78
sys/netinet6/raw_ip6.c: revision 1.160 (patch)
Fix a buffer overflow in ip6_get_prevhdr. Doing
mtod(m, char *) + len
is wrong, an option is allowed to be located in another mbuf of the chain.
If the offset of an option within the chain is bigger than the length of
the first mbuf in that chain, we are reading/writing one byte of packet-
controlled data beyond the end of the first mbuf.
The length of this first mbuf depends on the layout the network driver
chose. In the most difficult case, it will allocate a 2KB cluster, which
is bigger than the Ethernet MTU.
But there is at least one way of exploiting this case: by sending a
special combination of nested IPv6 fragments, the packet can control a
good bunch of 'len'. By luck, the memory pool containing clusters does not
embed the pool header in front of the items, so it is not straightforward
to predict what is located at 'mtod(m, char *) + len'.
However, by sending offending fragments in a loop, it is possible to
crash the kernel - at some point we will hit important data structures.
As far as I can tell, PF protects against this difficult case, because
it kicks nested fragments. NPF does not protect against this. IPF I don't
know.
Then there are the more easy cases, if the MTU is bigger than a cluster,
or if the network driver did not allocate a cluster, or perhaps if the
fragments are received via a tunnel; I haven't investigated these cases.
Change ip6_get_prevhdr so that it returns an offset in the chain, and
always use IP6_EXTHDR_GET to get a writable pointer. IP6_EXTHDR_GET
leaves M_PKTHDR untouched.
This place is still fragile.


To generate a diff of this commit:
cvs rdiff -u -r1.55 -r1.55.10.1 src/sys/netinet6/frag6.c
cvs rdiff -u -r1.149.2.1 -r1.149.2.1.6.1 src/sys/netinet6/ip6_input.c
cvs rdiff -u -r1.62.2.1 -r1.62.2.1.6.1 src/sys/netinet6/ip6_var.h
cvs rdiff -u -r1.136.2.1 -r1.136.2.1.2.1 src/sys/netinet6/raw_ip6.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/frag6.c
diff -u src/sys/netinet6/frag6.c:1.55 src/sys/netinet6/frag6.c:1.55.10.1
--- src/sys/netinet6/frag6.c:1.55	Fri Aug 30 07:42:08 2013
+++ src/sys/netinet6/frag6.c	Tue Jan 30 18:30:31 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: frag6.c,v 1.55 2013/08/30 07:42:08 christos Exp $	*/
+/*	$NetBSD: frag6.c,v 1.55.10.1 2018/01/30 18:30:31 martin Exp $	*/
 /*	$KAME: frag6.c,v 1.40 2002/05/27 21:40:31 itojun Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: frag6.c,v 1.55 2013/08/30 07:42:08 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: frag6.c,v 1.55.10.1 2018/01/30 18:30:31 martin Exp $");
 
 #include 
 #include 
@@ -441,14 +441,6 @@ insert:
 		m_cat(m, t);
 	}
 
-	/*
-	 * Store NXT to the original.
-	 */
-	{
-		u_int8_t *prvnxtp = ip6_get_prevhdr(m, offset); /* XXX */
-		*prvnxtp = nxt;
-	}
-
 	frag6_remque(q6);
 	frag6_nfrags -= q6->ip6q_nfrag;
 	kmem_intr_free(q6, sizeof(struct ip6q));
@@ -456,11 +448,30 @@ insert:
 
 	if (m->m_flags & M_PKTHDR) { /* Isn't it always true? */
 		int plen = 0;
-		for (t = m; t; t = t->m_next)
+		for (t = m; t; t = t->m_next) {
+			/*
+			 * XXX XXX Why don't we remove M_PKTHDR?
+			 */
 			plen += t->m_len;
+		}
 		m->m_pkthdr.len = plen;
 	}
 
+	/*
+	 * Restore NXT to the original.
+	 */
+	{
+		const int prvnxt = ip6_get_prevhdr(m, offset);
+		uint8_t *prvnxtp;
+
+		IP6_EXTHDR_GET(prvnxtp, uint8_t *, m, prvnxt,
+		sizeof(*prvnxtp));
+		if (prvnxtp == NULL) {
+			goto dropfrag;
+		}
+		*prvnxtp = nxt;
+	}
+
 	IP6_STATINC(IP6_STAT_REASSEMBLED);
 	in6_ifstat_inc(dstifp, ifs6_reass_ok);
 

Index: src/sys/netinet6/ip6_input.c
diff -u src/sys/netinet6/ip6_input.c:1.149.2.1 src/sys/netinet6/ip6_input.c:1.149.2.1.6.1
--- src/sys/netinet6/ip6_input.c:1.149.2.1	Fri Jan 23 09:27:15 2015
+++ src/sys/netinet6/ip6_input.c	Tue Jan 30 18:30:31 2018
@@ -1,4 +1,4 @@
-/*	$NetBSD: ip6_input.c,v 1.149.2.1 2015/01/23 09:27:15 martin Exp $	*/
+/*	$NetBSD: ip6_input.c,v 1.149.2.1.6.1 2018/01/30 18:30:31 martin Exp $	*/
 /*	$KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include 
-__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.149.2.1 2015/01/23 09:27:15 martin Exp $");
+__KERNEL_RCSID(0, "$NetBSD: ip6_input.c,v 1.149.2.1.6.1 2018/01/30 18:30:31 martin Exp $");
 
 #include "opt_gateway.h"
 #include "opt_inet.h"
@@ -1384,50 +1384,44 @@ ip6_pullexthdr(struct mbuf *m, size_t of
 }
 
 /*
- * Get pointer to the previous header followed by the header
+ * Get offset to the previous header followed by