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);