The UDP head was unlocked too early in one unicast case.

Submitted by:	bug reported by arr
This commit is contained in:
hsu 2002-06-12 15:21:41 +00:00
parent bbbd62ac9e
commit c580ba61b3

View File

@ -337,15 +337,13 @@ udp_input(m, off)
* for a broadcast or multicast datgram.) * for a broadcast or multicast datgram.)
*/ */
udpstat.udps_noportbcast++; udpstat.udps_noportbcast++;
INP_INFO_RUNLOCK(&udbinfo); goto badheadlocked;
goto bad;
} }
#ifdef IPSEC #ifdef IPSEC
/* check AH/ESP integrity. */ /* check AH/ESP integrity. */
if (ipsec4_in_reject_so(m, last->inp_socket)) { if (ipsec4_in_reject_so(m, last->inp_socket)) {
ipsecstat.in_polvio++; ipsecstat.in_polvio++;
INP_INFO_RUNLOCK(&udbinfo); goto badheadlocked;
goto bad;
} }
#endif /*IPSEC*/ #endif /*IPSEC*/
INP_UNLOCK(last); INP_UNLOCK(last);
@ -358,7 +356,6 @@ udp_input(m, off)
*/ */
inp = in_pcblookup_hash(&udbinfo, ip->ip_src, uh->uh_sport, inp = in_pcblookup_hash(&udbinfo, ip->ip_src, uh->uh_sport,
ip->ip_dst, uh->uh_dport, 1, m->m_pkthdr.rcvif); ip->ip_dst, uh->uh_dport, 1, m->m_pkthdr.rcvif);
INP_INFO_RUNLOCK(&udbinfo);
if (inp == NULL) { if (inp == NULL) {
if (log_in_vain) { if (log_in_vain) {
char buf[4*sizeof "123"]; char buf[4*sizeof "123"];
@ -372,27 +369,27 @@ udp_input(m, off)
udpstat.udps_noport++; udpstat.udps_noport++;
if (m->m_flags & (M_BCAST | M_MCAST)) { if (m->m_flags & (M_BCAST | M_MCAST)) {
udpstat.udps_noportbcast++; udpstat.udps_noportbcast++;
goto bad; goto badheadlocked;
} }
if (badport_bandlim(BANDLIM_ICMP_UNREACH) < 0) if (badport_bandlim(BANDLIM_ICMP_UNREACH) < 0)
goto bad; goto badheadlocked;
if (blackhole) if (blackhole)
goto bad; goto badheadlocked;
*ip = save_ip; *ip = save_ip;
ip->ip_len += iphlen; ip->ip_len += iphlen;
icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0); icmp_error(m, ICMP_UNREACH, ICMP_UNREACH_PORT, 0, 0);
INP_INFO_RUNLOCK(&udbinfo); INP_INFO_RUNLOCK(&udbinfo);
return; return;
} }
INP_LOCK(inp);
INP_INFO_RUNLOCK(&udbinfo);
#ifdef IPSEC #ifdef IPSEC
if (ipsec4_in_reject_so(m, inp->inp_socket)) { if (ipsec4_in_reject_so(m, inp->inp_socket)) {
ipsecstat.in_polvio++; ipsecstat.in_polvio++;
INP_INFO_RUNLOCK(&udbinfo);
goto bad; goto bad;
} }
#endif /*IPSEC*/ #endif /*IPSEC*/
INP_LOCK(inp);
/* /*
* Construct sockaddr format source address. * Construct sockaddr format source address.
* Stuff source address and datagram in user buffer. * Stuff source address and datagram in user buffer.
@ -429,6 +426,9 @@ udp_input(m, off)
sorwakeup(inp->inp_socket); sorwakeup(inp->inp_socket);
INP_UNLOCK(inp); INP_UNLOCK(inp);
return; return;
badheadlocked:
INP_INFO_RUNLOCK(&udbinfo);
bad: bad:
if (inp) if (inp)
INP_UNLOCK(inp); INP_UNLOCK(inp);