aboutsummaryrefslogtreecommitdiff
path: root/sys/netsmb
diff options
context:
space:
mode:
authorRick Macklem <rmacklem@FreeBSD.org>2015-11-16 23:19:53 +0000
committerRick Macklem <rmacklem@FreeBSD.org>2015-11-16 23:19:53 +0000
commite06f502c9e76b300c1844c1c6e0af103751f6c12 (patch)
tree5bc6e87a7d1e8ccb9bb7bb172685fa6b66763148 /sys/netsmb
parent7888a51f8d38c2694d7eebce10288bb354092091 (diff)
downloadsrc-e06f502c9e76b300c1844c1c6e0af103751f6c12.tar.gz
src-e06f502c9e76b300c1844c1c6e0af103751f6c12.zip
When the smbfs iod thread (smb_iod_thread()) is shutting down, smb_iod_destroy()
would call smb_iod_request(). This call could return as soon as the wakeup(evp) in smb_iod_main() call is done and then could destroy the mutexes. This caused a race with the rest of smb_iod_main()s use of these mutexes. A crash reported on freebsd-stable@ by Christian Kratzer was diagnosed as a use of one of these mutexes after it was destroyed. This patch moves destruction of the mutexes from smb_iod_destroy() to the end of smb_iod_thread(), so that they aren't destroyed before the thread is done with them. Christian comfirmed that the patch stopped the crashes from happening. Reported by: ck-lists@cksoft.de (Christian Kratzer) Tested by: ck-lists@cksoft.de (Christian Kratzer) Diagnosed by: jhb Reviewed by: jhb MFC after: 2 weeks
Notes
Notes: svn path=/head/; revision=290959
Diffstat (limited to 'sys/netsmb')
-rw-r--r--sys/netsmb/smb_iod.c8
1 files changed, 5 insertions, 3 deletions
diff --git a/sys/netsmb/smb_iod.c b/sys/netsmb/smb_iod.c
index dfdd6f2acaf7..ae5c6f721c44 100644
--- a/sys/netsmb/smb_iod.c
+++ b/sys/netsmb/smb_iod.c
@@ -659,6 +659,11 @@ smb_iod_thread(void *arg)
break;
tsleep(&iod->iod_flags, PWAIT, "90idle", iod->iod_sleeptimo);
}
+
+ /* We can now safely destroy the mutexes and free the iod structure. */
+ smb_sl_destroy(&iod->iod_rqlock);
+ smb_sl_destroy(&iod->iod_evlock);
+ free(iod, M_SMBIOD);
mtx_unlock(&Giant);
kproc_exit(0);
}
@@ -695,9 +700,6 @@ int
smb_iod_destroy(struct smbiod *iod)
{
smb_iod_request(iod, SMBIOD_EV_SHUTDOWN | SMBIOD_EV_SYNC, NULL);
- smb_sl_destroy(&iod->iod_rqlock);
- smb_sl_destroy(&iod->iod_evlock);
- free(iod, M_SMBIOD);
return 0;
}