Module Name:    src
Committed By:   christos
Date:           Wed Jan  4 19:37:14 UTC 2017

Modified Files:
        src/sys/netinet6: in6.c in6_ifattach.c in6_var.h nd6_rtr.c

Log Message:
- kill NULL argument from in6_update_ifa
- amend in6_update_ifa1 to return the ia, so that we can use it in pfil hooks
  to avoid NULL pointer crash.


To generate a diff of this commit:
cvs rdiff -u -r1.229 -r1.230 src/sys/netinet6/in6.c
cvs rdiff -u -r1.108 -r1.109 src/sys/netinet6/in6_ifattach.c
cvs rdiff -u -r1.87 -r1.88 src/sys/netinet6/in6_var.h
cvs rdiff -u -r1.128 -r1.129 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/in6.c
diff -u src/sys/netinet6/in6.c:1.229 src/sys/netinet6/in6.c:1.230
--- src/sys/netinet6/in6.c:1.229	Tue Jan  3 10:14:31 2017
+++ src/sys/netinet6/in6.c	Wed Jan  4 14:37:14 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: in6.c,v 1.229 2017/01/03 15:14:31 christos Exp $	*/
+/*	$NetBSD: in6.c,v 1.230 2017/01/04 19:37:14 christos Exp $	*/
 /*	$KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $	*/
 
 /*
@@ -62,7 +62,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.229 2017/01/03 15:14:31 christos Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.230 2017/01/04 19:37:14 christos Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_inet.h"
@@ -153,6 +153,8 @@ static int in6_ifremprefix(struct in6_if
 static int in6_ifinit(struct ifnet *, struct in6_ifaddr *,
 	const struct sockaddr_in6 *, int);
 static void in6_unlink_ifa(struct in6_ifaddr *, struct ifnet *);
+static int in6_update_ifa1(struct ifnet *, struct in6_aliasreq *,
+    struct in6_ifaddr **, struct psref *, int);
 
 void
 in6_init(void)
@@ -701,7 +703,10 @@ in6_control1(struct socket *so, u_long c
 		 * make (ia == NULL) or update (ia != NULL) the interface
 		 * address structure, and link it to the list.
 		 */
-		if ((error = in6_update_ifa(ifp, ifra, ia, 0)) != 0)
+		int s = splnet();
+		error = in6_update_ifa1(ifp, ifra, &ia, &psref, 0);
+		splx(s);
+		if (error)
 			break;
 		pfil_run_addrhooks(if_pfil, cmd, &ia->ia_ifa);
 		break;
@@ -779,7 +784,7 @@ in6_control(struct socket *so, u_long cm
  */
 static int
 in6_update_ifa1(struct ifnet *ifp, struct in6_aliasreq *ifra,
-    struct in6_ifaddr *ia, int flags)
+    struct in6_ifaddr **iap, struct psref *psref, int flags)
 {
 	int error = 0, hostIsNew = 0, plen = -1;
 	struct sockaddr_in6 dst6;
@@ -788,6 +793,7 @@ in6_update_ifa1(struct ifnet *ifp, struc
 	struct in6_multi *in6m_sol;
 	struct rtentry *rt;
 	int dad_delay, was_tentative;
+	struct in6_ifaddr *ia = iap ? *iap : NULL;
 
 	in6m_sol = NULL;
 
@@ -919,11 +925,9 @@ in6_update_ifa1(struct ifnet *ifp, struc
 		 * RA, it is called under an interrupt context.  So, we should
 		 * call malloc with M_NOWAIT.
 		 */
-		ia = (struct in6_ifaddr *) malloc(sizeof(*ia), M_IFADDR,
-		    M_NOWAIT);
+		ia = malloc(sizeof(*ia), M_IFADDR, M_NOWAIT|M_ZERO);
 		if (ia == NULL)
 			return ENOBUFS;
-		memset(ia, 0, sizeof(*ia));
 		LIST_INIT(&ia->ia6_memberships);
 		/* Initialize the address and masks, and put time stamp */
 		ia->ia_ifa.ifa_addr = sin6tosa(&ia->ia_addr);
@@ -944,6 +948,8 @@ in6_update_ifa1(struct ifnet *ifp, struc
 		ia->ia_ifp = ifp;
 		IN6_ADDRLIST_ENTRY_INIT(ia);
 		ifa_psref_init(&ia->ia_ifa);
+		if (psref)
+			ia6_acquire(ia, psref);
 	}
 
 	/* update timestamp */
@@ -1292,6 +1298,9 @@ in6_update_ifa1(struct ifnet *ifp, struc
 		nd6_dad_start(&ia->ia_ifa, dad_delay + 1);
 	}
 
+	if (iap)
+		*iap = ia;
+
 	return 0;
 
   cleanup:
@@ -1301,13 +1310,12 @@ in6_update_ifa1(struct ifnet *ifp, struc
 }
 
 int
-in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra,
-    struct in6_ifaddr *ia, int flags)
+in6_update_ifa(struct ifnet *ifp, struct in6_aliasreq *ifra, int flags)
 {
 	int rc, s;
 
 	s = splnet();
-	rc = in6_update_ifa1(ifp, ifra, ia, flags);
+	rc = in6_update_ifa1(ifp, ifra, NULL, NULL, flags);
 	splx(s);
 	return rc;
 }

Index: src/sys/netinet6/in6_ifattach.c
diff -u src/sys/netinet6/in6_ifattach.c:1.108 src/sys/netinet6/in6_ifattach.c:1.109
--- src/sys/netinet6/in6_ifattach.c:1.108	Sun Dec 18 22:32:54 2016
+++ src/sys/netinet6/in6_ifattach.c	Wed Jan  4 14:37:14 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: in6_ifattach.c,v 1.108 2016/12/19 03:32:54 ozaki-r Exp $	*/
+/*	$NetBSD: in6_ifattach.c,v 1.109 2017/01/04 19:37:14 christos 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.108 2016/12/19 03:32:54 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: in6_ifattach.c,v 1.109 2017/01/04 19:37:14 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -576,8 +576,7 @@ in6_ifattach_linklocal(struct ifnet *ifp
 	 * we know there's no other link-local address on the interface
 	 * and therefore we are adding one (instead of updating one).
 	 */
-	if ((error = in6_update_ifa(ifp, &ifra, NULL,
-	    IN6_IFAUPDATE_DADDELAY)) != 0) {
+	if ((error = in6_update_ifa(ifp, &ifra, IN6_IFAUPDATE_DADDELAY)) != 0) {
 		/*
 		 * XXX: When the interface does not support IPv6, this call
 		 * would fail in the SIOCINITIFADDR ioctl.  I believe the
@@ -634,7 +633,7 @@ in6_ifattach_loopback(struct ifnet *ifp)
 	 * We are sure that this is a newly assigned address, so we can set
 	 * NULL to the 3rd arg.
 	 */
-	if ((error = in6_update_ifa(ifp, &ifra, NULL, 0)) != 0) {
+	if ((error = in6_update_ifa(ifp, &ifra, 0)) != 0) {
 		nd6log(LOG_ERR, "failed to configure "
 		    "the loopback address on %s (errno=%d)\n",
 		    if_name(ifp), error);

Index: src/sys/netinet6/in6_var.h
diff -u src/sys/netinet6/in6_var.h:1.87 src/sys/netinet6/in6_var.h:1.88
--- src/sys/netinet6/in6_var.h:1.87	Wed Sep 14 12:17:17 2016
+++ src/sys/netinet6/in6_var.h	Wed Jan  4 14:37:14 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: in6_var.h,v 1.87 2016/09/14 16:17:17 christos Exp $	*/
+/*	$NetBSD: in6_var.h,v 1.88 2017/01/04 19:37:14 christos Exp $	*/
 /*	$KAME: in6_var.h,v 1.81 2002/06/08 11:16:51 itojun Exp $	*/
 
 /*
@@ -783,8 +783,7 @@ struct in6_multi_mship *in6_joingroup(st
 int	in6_leavegroup(struct in6_multi_mship *);
 int	in6_mask2len(struct in6_addr *, u_char *);
 int	in6_control(struct socket *, u_long, void *, struct ifnet *);
-int	in6_update_ifa(struct ifnet *, struct in6_aliasreq *,
-	struct in6_ifaddr *, int);
+int	in6_update_ifa(struct ifnet *, struct in6_aliasreq *, int);
 void	in6_purgeaddr(struct ifaddr *);
 void	in6_purgeif(struct ifnet *);
 void	in6_savemkludge(struct in6_ifaddr *);

Index: src/sys/netinet6/nd6_rtr.c
diff -u src/sys/netinet6/nd6_rtr.c:1.128 src/sys/netinet6/nd6_rtr.c:1.129
--- src/sys/netinet6/nd6_rtr.c:1.128	Mon Dec 19 02:51:34 2016
+++ src/sys/netinet6/nd6_rtr.c	Wed Jan  4 14:37:14 2017
@@ -1,4 +1,4 @@
-/*	$NetBSD: nd6_rtr.c,v 1.128 2016/12/19 07:51:34 ozaki-r Exp $	*/
+/*	$NetBSD: nd6_rtr.c,v 1.129 2017/01/04 19:37:14 christos Exp $	*/
 /*	$KAME: nd6_rtr.c,v 1.95 2001/02/07 08:09:47 itojun Exp $	*/
 
 /*
@@ -31,7 +31,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.128 2016/12/19 07:51:34 ozaki-r Exp $");
+__KERNEL_RCSID(0, "$NetBSD: nd6_rtr.c,v 1.129 2017/01/04 19:37:14 christos Exp $");
 
 #include <sys/param.h>
 #include <sys/systm.h>
@@ -1988,7 +1988,7 @@ in6_ifadd(struct nd_prefixctl *prc, int 
 	updateflags = 0;
 	if (mcast)
 		updateflags |= IN6_IFAUPDATE_DADDELAY;
-	if ((error = in6_update_ifa(ifp, &ifra, NULL, updateflags)) != 0) {
+	if ((error = in6_update_ifa(ifp, &ifra, updateflags)) != 0) {
 		nd6log(LOG_ERR, "failed to make ifaddr %s on %s (errno=%d)\n",
 		    ip6_sprintf(&ifra.ifra_addr.sin6_addr), if_name(ifp),
 		    error);
@@ -2109,7 +2109,7 @@ in6_tmpifadd(
 	updateflags = 0;
 	if (dad_delay)
 		updateflags |= IN6_IFAUPDATE_DADDELAY;
-	if ((error = in6_update_ifa(ifp, &ifra, NULL, updateflags)) != 0)
+	if ((error = in6_update_ifa(ifp, &ifra, updateflags)) != 0)
 		return (error);
 
 	s = pserialize_read_enter();

Reply via email to