Source-Changes-HG archive

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

[src/trunk]: src/sys/kern autoconf(9): Sprinkle KASSERT(dev->dv_pending == 0)...



details:   https://anonhg.NetBSD.org/src/rev/a83065c33112
branches:  trunk
changeset: 983874:a83065c33112
user:      riastradh <riastradh%NetBSD.org@localhost>
date:      Sun Jun 13 00:11:46 2021 +0000

description:
autoconf(9): Sprinkle KASSERT(dev->dv_pending == 0) in dealloc paths.

This would have made uhub's config_pending_incr leak more obvious by
crashing in KASSERT(dev->dv_pending == 0) early on, rather than
crashing in a tailq panic later on when the config_pending list gets
corrupted with use-after-free because nothing took the device off
dv_pending_list when attached.

(This is slightly academic now because config_detach blocks until
dev->dv_pending == 0, but it doesn't hurt and makes the intent
clearer.)

diffstat:

 sys/kern/subr_autoconf.c |  9 +++++++--
 1 files changed, 7 insertions(+), 2 deletions(-)

diffs (45 lines):

diff -r 70a298469635 -r a83065c33112 sys/kern/subr_autoconf.c
--- a/sys/kern/subr_autoconf.c  Sun Jun 13 00:11:17 2021 +0000
+++ b/sys/kern/subr_autoconf.c  Sun Jun 13 00:11:46 2021 +0000
@@ -1,4 +1,4 @@
-/* $NetBSD: subr_autoconf.c,v 1.285 2021/06/13 00:11:17 riastradh Exp $ */
+/* $NetBSD: subr_autoconf.c,v 1.286 2021/06/13 00:11:46 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.285 2021/06/13 00:11:17 riastradh Exp $");
+__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.286 2021/06/13 00:11:46 riastradh Exp $");
 
 #ifdef _KERNEL_OPT
 #include "opt_ddb.h"
@@ -1421,7 +1421,9 @@
 static void
 config_devfree(device_t dev)
 {
+
        KASSERT(dev->dv_flags & DVF_PRIV_ALLOC);
+       KASSERTMSG(dev->dv_pending == 0, "%d", dev->dv_pending);
 
        if (dev->dv_cfattach->ca_devsize > 0)
                kmem_free(dev->dv_private, dev->dv_cfattach->ca_devsize);
@@ -1439,6 +1441,7 @@
        int i;
 
        KASSERT(mutex_owned(&alldevs_lock));
+       KASSERTMSG(dev->dv_pending == 0, "%d", dev->dv_pending);
 
        /* Unlink from device list.  Link to garbage list. */
        TAILQ_REMOVE(&alldevs, dev, dv_list);
@@ -1469,6 +1472,8 @@
        struct device_garbage *dg = &dev->dv_garbage;
        device_lock_t dvl = device_getlock(dev);
 
+       KASSERTMSG(dev->dv_pending == 0, "%d", dev->dv_pending);
+
        if (dg->dg_devs != NULL)
                kmem_free(dg->dg_devs, sizeof(device_t) * dg->dg_ndevs);
 



Home | Main Index | Thread Index | Old Index