The following reply was made to PR kern/172963; it has been noted by GNATS.

From: Julien Charbon <jchar...@verisign.com>
To: bug-follo...@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) {
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to