summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authororion <orion@FreeBSD.org>2003-05-01 16:31:21 +0000
committerorion <orion@FreeBSD.org>2003-05-01 16:31:21 +0000
commit9f865e3f305382acb9ff15f7e8bcd92f244cfc48 (patch)
treed03c67c153056249303290f57413b28eb7090f56
parent60e1df174c66f8f3654ea24be41b8b06bfe3cf28 (diff)
downloadFreeBSD-src-9f865e3f305382acb9ff15f7e8bcd92f244cfc48.zip
FreeBSD-src-9f865e3f305382acb9ff15f7e8bcd92f244cfc48.tar.gz
Fix lock order reversal when opening device and chn_reset fails.
Submitted by: Jan-Espen Pettersen <sigsegv@leakingmemory.org> Tested by: Georg Funk <georgfunk@web.de>
-rw-r--r--sys/dev/sound/pcm/dsp.c9
1 files changed, 4 insertions, 5 deletions
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
index 65ff150..04622d2 100644
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -262,13 +262,12 @@ dsp_open(dev_t i_dev, int flags, int mode, struct thread *td)
i_dev->si_drv1 = rdch;
i_dev->si_drv2 = wrch;
- pcm_unlock(d);
- /* finished with snddev, new channels still locked */
- /* bump refcounts, reset and unlock any channels that we just opened */
+ /* Bump refcounts, reset and unlock any channels that we just opened,
+ * and then release device lock.
+ */
if (flags & FREAD) {
if (chn_reset(rdch, fmt)) {
- pcm_lock(d);
pcm_chnrelease(rdch);
i_dev->si_drv1 = NULL;
if (wrch && (flags & FWRITE)) {
@@ -286,7 +285,6 @@ dsp_open(dev_t i_dev, int flags, int mode, struct thread *td)
}
if (flags & FWRITE) {
if (chn_reset(wrch, fmt)) {
- pcm_lock(d);
pcm_chnrelease(wrch);
i_dev->si_drv2 = NULL;
if (flags & FREAD) {
@@ -304,6 +302,7 @@ dsp_open(dev_t i_dev, int flags, int mode, struct thread *td)
pcm_chnref(wrch, 1);
CHN_UNLOCK(wrch);
}
+ pcm_unlock(d);
splx(s);
return 0;
}
OpenPOWER on IntegriCloud