From owner-freebsd-bugs@FreeBSD.ORG Wed Oct 24 16:10:01 2012 Return-Path: Delivered-To: freebsd-bugs@hub.freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id BCB78FBE for ; Wed, 24 Oct 2012 16:10:01 +0000 (UTC) (envelope-from gnats@FreeBSD.org) Received: from freefall.freebsd.org (freefall.FreeBSD.org [8.8.178.135]) by mx1.freebsd.org (Postfix) with ESMTP id 8CC8E8FC16 for ; Wed, 24 Oct 2012 16:10:01 +0000 (UTC) Received: from freefall.freebsd.org (localhost [127.0.0.1]) by freefall.freebsd.org (8.14.5/8.14.5) with ESMTP id q9OGA1uq044839 for ; Wed, 24 Oct 2012 16:10:01 GMT (envelope-from gnats@freefall.freebsd.org) Received: (from gnats@localhost) by freefall.freebsd.org (8.14.5/8.14.5/Submit) id q9OGA1tP044838; Wed, 24 Oct 2012 16:10:01 GMT (envelope-from gnats) Date: Wed, 24 Oct 2012 16:10:01 GMT Message-Id: <201210241610.q9OGA1tP044838@freefall.freebsd.org> To: freebsd-bugs@FreeBSD.org Cc: From: Julien Charbon Subject: Re: kern/172963: Kernel panic in udp_input() X-BeenThere: freebsd-bugs@freebsd.org X-Mailman-Version: 2.1.14 Precedence: list Reply-To: Julien Charbon List-Id: Bug reports List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 24 Oct 2012 16:10:01 -0000 The following reply was made to PR kern/172963; it has been noted by GNATS. From: Julien Charbon 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) {