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();