summaryrefslogtreecommitdiff
path: root/usr/src
diff options
context:
space:
mode:
authorjprakash <none@none>2007-12-14 11:26:33 -0800
committerjprakash <none@none>2007-12-14 11:26:33 -0800
commitba3431dfb95fc82442859727ae0167740201a8d2 (patch)
treeb343254dacd226d190456523a354f023267ede85 /usr/src
parent859a234bf154da24a4db926cc2f6f367ccdc3942 (diff)
downloadillumos-gate-ba3431dfb95fc82442859727ae0167740201a8d2.tar.gz
6447961 race between two threads to connect() to a socket can cause panic
Diffstat (limited to 'usr/src')
-rw-r--r--usr/src/uts/common/fs/sockfs/socktpi.c18
1 files changed, 10 insertions, 8 deletions
diff --git a/usr/src/uts/common/fs/sockfs/socktpi.c b/usr/src/uts/common/fs/sockfs/socktpi.c
index a198c17176..4556eaa736 100644
--- a/usr/src/uts/common/fs/sockfs/socktpi.c
+++ b/usr/src/uts/common/fs/sockfs/socktpi.c
@@ -1972,11 +1972,17 @@ sotpi_connect(struct sonode *so,
mutex_enter(&so->so_lock);
/*
- * Make sure that there is a preallocated unbind_req
- * message before any binding. This message allocated when
- * the socket is created but it might be have been
- * consumed.
+ * Make sure there is a preallocated T_unbind_req message
+ * before any binding. This message is allocated when the
+ * socket is created. Since another thread can consume
+ * so_unbind_mp by the time we return from so_lock_single(),
+ * we should check the availability of so_unbind_mp after
+ * we return from so_lock_single().
*/
+
+ so_lock_single(so); /* Set SOLOCKED */
+ need_unlock = B_TRUE;
+
if (so->so_unbind_mp == NULL) {
dprintso(so, 1, ("sotpi_connect: allocating unbind_req\n"));
/* NOTE: holding so_lock while sleeping */
@@ -1984,14 +1990,10 @@ sotpi_connect(struct sonode *so,
soallocproto(sizeof (struct T_unbind_req), _ALLOC_INTR);
if (so->so_unbind_mp == NULL) {
error = EINTR;
- need_unlock = B_FALSE;
goto done;
}
}
- so_lock_single(so); /* Set SOLOCKED */
- need_unlock = B_TRUE;
-
/*
* Can't have done a listen before connecting.
*/