diff options
author | jprakash <none@none> | 2007-12-14 11:26:33 -0800 |
---|---|---|
committer | jprakash <none@none> | 2007-12-14 11:26:33 -0800 |
commit | ba3431dfb95fc82442859727ae0167740201a8d2 (patch) | |
tree | b343254dacd226d190456523a354f023267ede85 /usr/src | |
parent | 859a234bf154da24a4db926cc2f6f367ccdc3942 (diff) | |
download | illumos-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.c | 18 |
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. */ |