From aad1f73434c23d80797f63cc5c7596f64814c482 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Fri, 21 Jan 2011 13:55:36 +0800 Subject: [PATCH] udp6: Protect udbinfo by udbinfo barrier --- sys/netinet/udp_usrreq.c | 6 ++---- sys/netinet/udp_var.h | 2 ++ sys/netinet6/udp6_usrreq.c | 24 ++++++++++++++++++------ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/sys/netinet/udp_usrreq.c b/sys/netinet/udp_usrreq.c index 3ba2b2813b..b4a439a49f 100644 --- a/sys/netinet/udp_usrreq.c +++ b/sys/netinet/udp_usrreq.c @@ -183,8 +183,6 @@ static int udp_connect_oncpu(struct socket *so, struct thread *td, struct sockaddr_in *sin, struct sockaddr_in *if_sin); static int udp_output (struct inpcb *, struct mbuf *, struct sockaddr *, struct mbuf *, struct thread *); -static void udbinfo_barrier_set(void); -static void udbinfo_barrier_rem(void); void udp_init(void) @@ -1291,14 +1289,14 @@ udbinfo_unlock(void) lwkt_serialize_exit(&udbinfo_slize); } -static void +void udbinfo_barrier_set(void) { netisr_barrier_set(udbinfo_br); udbinfo_lock(); } -static void +void udbinfo_barrier_rem(void) { udbinfo_unlock(); diff --git a/sys/netinet/udp_var.h b/sys/netinet/udp_var.h index 513c6ba6fc..654b99c349 100644 --- a/sys/netinet/udp_var.h +++ b/sys/netinet/udp_var.h @@ -160,6 +160,8 @@ struct lwkt_port *udp_cport (int); void udbinfo_lock(void); void udbinfo_unlock(void); +void udbinfo_barrier_set(void); +void udbinfo_barrier_rem(void); #endif diff --git a/sys/netinet6/udp6_usrreq.c b/sys/netinet6/udp6_usrreq.c index 1c4e837962..2b43d8ac45 100644 --- a/sys/netinet6/udp6_usrreq.c +++ b/sys/netinet6/udp6_usrreq.c @@ -556,7 +556,10 @@ udp6_abort(netmsg_t msg) inp = so->so_pcb; if (inp) { soisdisconnected(so); + + udbinfo_barrier_set(); in6_pcbdetach(inp); + udbinfo_barrier_rem(); error = 0; } else { error = EINVAL; @@ -584,11 +587,14 @@ udp6_attach(netmsg_t msg) if (error) goto out; } - crit_enter(); + + udbinfo_barrier_set(); error = in_pcballoc(so, &udbinfo); - crit_exit(); + udbinfo_barrier_rem(); + if (error) goto out; + sosetport(so, cpu_portfn(0)); inp = (struct inpcb *)so->so_pcb; inp->inp_vflag |= INP_IPV6; @@ -648,7 +654,10 @@ udp6_bind(netmsg_t msg) if (error == 0) { if (IN6_IS_ADDR_UNSPECIFIED(&sin6_p->sin6_addr)) inp->inp_flags |= INP_WASBOUND_NOTANY; + + udbinfo_barrier_set(); in_pcbinswildcardhash(inp); + udbinfo_barrier_rem(); } out: lwkt_replymsg(&msg->bind.base.lmsg, error); @@ -663,6 +672,8 @@ udp6_connect(netmsg_t msg) struct inpcb *inp; int error; + udbinfo_barrier_set(); + inp = so->so_pcb; if (inp == NULL) { error = EINVAL; @@ -722,6 +733,7 @@ udp6_connect(netmsg_t msg) in_pcbinswildcardhash(inp); } out: + udbinfo_barrier_rem(); lwkt_replymsg(&msg->connect.base.lmsg, error); } @@ -734,9 +746,9 @@ udp6_detach(netmsg_t msg) inp = so->so_pcb; if (inp) { - crit_enter(); + udbinfo_barrier_set(); in6_pcbdetach(inp); - crit_exit(); + udbinfo_barrier_rem(); error = 0; } else { error = EINVAL; @@ -768,9 +780,9 @@ udp6_disconnect(netmsg_t msg) if (IN6_IS_ADDR_UNSPECIFIED(&inp->in6p_faddr)) { error = ENOTCONN; } else { - crit_enter(); + udbinfo_barrier_set(); in6_pcbdisconnect(inp); - crit_exit(); + udbinfo_barrier_rem(); soclrstate(so, SS_ISCONNECTED); /* XXX */ error = 0; } -- 2.41.0