From 046e2eafb0788e5ca35a0913128cfc4e7554d319 Mon Sep 17 00:00:00 2001 From: ozaki-r Date: Thu, 12 Jan 2017 04:43:59 +0000 Subject: [PATCH] Prevent in6_ifaddr from being freed with holding its psref This is a possible fix for PR kern/51828. --- sys/netinet6/in6.c | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/sys/netinet6/in6.c b/sys/netinet6/in6.c index 78a9457310b3..a53ae9b5c914 100644 --- a/sys/netinet6/in6.c +++ b/sys/netinet6/in6.c @@ -1,4 +1,4 @@ -/* $NetBSD: in6.c,v 1.232 2017/01/11 18:25:46 christos Exp $ */ +/* $NetBSD: in6.c,v 1.233 2017/01/12 04:43:59 ozaki-r Exp $ */ /* $KAME: in6.c,v 1.198 2001/07/18 09:12:38 itojun Exp $ */ /* @@ -62,7 +62,7 @@ */ #include -__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.232 2017/01/11 18:25:46 christos Exp $"); +__KERNEL_RCSID(0, "$NetBSD: in6.c,v 1.233 2017/01/12 04:43:59 ozaki-r Exp $"); #ifdef _KERNEL_OPT #include "opt_inet.h" @@ -797,6 +797,9 @@ in6_update_ifa1(struct ifnet *ifp, struct in6_aliasreq *ifra, int dad_delay, was_tentative; struct in6_ifaddr *ia = iap ? *iap : NULL; + KASSERT((iap == NULL && psref == NULL) || + (iap != NULL && psref != NULL)); + in6m_sol = NULL; /* Validate parameters */ @@ -950,8 +953,6 @@ in6_update_ifa1(struct ifnet *ifp, struct in6_aliasreq *ifra, ia->ia_ifp = ifp; IN6_ADDRLIST_ENTRY_INIT(ia); ifa_psref_init(&ia->ia_ifa); - if (psref) - ia6_acquire(ia, psref); } /* update timestamp */ @@ -1300,8 +1301,11 @@ in6_update_ifa1(struct ifnet *ifp, struct in6_aliasreq *ifra, nd6_dad_start(&ia->ia_ifa, dad_delay + 1); } - if (iap) + if (iap != NULL) { *iap = ia; + if (hostIsNew) + ia6_acquire(ia, psref); + } return 0;