From 2f8c108bd4b7e18519ea0b1ecd0d889776121703 Mon Sep 17 00:00:00 2001 From: Sepherosa Ziehau Date: Tue, 3 Nov 2015 11:32:22 +0800 Subject: [PATCH] uipc: Hold unp_token before calling unp_find_lockref() Mainly to avoid name resolution and v_socket accessing races. Add comment about it. --- sys/kern/uipc_usrreq.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/sys/kern/uipc_usrreq.c b/sys/kern/uipc_usrreq.c index e8b53d271b..e18ec924fe 100644 --- a/sys/kern/uipc_usrreq.c +++ b/sys/kern/uipc_usrreq.c @@ -549,8 +549,10 @@ uipc_send(netmsg_t msg) error = EISCONN; break; } + lwkt_gettoken(&unp_token); error = unp_find_lockref(msg->send.nm_addr, msg->send.nm_td, so->so_type, &unp2); + lwkt_reltoken(&unp_token); if (error) break; /* @@ -2061,6 +2063,16 @@ unp_discard(struct file *fp, void *data __unused) taskqueue_enqueue(unp_taskqueue, &unp_defdiscard_task); } +/* + * NOTE: + * unp_token must be held before calling this function to avoid name + * resolution and v_socket accessing races, especially racing against + * the unp_detach(). + * + * NOTE: + * For anyone caring about unconnected unix socket sending performance, + * other approach could be taken... + */ static int unp_find_lockref(struct sockaddr *nam, struct thread *td, short type, struct unpcb **unp_ret) @@ -2074,6 +2086,8 @@ unp_find_lockref(struct sockaddr *nam, struct thread *td, short type, struct nlookupdata nd; char buf[SOCK_MAXADDRLEN]; + ASSERT_LWKT_TOKEN_HELD(&unp_token); + *unp_ret = NULL; len = nam->sa_len - offsetof(struct sockaddr_un, sun_path); -- 2.41.0