From nobody@FreeBSD.org  Mon Oct 22 17:34:06 2012
Return-Path: <nobody@FreeBSD.org>
Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52])
	by hub.freebsd.org (Postfix) with ESMTP id 3D9064E4
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 22 Oct 2012 17:34:06 +0000 (UTC)
	(envelope-from nobody@FreeBSD.org)
Received: from red.freebsd.org (red.freebsd.org [IPv6:2001:4f8:fff6::22])
	by mx1.freebsd.org (Postfix) with ESMTP id 0BB2C8FC1B
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 22 Oct 2012 17:34:06 +0000 (UTC)
Received: from red.freebsd.org (localhost [127.0.0.1])
	by red.freebsd.org (8.14.5/8.14.5) with ESMTP id q9MHY51L015842
	for <freebsd-gnats-submit@FreeBSD.org>; Mon, 22 Oct 2012 17:34:05 GMT
	(envelope-from nobody@red.freebsd.org)
Received: (from nobody@localhost)
	by red.freebsd.org (8.14.5/8.14.5/Submit) id q9MHY51V015840;
	Mon, 22 Oct 2012 17:34:05 GMT
	(envelope-from nobody)
Message-Id: <201210221734.q9MHY51V015840@red.freebsd.org>
Date: Mon, 22 Oct 2012 17:34:05 GMT
From: Vincent Miller <vmiller@verisign.com>
To: freebsd-gnats-submit@FreeBSD.org
Subject: Kernel panic in udp_input()
X-Send-Pr-Version: www-3.1
X-GNATS-Notify:

>Number:         172963
>Category:       kern
>Synopsis:       [patch] [panic] Kernel panic in udp_input()
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          closed
>Quarter:        
>Keywords:       
>Date-Required:  
>Class:          sw-bug
>Submitter-Id:   current-users
>Arrival-Date:   Mon Oct 22 17:40:00 UTC 2012
>Closed-Date:    Sun Apr 28 19:14:17 UTC 2013
>Last-Modified:  Sun Apr 28 19:14:17 UTC 2013
>Originator:     Vincent Miller
>Release:        8.3-RELEASE-p4
>Organization:
>Environment:
FreeBSD flumpe15-qa2 8.3-RELEASE-p4 FreeBSD 8.3-RELEASE-p4 #0: Wed Sep 5 09:11:22 UTC 2012   root@bsdr620:/usr/obj/usr/src/sys/GENERIC amd64
>Description:
There appears to be a panic/freezing condition in FreeBSD 8.3-RELEASE-p4 in udp_input().  Please reference the panic trace below.  The condition is very similar to the issues discussed in a mail thread at http://lists.freebsd.org/pipermail/freebsd-net/2011-November/030408.html.  We have been unable to get reliable crash dumps from this panic.

Fatal trap 12: page fault while in kernel mode
cpuid = 4; apic id = 08
fault virtual address   = 0x0
fault code              = supervisor read data, page not present
instruction pointer     = 0x20:0xffffffff807a08a2
stack pointer           = 0x28:0xffffffa40c2689b0
frame pointer           = 0x28:0xffffffa40c268a80
code segment            = base 0x0, limit 0xfffff, type 0x1b
                        = DPL 0, pres 1, long 1, def32 0, gran 1
processor eflags        = interrupt enabled, resume, IOPL = 0
current process         = 12 (swi1: netisr 0)
trap number             = 12
panic: page fault
cpuid = 4
KDB: stack backtrace:
#0 0xffffffff80642b3e at kdb_backtrace+0x5e
#1 0xffffffff8060fd57 at panic+0x187
#2 0xffffffff80905990 at trap_fatal+0x290
#3 0xffffffff80905ce1 at trap_pfault+0x201
kernel trap 12 with interrupts disabled
#4 0xffffffff8090619f at trap+0x3df


#5 0xffffffff808ed674 at calltrap+0x8


#6 0xffffffff8072000c at ip_input+0xac
Fatal trap 12: page fault while in kernel mode
cpuid = 5; apic id = 0a
#7 0xffffffff806cba29 at swi_net+0x149
fault virtual address   = 0xc
#8 0xffffffff805e7794 at intr_event_execute_handlers+0x104
fault code              = supervisor read data, page not present
#9 0xffffffff805e8e25 at ithread_loop+0x95
instruction pointer     = 0x20:0xffffffff8064f795
#10 0xffffffff805e49af at fork_exit+0x11f
stack pointer           = 0x28:0xffffffa41cd969a0
#11 0xffffffff808edbbe at fork_trampoline+0xe
frame pointer           = 0x28:0xffffffa41cd969d0
code segment            = base 0x0, limit 0xfffff, type 0x1b
                        = DPL 0, pres 1, long 1, def32 0, gran 1
processor eflags        = resume, IOPL = 0
current process         = 8 (pagedaemon)
trap number             = 12
>How-To-Repeat:
We have been able to produce roughly 1 panic per day applying load to 16 hosts.  It is reproducible under heavy UDP load against systems running a UDP service.
>Fix:
N/A

>Release-Note:
>Audit-Trail:

From: "Miller, Vincent (Rick)" <vmiller@verisign.com>
To: "bug-followup@FreeBSD.org" <bug-followup@FreeBSD.org>,
        "Miller, Vincent
 (Rick)" <vmiller@verisign.com>
Cc:  
Subject: kern/172963: Kernel panic in udp_input()
Date: Wed, 24 Oct 2012 12:10:16 +0000

 --_000_9E5449BF91F9ED478E519A7166D3A82A0D682CA0BRN1WNEXMBX01vc_
 Content-Type: text/plain; charset="us-ascii"
 Content-Transfer-Encoding: quoted-printable
 
 Some of our developers spent a significant amount of time troubleshooting t=
 his.  The race condition has been identified.  The relevant information is =
 below:
 
 It is a race condition between:
 
  - udp_input()
  - udp_detach()
  - udp_pcblist()
 
  How to reproduce:
 
  - Call  sysctl(" net.inet.udp.pcblist") continuously with:
 
 $ while true; do sysctl -x net.inet.udp.pcblist > /dev/null; done;
 
  - Open a bunch of UDP sockets (to slow down udp_pcblist() call):
 
 $ for port in $(jot - 20000 24000 1); do socat -u -T 1 UDP4-LISTEN:$port,re=
 useaddr GOPEN:/dev/null & done
 
  - Launch a UDP server that close() after each request it received:
 
 $ while true; do socat -u -T 0.0001 UDP4-LISTEN:12345,reuseaddr GOPEN:/dev/=
 null; done
 
  - Bombard this server with UDP request from another machine (could be also=
  on the same machine):
 
 $ while true; do socat -u EXEC:'/bin/echo' UDP4:10.51.33.40:12345 & sleep 0=
 .0001; done
 
  - Check these messages in /var/log/messages after 5/10 minutes:
 
 Oct 24 09:05:21 flumpe4-qa2 kernel: udp_input(): Using freed inp 0xffffff0d=
 f43d7930 inp->inp_refcount 1 inp->inp_ppcb 0
 Oct 24 09:05:21 flumpe4-qa2 kernel: udp_pcblist(): Using freed inp 0xffffff=
 0df43d7930 inp->inp_refcount 1 inp->inp_ppcb 0
 
  (inp pointer being the same for udp_input() _and_ udp_pcblist(), _and_ inp=
 ->inp_ppcb being NULL)
 
  Which is the proof that: udp_input() retrieves an inp pointer 0xffffff0df4=
 3d7930 _and_ this inp has been released in_pcbrele() but not deleted becaus=
 e someone had still a reference on it (flag INP_FREED introduced by debug p=
 atch) _and_ udp_detach() has been called on this inp (inp->inp_ppcb being N=
 ULL) _and_ this is udp_pcblist() that holds this reference on this inp.
 
  Without the patch the crash will occur in udp_input():
 
         /* Check inp state */
         if ((inp->inp_flags2 & INP_FREED) && (inp->inp_socket =3D=3D NULL))=
  {
                 log(LOG_INFO, "udp_input(): Using freed inp %p inp->inp_ref=
 count %d inp->inp_ppcb %p\n",
                         inp, inp->inp_refcount, inp->inp_ppcb);
                 INP_RUNLOCK(inp);
                 goto badunlocked;
         }
         up =3D intoudpcb(inp); // intoudpcb(ip) being ((struct udpcb *)(ip)=
 ->inp_ppcb) and inp_ppcb being NULL...
         if (up->u_tun_func =3D=3D NULL) { // Panic here in default kernel
 
 --_000_9E5449BF91F9ED478E519A7166D3A82A0D682CA0BRN1WNEXMBX01vc_
 Content-Type: text/html; charset="us-ascii"
 Content-ID: <6AB7A0C7A250C648A166B4B1E0BEA58E@verisign.com>
 Content-Transfer-Encoding: quoted-printable
 
 <html>
 <head>
 <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dus-ascii"=
 >
 </head>
 <body style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-lin=
 e-break: after-white-space; color: rgb(0, 0, 0); font-size: 14px; font-fami=
 ly: Calibri, sans-serif; ">
 <div>
 <div>
 <div>Some of our developers spent a significant amount of time troubleshoot=
 ing this. &nbsp;The race condition has been identified. &nbsp;The relevant =
 information is below:</div>
 <div><br>
 </div>
 <div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 It is a race condition between:</div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <br>
 </div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 &nbsp;- udp_input()</div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 &nbsp;-&nbsp;udp_detach()</div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 &nbsp;-&nbsp;udp_pcblist()</div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <br>
 </div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 &nbsp;How to reproduce:</div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <br>
 </div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 &nbsp;- Call &nbsp;sysctl(&quot;&nbsp;net.inet.udp.pcblist&quot;) continuou=
 sly with:</div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <br>
 </div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <font face=3D"Courier" style=3D"font-size: 12px; ">$ while true; do sysctl =
 -x net.inet.udp.pcblist &gt; /dev/null; done;</font></div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <br>
 </div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 &nbsp;- Open a bunch of UDP sockets (to slow down udp_pcblist() call):</div=
 >
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <br>
 </div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <font face=3D"Courier" style=3D"font-size: 12px; ">$ for port in $(jot - 20=
 000 24000 1); do socat -u -T 1 UDP4-LISTEN:$port,reuseaddr GOPEN:/dev/null =
 &amp; done</font></div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <br>
 </div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 &nbsp;- Launch a UDP server that close() after each request it received:</d=
 iv>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <br>
 </div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <font face=3D"Courier" style=3D"font-size: 12px; ">$ while true; do socat -=
 u -T 0.0001 UDP4-LISTEN:12345,reuseaddr GOPEN:/dev/null; done</font></div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <br>
 </div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 &nbsp;- Bombard this server with UDP request from another machine (could be=
  also on the same machine):</div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <br>
 </div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <font face=3D"Courier" style=3D"font-size: 12px; ">$ while true; do socat -=
 u EXEC:'/bin/echo' UDP4:10.51.33.40:12345 &amp; sleep 0.0001; done</font></=
 div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <br>
 </div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 &nbsp;- Check these messages in /var/log/messages after 5/10 minutes:</div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <br>
 </div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <div><font face=3D"Courier" style=3D"font-size: 12px; ">Oct 24 09:05:21 flu=
 mpe4-qa2 kernel: udp_input(): Using freed inp 0xffffff0df43d7930 inp-&gt;in=
 p_refcount 1 inp-&gt;inp_ppcb 0</font></div>
 <div><font face=3D"Courier" style=3D"font-size: 12px; ">Oct 24 09:05:21 flu=
 mpe4-qa2 kernel: udp_pcblist(): Using freed inp 0xffffff0df43d7930 inp-&gt;=
 inp_refcount 1 inp-&gt;inp_ppcb 0</font></div>
 </div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <div><br>
 </div>
 </div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 &nbsp;(inp pointer being the same for udp_input() _and_ udp_pcblist(), _and=
 _ inp-&gt;inp_ppcb being NULL)</div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <br>
 </div>
 <div style=3D"font-family: Calibri; font-size: medium; "><font face=3D"Cali=
 bri,sans-serif">&nbsp;Which is the proof that:&nbsp;</font><font face=3D"Ca=
 libri,sans-serif">udp_input() retrieves an&nbsp;inp pointer&nbsp;</font><fo=
 nt face=3D"Calibri,sans-serif" style=3D"color: rgb(0, 0, 0); font-family: C=
 alibri, sans-serif; font-size: 14px; ">0xffffff0df43d7930</font><font face=
 =3D"Calibri,sans-serif" style=3D"color: rgb(0, 0, 0); font-family: Calibri,=
  sans-serif; font-size: 14px; ">&nbsp;_and_&nbsp;</font><font face=3D"Calib=
 ri,sans-serif" style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-ser=
 if; font-size: 14px; ">this
  inp has been released in_pcbrele() but not deleted because someone had sti=
 ll a&nbsp;reference on it&nbsp;(flag INP_FREED introduced by debug patch</f=
 ont><font face=3D"Calibri,sans-serif" style=3D"color: rgb(0, 0, 0); font-fa=
 mily: Calibri, sans-serif; font-size: 14px; ">)
  _and_ udp</font><font face=3D"Calibri,sans-serif" style=3D"color: rgb(0, 0=
 , 0); font-family: Calibri, sans-serif; font-size: 14px; ">_detach() has be=
 en called on this inp (inp-&gt;inp_ppcb being NULL) _and_ this is udp_pcbli=
 st() that holds this reference on this&nbsp;</font><font face=3D"Calibri,sa=
 ns-serif" style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; f=
 ont-size: 14px; ">inp</font><font face=3D"Calibri,sans-serif">.</font></div=
 >
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 &nbsp;&nbsp;</div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 &nbsp;Without the patch the crash will occur in udp_input():</div>
 <div style=3D"color: rgb(0, 0, 0); font-family: Calibri, sans-serif; font-s=
 ize: 14px; ">
 <br>
 </div>
 <div style=3D"font-family: Calibri; font-size: medium; ">
 <div style=3D"color: rgb(0, 0, 0); "><font face=3D"Courier" style=3D"font-s=
 ize: 12px; ">&nbsp; &nbsp; &nbsp; &nbsp; /* Check inp state */</font></div>
 <div style=3D"color: rgb(0, 0, 0); "><font face=3D"Courier" style=3D"font-s=
 ize: 12px; ">&nbsp; &nbsp; &nbsp; &nbsp; if ((inp-&gt;inp_flags2 &amp; INP_=
 FREED) &amp;&amp; (inp-&gt;inp_socket =3D=3D NULL)) {</font></div>
 <div style=3D"color: rgb(0, 0, 0); "><font face=3D"Courier" style=3D"font-s=
 ize: 12px; ">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; log(LO=
 G_INFO, &quot;udp_input(): Using freed inp %p inp-&gt;inp_refcount %d inp-&=
 gt;inp_ppcb %p\n&quot;,</font></div>
 <div style=3D"color: rgb(0, 0, 0); "><font face=3D"Courier" style=3D"font-s=
 ize: 12px; ">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;=
  &nbsp; &nbsp; &nbsp; inp, inp-&gt;inp_refcount, inp-&gt;inp_ppcb);</font><=
 /div>
 <div style=3D"color: rgb(0, 0, 0); "><font face=3D"Courier" style=3D"font-s=
 ize: 12px; ">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; INP_RU=
 NLOCK(inp);</font></div>
 <div style=3D"color: rgb(0, 0, 0); "><font face=3D"Courier" style=3D"font-s=
 ize: 12px; ">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; goto b=
 adunlocked;</font></div>
 <div style=3D"color: rgb(0, 0, 0); "><font face=3D"Courier" style=3D"font-s=
 ize: 12px; ">&nbsp; &nbsp; &nbsp; &nbsp; }</font></div>
 <div><font face=3D"Courier" style=3D"color: rgb(0, 0, 0); font-size: 12px; =
 ">&nbsp; &nbsp; &nbsp; &nbsp; up =3D intoudpcb(inp); //&nbsp;</font><font f=
 ace=3D"Courier"><span style=3D"font-size: 12px; ">intoudpcb(ip) being ((str=
 uct udpcb *)(ip)-&gt;inp_ppcb) and&nbsp;</span></font><span style=3D"font-f=
 amily: Courier; font-size: 12px; ">inp_ppcb
  being NULL...</span></div>
 <div>
 <div><font face=3D"Courier"><span style=3D"font-size: 12px; ">&nbsp; &nbsp;=
  &nbsp; &nbsp; if (up-&gt;u_tun_func =3D=3D NULL) { // Panic here in&nbsp;d=
 efault kernel</span></font></div>
 </div>
 </div>
 </div>
 </div>
 </div>
 </body>
 </html>
 
 --_000_9E5449BF91F9ED478E519A7166D3A82A0D682CA0BRN1WNEXMBX01vc_--

From: Julien Charbon <jcharbon@verisign.com>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/172963: Kernel panic in udp_input()
Date: Wed, 24 Oct 2012 17:47:06 +0200

   Below the patch used with previous instructions that highlights and logs this race condition:
 
 Index: sys/netinet/in_pcb.c
 ===================================================================
 --- sys/netinet/in_pcb.c	(revision 32)
 +++ sys/netinet/in_pcb.c	(working copy)
 @@ -1055,8 +1055,10 @@
   	INP_WLOCK_ASSERT(inp);
 
   	inp->inp_refcount--;
 -	if (inp->inp_refcount > 0)
 +	if (inp->inp_refcount > 0) {
 +		inp->inp_flags2 |= INP_FREED;
   		return (0);
 +	}
   	in_pcbfree_internal(inp);
   	return (1);
   }
 Index: sys/netinet/in_pcb.h
 ===================================================================
 --- sys/netinet/in_pcb.h	(revision 32)
 +++ sys/netinet/in_pcb.h	(working copy)
 @@ -443,6 +443,7 @@
    */
   #define	INP_LLE_VALID		0x00000001 /* cached lle is valid */	
   #define	INP_RT_VALID		0x00000002 /* cached rtentry is valid */
 +#define	INP_FREED		0x00000004 /* inp no more valid */
 
   #define	INPLOOKUP_WILDCARD	1
   #define	sotoinpcb(so)	((struct inpcb *)(so)->so_pcb)
 Index: sys/netinet/udp_usrreq.c
 ===================================================================
 --- sys/netinet/udp_usrreq.c	(revision 32)
 +++ sys/netinet/udp_usrreq.c	(working copy)
 @@ -624,6 +624,13 @@
   		INP_RUNLOCK(inp);
   		goto badunlocked;
   	}
 +	/* Check inp state */
 +	if ((inp->inp_flags2 & INP_FREED) && (inp->inp_socket == NULL)) {
 +		log(LOG_INFO, "udp_input(): Using freed inp %p inp->inp_refcount %d\n",
 +			inp, inp->inp_refcount);
 +		INP_RUNLOCK(inp);
 +		goto badunlocked;
 +	}
   	up = intoudpcb(inp);
   	if (up->u_tun_func == NULL) {
   		udp_append(inp, ip, m, iphlen + sizeof(struct udphdr), &udp_in);
 @@ -797,6 +804,10 @@
   	for (i = 0; i < n; i++) {
   		inp = inp_list[i];
   		INP_WLOCK(inp);
 +		if ((inp->inp_flags2 & INP_FREED) && (inp->inp_socket == NULL)) {
 +			log(LOG_INFO, "udp_pcblist(): Using freed inp %p inp->inp_refcount %d\n",
 +				inp, inp->inp_refcount);
 +		}
   		if (!in_pcbrele(inp))
   			INP_WUNLOCK(inp);
   	}
 @@ -1443,6 +1454,7 @@
   	inp = sotoinpcb(so);
   	inp->inp_vflag |= INP_IPV4;
   	inp->inp_ip_ttl = V_ip_defttl;
 +	inp->inp_flags2 = 0;
 
   	error = udp_newudpcb(inp);
   	if (error) {

From: "Charbon, Julien" <jcharbon@verisign.com>
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/172963: Kernel panic in udp_input()
Date: Fri, 26 Oct 2012 13:54:38 +0200

   I confirm that this race condition is also present in IPv6 UDP code 
 (Not a surprise as FreeBSD UDP v4 and v6 codes are pretty symmetric), 
 and below the stack trace:
 
 Fatal trap 12: page fault while in kernel mode
 cpuid = 7; apic id = 22
 fault virtual address   = 0x7
 fault code              = supervisor read data, page not present
 instruction pointer     = 0x20:0xffffffff807b60be
 stack pointer           = 0x28:0xffffffa41c83e510
 frame pointer           = 0x28:0xffffffa41c83e5a0
 code segment            = base 0x0, limit 0xfffff, type 0x1b
                          = DPL 0, pres 1, long 1, def32 0, gran 1
 processor eflags        = interrupt enabled, resume, IOPL = 0
 current process         = 12 (irq291: ix1:que 7)
 trap number             = 12
 panic: page fault
 cpuid = 7
 KDB: stack backtrace:
 #0 0xffffffff80642b3e at kdb_backtrace+0x5e
 #1 0xffffffff8060fd57 at panic+0x187
 #2 0xffffffff80905990 at trap_fatal+0x290
 #3 0xffffffff80905ce1 at trap_pfault+0x201
 #4 0xffffffff8090619f at trap+0x3df
 #5 0xffffffff808ed674 at calltrap+0x8
 #6 0xffffffff807b6986 at ip6_savecontrol+0x36
 #7 0xffffffff807cd5c0 at udp6_append+0x60
 #8 0xffffffff807ce99d at udp6_input+0x63d
 #9 0xffffffff807b76bf at ip6_input+0xb4f
 #10 0xffffffff806cb23e at netisr_dispatch_src+0x7e
 #11 0xffffffff806c12dd at ether_demux+0x14d
 #12 0xffffffff806c16e7 at ether_input+0x197
 #13 0xffffffff806c11ff at ether_demux+0x6f
 #14 0xffffffff806c16e7 at ether_input+0x197
 #15 0xffffffff803e3d8b at ixgbe_rxeof+0x1eb
 #16 0xffffffff803e4578 at ixgbe_msix_que+0xa8
 #17 0xffffffff805e7794 at intr_event_execute_handlers+0x104
 
 --
 Julien

From: "De La Gueronniere, Marc" <mdelagueronniere@verisign.com>
To: "bug-followup@FreeBSD.org" <bug-followup@FreeBSD.org>
Cc:  
Subject: Re: kern/172963: [patch] [panic] Kernel panic in udp_input()
Date: Tue, 30 Oct 2012 12:17:57 +0000

 --_004_E56E3233C2539B4B9DC3A8138715D0F80E7CEFBRN1WNEXMBX01vcor_
 Content-Type: multipart/alternative;
 	boundary="_000_E56E3233C2539B4B9DC3A8138715D0F80E7CEFBRN1WNEXMBX01vcor_"
 
 --_000_E56E3233C2539B4B9DC3A8138715D0F80E7CEFBRN1WNEXMBX01vcor_
 Content-Type: text/plain; charset="us-ascii"
 Content-Transfer-Encoding: quoted-printable
 
 Here is the patch we are successfully using so far.
 
 Marc de la Gueronniere
 
 --_000_E56E3233C2539B4B9DC3A8138715D0F80E7CEFBRN1WNEXMBX01vcor_
 Content-Type: text/html; charset="us-ascii"
 Content-ID: <ED77CBC1999ABD409A656A172C143827@verisign.com>
 Content-Transfer-Encoding: quoted-printable
 
 <html>
 <head>
 <meta http-equiv=3D"Content-Type" content=3D"text/html; charset=3Dus-ascii"=
 >
 </head>
 <body style=3D"word-wrap: break-word; -webkit-nbsp-mode: space; -webkit-lin=
 e-break: after-white-space; color: rgb(0, 0, 0); font-size: 14px; font-fami=
 ly: Calibri, sans-serif; ">
 <div>Here is the patch we are successfully using so far.</div>
 <div><br>
 </div>
 <div>Marc de la Gueronniere</div>
 </body>
 </html>
 
 --_000_E56E3233C2539B4B9DC3A8138715D0F80E7CEFBRN1WNEXMBX01vcor_--
 
 --_004_E56E3233C2539B4B9DC3A8138715D0F80E7CEFBRN1WNEXMBX01vcor_
 Content-Type: application/octet-stream;
 	name="patch_udp_input_8_3p4_pr_kern_172963.patch"
 Content-Description: patch_udp_input_8_3p4_pr_kern_172963.patch
 Content-Disposition: attachment;
 	filename="patch_udp_input_8_3p4_pr_kern_172963.patch"; size=1609;
 	creation-date="Tue, 30 Oct 2012 12:17:57 GMT";
 	modification-date="Tue, 30 Oct 2012 12:17:57 GMT"
 Content-ID: <E30FD4E9F08990419DA7E9D264855A21@verisign.com>
 Content-Transfer-Encoding: base64
 
 Y29tbWl0IDQ5N2FhMmJjNmY0YjczODMzNDRhYjdmZDgxMmQyOTZjNjk5NzI5OGQKQXV0aG9yOiBN
 YXJjIGRlIGxhIEd1ZXJvbm5pZXJlIDxtZGVsYWd1ZXJvbm5pZXJlQHZlcmlzaWduLmNvbT4KRGF0
 ZTogICBXZWQgT2N0IDI0IDE5OjU5OjQxIDIwMTIgKzAwMDAKCiAgICBrZXJuLzE3Mjk2MzogS2Vy
 bmVsIHBhbmljIGluIHVkcF9pbnB1dCgpCgpkaWZmIC0tZ2l0IGEvc3lzL25ldGluZXQvdWRwX3Vz
 cnJlcS5jIGIvc3lzL25ldGluZXQvdWRwX3VzcnJlcS5jCmluZGV4IGI3MjAzNjQuLmY5ZDAyNDUg
 MTAwNjQ0Ci0tLSBhL3N5cy9uZXRpbmV0L3VkcF91c3JyZXEuYworKysgYi9zeXMvbmV0aW5ldC91
 ZHBfdXNycmVxLmMKQEAgLTQ5NCw2ICs0OTQsMTIgQEAgdWRwX2lucHV0KHN0cnVjdCBtYnVmICpt
 LCBpbnQgb2ZmKQogCiAJCQlJTlBfUkxPQ0soaW5wKTsKIAorCQkJLy8gaW5fcGNiZHJvcCBkb2Vz
 IG5vdCB1bmxpbmsgZnJvbSBWX3VkYgorCQkJaWYgKGlucC0+aW5wX3NvY2tldCA9PSBOVUxMKSB7
 CisJCQkJSU5QX1JVTkxPQ0soaW5wKTsKKwkJCQljb250aW51ZTsKKwkJCX0KKwogCQkJLyoKIAkJ
 CSAqIEhhbmRsZSBzb2NrZXQgZGVsaXZlcnkgcG9saWN5IGZvciBhbnktc291cmNlCiAJCQkgKiBh
 bmQgc291cmNlLXNwZWNpZmljIG11bHRpY2FzdC4gW1JGQzM2NzhdCkBAIC0xNTU5LDYgKzE1NjUs
 NyBAQCB1ZHBfZGV0YWNoKHN0cnVjdCBzb2NrZXQgKnNvKQogCUtBU1NFUlQodXAgIT0gTlVMTCwg
 KCIlczogdXAgPT0gTlVMTCIsIF9fZnVuY19fKSk7CiAJaW5wLT5pbnBfcHBjYiA9IE5VTEw7CiAJ
 aW5fcGNiZGV0YWNoKGlucCk7CisJaW5fcGNiZHJvcChpbnApOwogCWluX3BjYmZyZWUoaW5wKTsK
 IAlJTlBfSU5GT19XVU5MT0NLKCZWX3VkYmluZm8pOwogCXVkcF9kaXNjYXJkY2IodXApOwpkaWZm
 IC0tZ2l0IGEvc3lzL25ldGluZXQ2L3VkcDZfdXNycmVxLmMgYi9zeXMvbmV0aW5ldDYvdWRwNl91
 c3JyZXEuYwppbmRleCAyMmRkZGU0Li4yZThiNTY0IDEwMDY0NAotLS0gYS9zeXMvbmV0aW5ldDYv
 dWRwNl91c3JyZXEuYworKysgYi9zeXMvbmV0aW5ldDYvdWRwNl91c3JyZXEuYwpAQCAtMjcxLDYg
 KzI3MSwxMCBAQCB1ZHA2X2lucHV0KHN0cnVjdCBtYnVmICoqbXAsIGludCAqb2ZmcCwgaW50IHBy
 b3RvKQogCQkJCSAgICBpbnAtPmlucF9mcG9ydCAhPSB1aC0+dWhfc3BvcnQpCiAJCQkJCWNvbnRp
 bnVlOwogCQkJfQorCQkJLy8gaW5fcGNiZHJvcCBkb2VzIG5vdCB1bmxpbmsgZnJvbSBWX3VkYgor
 CQkJaWYgKGlucC0+aW5wX3NvY2tldCA9PSBOVUxMKSB7CisJCQkJY29udGludWU7CisJCQl9CiAK
 IAkJCS8qCiAJCQkgKiBIYW5kbGUgc29ja2V0IGRlbGl2ZXJ5IHBvbGljeSBmb3IgYW55LXNvdXJj
 ZQpAQCAtOTY0LDYgKzk2OCw3IEBAIHVkcDZfZGV0YWNoKHN0cnVjdCBzb2NrZXQgKnNvKQogCXVw
 ID0gaW50b3VkcGNiKGlucCk7CiAJS0FTU0VSVCh1cCAhPSBOVUxMLCAoIiVzOiB1cCA9PSBOVUxM
 IiwgX19mdW5jX18pKTsKIAlpbl9wY2JkZXRhY2goaW5wKTsKKwlpbl9wY2Jkcm9wKGlucCk7CiAJ
 aW5fcGNiZnJlZShpbnApOwogCUlOUF9JTkZPX1dVTkxPQ0soJlZfdWRiaW5mbyk7CiAJdWRwX2Rp
 c2NhcmRjYih1cCk7Cg==
 
 --_004_E56E3233C2539B4B9DC3A8138715D0F80E7CEFBRN1WNEXMBX01vcor_--

From: "Charbon, Julien" <jcharbon@verisign.com>
To: bug-followup@FreeBSD.org
Cc: rwatson@FreeBSD.org,
        "De La Gueronniere, Marc" <mdelagueronniere@verisign.com>
Subject: Re: kern/172963: Kernel panic in udp_input()
Date: Tue, 09 Apr 2013 16:51:41 +0200

 This is a multi-part message in MIME format.
 --------------000809060905090504090109
 Content-Type: text/plain; charset=ISO-8859-1; format=flowed
 Content-Transfer-Encoding: 7bit
 
 
   I confirm this issue is still reproducible in FreeBSD 8.4-BETA1.
 Joined a smaller patch wrote my Marc to fix it.
 
 --
 Julien
 
 --------------000809060905090504090109
 Content-Type: text/plain; charset=UTF-8; x-mac-type="0"; x-mac-creator="0";
  name="udp_input_panic_minimal.patch"
 Content-Transfer-Encoding: 7bit
 Content-Disposition: attachment;
  filename="udp_input_panic_minimal.patch"
 
 diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c
 index b720364..25c741a 100644
 --- a/sys/netinet/udp_usrreq.c
 +++ b/sys/netinet/udp_usrreq.c
 @@ -493,7 +493,14 @@ udp_input(struct mbuf *m, int off)
  				continue;
  
  			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 +627,14 @@ 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;
 diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c
 index 22ddde4..78b4b84 100644
 --- a/sys/netinet6/udp6_usrreq.c
 +++ b/sys/netinet6/udp6_usrreq.c
 @@ -271,7 +271,13 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
  				    inp->inp_fport != uh->uh_sport)
  					continue;
  			}
 -
 +			/*
 +			 * 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 +402,14 @@ udp6_input(struct mbuf **mp, int *offp, int proto)
  	}
  	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);
 
 --------------000809060905090504090109--

From: "Robert N. M. Watson" <rwatson@FreeBSD.org>
To: "Charbon, Julien" <jcharbon@verisign.com>
Cc: bug-followup@FreeBSD.org,
 "De La Gueronniere, Marc" <mdelagueronniere@verisign.com>
Subject: Re: kern/172963: Kernel panic in udp_input()
Date: Tue, 9 Apr 2013 16:33:01 +0100

 Thanks -- I'll try to look at this tonight. Definitely want to fix this =
 before 8.4 ships, if we can -- apologies for the delay :-(.
 
 Robert
 
 On 9 Apr 2013, at 15:51, Charbon, Julien wrote:
 
 > <udp_input_panic_minimal.patch>
 

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"
 

From: "Robert N. M. Watson" <rwatson@FreeBSD.org>
To: "Charbon, Julien" <jcharbon@verisign.com>
Cc: bug-followup@FreeBSD.org,
 "De La Gueronniere, Marc" <mdelagueronniere@verisign.com>
Subject: Re: kern/172963: Kernel panic in udp_input()
Date: Sun, 14 Apr 2013 17:33:05 +0100

 Hi Julien:
 
 I've committed the patch, with minor style tweaks, to stable/8. I also =
 communicated, a few days ago, to re@ that we need to get this fix into =
 the next 8.4 release candidate, and they are willing to hold the release =
 candidate for the merge. I'll ping re@ and find out how quickly they =
 want me to do the releng/8.4 merge. Regardless, it sounds like it will =
 successfully make 8.4
 
 Thanks again for your patience over the last few months, and also for =
 the assiduous debugging and patch generation!
 
 Robert
 
 On 9 Apr 2013, at 15:51, Charbon, Julien wrote:
 
 >=20
 > I confirm this issue is still reproducible in FreeBSD 8.4-BETA1.
 > Joined a smaller patch wrote my Marc to fix it.
 >=20
 > --
 > Julien
 > <udp_input_panic_minimal.patch>
 

From: dfilter@FreeBSD.ORG (dfilter service)
To: bug-followup@FreeBSD.org
Cc:  
Subject: Re: kern/172963: commit references a PR
Date: Fri, 19 Apr 2013 21:09:04 +0000 (UTC)

 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 <vmiller@verisign.com>
     Submitted by: Julien Charbon <jcharbon@verisign.com>
     Submitted by: Marc De La Gueronniere <mdelagueronniere@verisign.com>
   
   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);
 _______________________________________________
 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"
 

From: Robert Watson <rwatson@FreeBSD.org>
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 <rwatson@FreeBSD.org>
 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 <vmiller@verisign.com>
      Submitted by: Julien Charbon <jcharbon@verisign.com>
      Submitted by: Marc De La Gueronniere <mdelagueronniere@verisign.com>
 
    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);
State-Changed-From-To: open->closed 
State-Changed-By: rwatson 
State-Changed-When: Sun Apr 28 19:12:41 UTC 2013 
State-Changed-Why:  
Close PR -- patch now merged to releng/8 and in particular the forthcoming 
8.x release.  Please let me know if you encounter any further issues -- and 
thanks for submitting the patch! 


http://www.freebsd.org/cgi/query-pr.cgi?pr=172963 
>Unformatted:
