Skip site navigation (1)Skip section navigation (2)
Date:      Wed, 24 Oct 2012 16:10:01 GMT
From:      Julien Charbon <jcharbon@verisign.com>
To:        freebsd-bugs@FreeBSD.org
Subject:   Re: kern/172963: Kernel panic in udp_input()
Message-ID:  <201210241610.q9OGA1tP044838@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: 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) {



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