Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 14 Apr 2013 16:30:01 GMT
From:      dfilter@FreeBSD.ORG (dfilter service)
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: kern/172963: commit references a PR
Message-ID:  <201304141630.r3EGU1gw098889@freefall.freebsd.org>

next in thread | raw e-mail | index | archive | help
The following reply was made to PR kern/172963; it has been noted by GNATS.

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/172963: commit references a PR
Date: Sun, 14 Apr 2013 16:26:17 +0000 (UTC)

 Author: rwatson
 Date: Sun Apr 14 16:25:37 2013
 New Revision: 249478
 URL: http://svnweb.freebsd.org/changeset/base/249478
 
 Log:
   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 <vmiller@verisign.com>
   Submitted by:	Julien Charbon <jcharbon@verisign.com>
   Submitted by:	Marc De La Gueronniere <mdelagueronniere@verisign.com>
 
 Modified:
   stable/8/sys/netinet/udp_usrreq.c
   stable/8/sys/netinet6/udp6_usrreq.c
 
 Modified: stable/8/sys/netinet/udp_usrreq.c
 ==============================================================================
 --- stable/8/sys/netinet/udp_usrreq.c	Sun Apr 14 16:20:25 2013	(r249477)
 +++ stable/8/sys/netinet/udp_usrreq.c	Sun Apr 14 16:25:37 2013	(r249478)
 @@ -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: stable/8/sys/netinet6/udp6_usrreq.c
 ==============================================================================
 --- stable/8/sys/netinet6/udp6_usrreq.c	Sun Apr 14 16:20:25 2013	(r249477)
 +++ stable/8/sys/netinet6/udp6_usrreq.c	Sun Apr 14 16:25:37 2013	(r249478)
 @@ -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);
 _______________________________________________
 svn-src-all@freebsd.org mailing list
 http://lists.freebsd.org/mailman/listinfo/svn-src-all
 To unsubscribe, send any mail to "svn-src-all-unsubscribe@freebsd.org"
 



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?201304141630.r3EGU1gw098889>