Source-Changes-HG archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

[src/trunk]: src/sys/dev/audio audio(4): Wait for opens to drain in detach.



details:   https://anonhg.NetBSD.org/src/rev/01571300956c
branches:  trunk
changeset: 365703:01571300956c
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Tue Apr 19 09:19:53 2022 +0000

description:
audio(4): Wait for opens to drain in detach.

Otherwise detach may barge ahead and start freeing things before open
has finished and is about to use them after free.

Reported-by: syzbot+31d2619e72c2c8436cc9%syzkaller.appspotmail.com@localhost

diffstat:

 sys/dev/audio/audio.c |  15 +++++++++++++--
 1 files changed, 13 insertions(+), 2 deletions(-)

diffs (43 lines):

diff -r dcb74c66cba7 -r 01571300956c sys/dev/audio/audio.c
--- a/sys/dev/audio/audio.c     Tue Apr 19 01:35:28 2022 +0000
+++ b/sys/dev/audio/audio.c     Tue Apr 19 09:19:53 2022 +0000
@@ -1,4 +1,4 @@
-/*     $NetBSD: audio.c,v 1.123 2022/04/09 23:35:58 riastradh Exp $    */
+/*     $NetBSD: audio.c,v 1.124 2022/04/19 09:19:53 riastradh Exp $    */
 
 /*-
  * Copyright (c) 2008 The NetBSD Foundation, Inc.
@@ -181,7 +181,7 @@
  */
 
 #include <sys/cdefs.h>
-__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.123 2022/04/09 23:35:58 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: audio.c,v 1.124 2022/04/19 09:19:53 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "audio.h"
@@ -1344,6 +1344,7 @@
 {
        struct audio_softc *sc;
        struct audio_file *file;
+       int maj, mn;
        int error;
 
        sc = device_private(self);
@@ -1359,6 +1360,16 @@
                return error;
 
        /*
+        * Prevent new opens and wait for existing opens to complete.
+        */
+       maj = cdevsw_lookup_major(&audio_cdevsw);
+       mn = device_unit(self);
+       vdevgone(maj, mn|SOUND_DEVICE, mn|SOUND_DEVICE, VCHR);
+       vdevgone(maj, mn|AUDIO_DEVICE, mn|AUDIO_DEVICE, VCHR);
+       vdevgone(maj, mn|AUDIOCTL_DEVICE, mn|AUDIOCTL_DEVICE, VCHR);
+       vdevgone(maj, mn|MIXER_DEVICE, mn|MIXER_DEVICE, VCHR);
+
+       /*
         * This waits currently running sysctls to finish if exists.
         * After this, no more new sysctls will come.
         */



Home | Main Index | Thread Index | Old Index