Module Name:    src
Committed By:   ozaki-r
Date:           Wed Nov 30 02:08:57 UTC 2016

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

Log Message:
Fix panic on destroying an interface with IPv6 addresses obtained with RA

nd6_purge depends on that IPv6 addresses are purged. If addresses remain,
pfxlist_onlink_check called from nd6_purge dereferences a dangling pointer
(ia->ia6_ndpr) that is freed before calling pfxlist_onlink_check. Fix it by
removing addresses before calling nd6_purge, which is the original behavior
that was changed by in6.c,v 1.203 and in6_ifattach.c,v 1.99.

Note that it seems the issue occurs because of a hack that forcibly destroys
prefix list entries of a given interface in nd6_purge. We should tackle the
hack in the future.

Fix PR kern/51467


To generate a diff of this commit:
cvs rdiff -u -r1.106 -r1.107 src/sys/netinet6/in6_ifattach.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/in6_ifattach.c
diff -u src/sys/netinet6/in6_ifattach.c:1.106 src/sys/netinet6/in6_ifattach.c:1.107
--- src/sys/netinet6/in6_ifattach.c:1.106	Tue Oct 18 02:45:41 2016
+++ src/sys/netinet6/in6_ifattach.c	Wed Nov 30 02:08:57 2016
@@ -1,4 +1,4 @@
-/*	$NetBSD: in6_ifattach.c,v 1.106 2016/10/18 02:45:41 ozaki-r Exp $	*/
+/*	$NetBSD: in6_ifattach.c,v 1.107 2016/11/30 02:08:57 ozaki-r Exp $	*/
 /*	$KAME: in6_ifattach.c,v 1.124 2001/07/18 08:32:51 jinmei Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.106 2016/10/18 02:45:41 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.107 2016/11/30 02:08:57 ozaki-r Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -809,15 +809,15 @@ void
 in6_ifdetach(struct ifnet *ifp)
 {
 
+	/* nuke any of IPv6 addresses we have */
+	if_purgeaddrs(ifp, AF_INET6, in6_purgeaddr);
+
 	/* remove ip6_mrouter stuff */
 	ip6_mrouter_detach(ifp);
 
 	/* remove neighbor management table */
 	nd6_purge(ifp, NULL);
 
-	/* nuke any of IPv6 addresses we have */
-	if_purgeaddrs(ifp, AF_INET6, in6_purgeaddr);
-
 	/* cleanup multicast address kludge table, if there is any */
 	in6_purgemkludge(ifp);
 

Reply via email to