From dec802607305a906438545a818fbf96dfbd54a01 Mon Sep 17 00:00:00 2001 From: Robert Watson Date: Wed, 12 Apr 2006 03:32:54 +0000 Subject: [PATCH] Add comment to udp6_input() that locking is missing from multicast UDPv6 delivery. Lock the inpcb of the UDP connection being delivered to before processing IPSEC policy and other delivery activities. MFC after: 3 months --- sys/netinet6/udp6_usrreq.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 61c8ea1bd92a..71578455c57b 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -217,6 +217,9 @@ udp6_input(mp, offp, proto) /* * Locate pcb(s) for datagram. * (Algorithm copied from raw_intr().) + * + * XXXRW: The individual inpcbs need to be locked in the + * style of udp_input(). */ last = NULL; LIST_FOREACH(in6p, &udb, inp_list) { @@ -331,7 +334,7 @@ udp6_input(mp, offp, proto) in6p = in6_pcblookup_hash(&udbinfo, &ip6->ip6_src, uh->uh_sport, &ip6->ip6_dst, uh->uh_dport, 1, m->m_pkthdr.rcvif); - if (in6p == 0) { + if (in6p == NULL) { if (log_in_vain) { char buf[INET6_ADDRSTRLEN]; @@ -351,11 +354,13 @@ udp6_input(mp, offp, proto) icmp6_error(m, ICMP6_DST_UNREACH, ICMP6_DST_UNREACH_NOPORT, 0); return IPPROTO_DONE; } + INP_LOCK(in6p); #if defined(IPSEC) || defined(FAST_IPSEC) /* * Check AH/ESP integrity. */ if (ipsec6_in_reject(m, in6p)) { + INP_UNLOCK(in6p); #ifdef IPSEC ipsec6stat.in_polvio++; #endif /* IPSEC */ @@ -375,10 +380,12 @@ udp6_input(mp, offp, proto) m_adj(m, off + sizeof(struct udphdr)); if (sbappendaddr(&in6p->in6p_socket->so_rcv, (struct sockaddr *)&fromsa, m, opts) == 0) { + INP_UNLOCK(in6p); udpstat.udps_fullsock++; goto bad; } sorwakeup(in6p->in6p_socket); + INP_UNLOCK(in6p); INP_INFO_RUNLOCK(&udbinfo); return IPPROTO_DONE; bad: