From owner-freebsd-bugs@FreeBSD.ORG Thu Apr 25 20:20:01 2013 Return-Path: Delivered-To: freebsd-bugs@smarthost.ysv.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:1900:2254:206a::19:1]) by hub.freebsd.org (Postfix) with ESMTP id 4F354F3B for ; Thu, 25 Apr 2013 20:20:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.freebsd.org [IPv6:2001:1900:2254:206c::16:87]) by mx1.freebsd.org (Postfix) with ESMTP id 402B11825 for ; Thu, 25 Apr 2013 20:20:01 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.6/8.14.6) with ESMTP id r3PKK1iB083977 for ; Thu, 25 Apr 2013 20:20:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.6/8.14.6/Submit) id r3PKK1xE083976; Thu, 25 Apr 2013 20:20:01 GMT (envelope-from gnats) Date: Thu, 25 Apr 2013 20:20:01 GMT Message-Id: <201304252020.r3PKK1xE083976@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: Robert Watson Subject: Re: kern/172963 (was: svn commit: r249660 - in releng/8.4/sys:netinet netinet6 (fwd)) X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: Robert Watson List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Thu, 25 Apr 2013 20:20:01 -0000 The following reply was made to PR kern/172963; it has been noted by GNATS. From: Robert Watson To: bug-followup@FreeBSD.org Cc: Subject: Re: kern/172963 (was: svn commit: r249660 - in releng/8.4/sys:netinet netinet6 (fwd)) Date: Thu, 25 Apr 2013 21:16:56 +0100 (BST) ---------- Forwarded message ---------- Date: Fri, 19 Apr 2013 21:08:56 +0000 (UTC) From: Robert Watson To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-releng@freebsd.org Subject: svn commit: r249660 - in releng/8.4/sys: netinet netinet6 Author: rwatson Date: Fri Apr 19 21:08:56 2013 New Revision: 249660 URL: http://svnweb.freebsd.org/changeset/base/249660 Log: Merge r249478 from stable/8 to releng/8.4: FreeBSD 8.0 introduced inpcb reference counting, and FreeBSD 8.1 began using that reference count to protect inpcb stability in udp_pcblist() and other monitoring functions, preventing the inpcb from being garbage collected across potentially sleeping copyout() operations despite the inpcb zone becoming shrinkable. However, this introduced a race condition in which inp->inp_socket() might become NULL as a result of the socket being freed, but before the inpcb we removed from the global list of connections, allowing it to be exposed to a third thread invoking udp_input() or udp6_input() which would try to indirect through inp_socket without testing it for NULL. This might occur with particular regularity on systems that frequently run netstat, or which use SNMP for connection monitoring. Later FreeBSD releases use a different reference/destruction model, but stable/8 remained affected in FreeBSD 8.2 and 8.3; the problem could be spotted on very high-load UDP services, such as top-level name servers. An Errata Note for 8.x branches under continuing support might be appropriate. Regardless, this fix should be merged to releng/8.4 prior to 8.4-RELEASE. PR: 172963 Submitted by: Vincent Miller Submitted by: Julien Charbon Submitted by: Marc De La Gueronniere Approved by: re (rodrigc) Modified: releng/8.4/sys/netinet/udp_usrreq.c releng/8.4/sys/netinet6/udp6_usrreq.c Directory Properties: releng/8.4/sys/ (props changed) releng/8.4/sys/netinet/ (props changed) releng/8.4/sys/netinet6/ (props changed) Modified: releng/8.4/sys/netinet/udp_usrreq.c ============================================================================== --- releng/8.4/sys/netinet/udp_usrreq.c Fri Apr 19 21:08:21 2013 (r249659) +++ releng/8.4/sys/netinet/udp_usrreq.c Fri Apr 19 21:08:56 2013 (r249660) @@ -495,6 +495,15 @@ udp_input(struct mbuf *m, int off) INP_RLOCK(inp); /* + * Detached PCBs can linger in the list if someone + * holds a reference. (e.g. udp_pcblist) + */ + if (inp->inp_socket == NULL) { + INP_RUNLOCK(inp); + continue; + } + + /* * Handle socket delivery policy for any-source * and source-specific multicast. [RFC3678] */ @@ -620,6 +629,15 @@ udp_input(struct mbuf *m, int off) */ INP_RLOCK(inp); INP_INFO_RUNLOCK(&V_udbinfo); + + /* + * Detached PCBs can linger in the hash table if someone holds a + * reference. (e.g. udp_pcblist) + */ + if (inp->inp_socket == NULL) { + INP_RUNLOCK(inp); + goto badunlocked; + } if (inp->inp_ip_minttl && inp->inp_ip_minttl > ip->ip_ttl) { INP_RUNLOCK(inp); goto badunlocked; Modified: releng/8.4/sys/netinet6/udp6_usrreq.c ============================================================================== --- releng/8.4/sys/netinet6/udp6_usrreq.c Fri Apr 19 21:08:21 2013 (r249659) +++ releng/8.4/sys/netinet6/udp6_usrreq.c Fri Apr 19 21:08:56 2013 (r249660) @@ -273,6 +273,13 @@ udp6_input(struct mbuf **mp, int *offp, } /* + * Detached PCBs can linger in the list if someone + * holds a reference. (e.g. udp_pcblist) + */ + if (inp->inp_socket == NULL) + continue; + + /* * Handle socket delivery policy for any-source * and source-specific multicast. [RFC3678] */ @@ -396,6 +403,15 @@ udp6_input(struct mbuf **mp, int *offp, } INP_RLOCK(inp); INP_INFO_RUNLOCK(&V_udbinfo); + + /* + * Detached PCBs can linger in the hash table if someone holds a + * reference. (e.g. udp_pcblist) + */ + if (inp->inp_socket == NULL) { + INP_RUNLOCK(inp); + goto badunlocked; + } up = intoudpcb(inp); if (up->u_tun_func == NULL) { udp6_append(inp, m, off, &fromsa);