NetBSD-Bugs archive

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

kern/51785: Accessing speaker device does not prevent its removal

>Number:         51785
>Category:       kern
>Synopsis:       Accessing speaker device does not prevent its removal
>Confidential:   no
>Severity:       serious
>Priority:       medium
>Responsible:    kern-bug-people
>State:          open
>Class:          sw-bug
>Submitter-Id:   net
>Arrival-Date:   Fri Jan 06 03:25:00 +0000 2017
>Originator:     Paul Goyette
>Release:        NetBSD 7.99.53
| Paul Goyette     | PGP Key fingerprint:     | E-mail addresses:      |
| (Retired)        | FA29 0E3B 35AF E8AE 6651 | paul at   |
| Kernel Developer | 0786 F758 55DE 53BA 7731 | pgoyette at |
System: NetBSD 7.99.53 NetBSD 7.99.53 (SPEEDY 2016-12-31 23:00:24) #1: Sun Jan 1 01:39:34 UTC 2017 amd64
Architecture: x86_64
Machine: amd64
I started to write a MODULE_CMD_FINI routine for the spkr module.  It
seems that if the spkr device is busy playing something, it is still
possible to call config_fini_component() for the driver with a success
return code.  As a result, the driver assumes that it is safe to be

After the current play-string finishes, I/O completion code returns to
memory that no longer contains the driver, resulting in a panic.
1. Build a kernel that does NOT have the spkr driver built-in, and
   with the following patch (with appropriate substitution of tab
   characters for white-space):

diff -u -p -r1.5 spkr.c
--- spkr.c      15 Dec 2016 06:55:55 -0000      1.5
+++ spkr.c      6 Jan 2017 03:11:05 -0000
@@ -493,20 +493,21 @@ spkr_modcmd(modcmd_t cmd, void *arg)
                error = config_init_component(cfdriver_ioconf_spkr,
-                       cfattach_ioconf_spkr, cfdata_ioconf_spkr);
+                   cfattach_ioconf_spkr, cfdata_ioconf_spkr);
                if (error) {
                        devsw_detach(NULL, &spkr_cdevsw);
        case MODULE_CMD_FINI:
-               return EBUSY;
-#ifdef notyet
-               error = config_fini_component(cfdriver_ioconf_spkr,
-                       cfattach_ioconf_spkr, cfdata_ioconf_spkr);
                devsw_detach(NULL, &spkr_cdevsw);
+               error = config_fini_component(cfdriver_ioconf_spkr,
+                   cfattach_ioconf_spkr, cfdata_ioconf_spkr);
+               if (error)
+                       devsw_attach(spkr_cd.cd_name, NULL, &bmajor,
+                           &spkr_cdevsw, &cmajor);
                error = ENOTTY;

2. play a string to the /dev/speaker in the background:

	echo T60L1CP1CP1C > /dev/speaker &

3. while it is still playing, modunload spkr
Some sort of interlock would normally be held while the device is open
(the "echo" command above does not complete until the playstring is
finished).  This interlock would result in a failure to detach the
driver's data structures;  ie, you would get a failure from one or more
of config_{cfdata,cfattach,cfdriver}_detach().  This would cause the
call to config_fini_component() to fail, preventing the module from
being unloaded.


Home | Main Index | Thread Index | Old Index