Module Name: src Committed By: riastradh Date: Sun Jun 13 09:30:48 UTC 2021
Modified Files: src/sys/kern: subr_autoconf.c Log Message: autoconf(9): Take kernel lock in config_detach. config_detach is used in too many places to audit for now -- so although I'm quite sure it is racy (e.g., with cloning devices and drvctl: drvctl -d a newly opened fss0 before sc_state has transitioned from FSS_IDLE), this will mitigate the immediate fallout until we can properly fix autoconf's notions of device pointers. To generate a diff of this commit: cvs rdiff -u -r1.286 -r1.287 src/sys/kern/subr_autoconf.c Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/sys/kern/subr_autoconf.c diff -u src/sys/kern/subr_autoconf.c:1.286 src/sys/kern/subr_autoconf.c:1.287 --- src/sys/kern/subr_autoconf.c:1.286 Sun Jun 13 00:11:46 2021 +++ src/sys/kern/subr_autoconf.c Sun Jun 13 09:30:48 2021 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_autoconf.c,v 1.286 2021/06/13 00:11:46 riastradh Exp $ */ +/* $NetBSD: subr_autoconf.c,v 1.287 2021/06/13 09:30:48 riastradh Exp $ */ /* * Copyright (c) 1996, 2000 Christopher G. Demetriou @@ -79,7 +79,7 @@ #define __SUBR_AUTOCONF_PRIVATE /* see <sys/device.h> */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.286 2021/06/13 00:11:46 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.287 2021/06/13 09:30:48 riastradh Exp $"); #ifdef _KERNEL_OPT #include "opt_ddb.h" @@ -1969,7 +1969,7 @@ config_detach(device_t dev, int flags) device_t d __diagused; int rv = 0; - KASSERT(KERNEL_LOCKED_P()); + KERNEL_LOCK(1, NULL); cf = dev->dv_cfdata; KASSERTMSG((cf == NULL || cf->cf_fstate == FSTATE_FOUND || @@ -1988,8 +1988,10 @@ config_detach(device_t dev, int flags) * attached. */ rv = config_detach_enter(dev); - if (rv) + if (rv) { + KERNEL_UNLOCK_ONE(NULL); return rv; + } mutex_enter(&alldevs_lock); if (dev->dv_del_gen != 0) { @@ -1999,6 +2001,7 @@ config_detach(device_t dev, int flags) device_xname(dev)); #endif /* DIAGNOSTIC */ config_detach_exit(dev); + KERNEL_UNLOCK_ONE(NULL); return ENOENT; } alldevs_nwrite++; @@ -2095,6 +2098,8 @@ out: } config_alldevs_exit(&af); + KERNEL_UNLOCK_ONE(NULL); + return rv; }