From owner-svn-src-all@FreeBSD.ORG Sat Jun 27 11:05:53 2009 Return-Path: Delivered-To: svn-src-all@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 6307A1065679; Sat, 27 Jun 2009 11:05:53 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id 519248FC1B; Sat, 27 Jun 2009 11:05:53 +0000 (UTC) (envelope-from rwatson@FreeBSD.org) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id n5RB5rOZ076209; Sat, 27 Jun 2009 11:05:53 GMT (envelope-from rwatson@svn.freebsd.org) Received: (from rwatson@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id n5RB5rv5076207; Sat, 27 Jun 2009 11:05:53 GMT (envelope-from rwatson@svn.freebsd.org) Message-Id: <200906271105.n5RB5rv5076207@svn.freebsd.org> From: Robert Watson Date: Sat, 27 Jun 2009 11:05:53 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r195102 - head/sys/netinet6 X-BeenThere: svn-src-all@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: "SVN commit messages for the entire src tree \(except for " user" and " projects" \)" List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Sat, 27 Jun 2009 11:05:53 -0000 Author: rwatson Date: Sat Jun 27 11:05:53 2009 New Revision: 195102 URL: http://svn.freebsd.org/changeset/base/195102 Log: In in6_update_ifa(), jump to 'cleanup' rather than returning directly in one additional case, avoiding an ifaddr reference leak. Defer releasing the in6_ifaddr's in6_ifaddrhead reference until the end of in6_unlink_ifa(), as callers are inconsistent regarding whether or not they hold a reference across the call. This avoids using the ifaddr after it may have been freed. Reported by: tegge Reviewed by: tegge Approved by: re (blanket) MFC after: 6 weeks Modified: head/sys/netinet6/in6.c Modified: head/sys/netinet6/in6.c ============================================================================== --- head/sys/netinet6/in6.c Sat Jun 27 10:45:58 2009 (r195101) +++ head/sys/netinet6/in6.c Sat Jun 27 11:05:53 2009 (r195102) @@ -970,8 +970,7 @@ in6_update_ifa(struct ifnet *ifp, struct "%s on %s (errno=%d)\n", ip6_sprintf(ip6buf, &llsol), if_name(ifp), error)); - in6_purgeaddr((struct ifaddr *)ia); - return (error); + goto cleanup; } LIST_INSERT_HEAD(&ia->ia6_memberships, imm, i6mm_chain); @@ -1378,10 +1377,14 @@ in6_unlink_ifa(struct in6_ifaddr *ia, st IF_ADDR_UNLOCK(ifp); ifa_free(&ia->ia_ifa); /* if_addrhead */ + /* + * Defer the release of what might be the last reference to the + * in6_ifaddr so that it can't be freed before the remainder of the + * cleanup. + */ IN6_IFADDR_WLOCK(); TAILQ_REMOVE(&V_in6_ifaddrhead, ia, ia_link); IN6_IFADDR_WUNLOCK(); - ifa_free(&ia->ia_ifa); /* in6_ifaddrhead */ /* * Release the reference to the base prefix. There should be a @@ -1404,7 +1407,7 @@ in6_unlink_ifa(struct in6_ifaddr *ia, st if ((ia->ia6_flags & IN6_IFF_AUTOCONF)) { pfxlist_onlink_check(); } - + ifa_free(&ia->ia_ifa); /* in6_ifaddrhead */ splx(s); }