Module Name: src Committed By: martin Date: Tue Aug 1 14:53:54 UTC 2023
Modified Files: src/sys/kern [netbsd-10]: subr_autoconf.c Log Message: Pull up following revision(s) (requested by riastradh in ticket #285): sys/kern/subr_autoconf.c: revision 1.308 autoconf(9): Avoid potential ABA bug in config_makeroom. When we unlock alldevs_lock to allocate a new cd_devs array nsp, other threads may have: 1. freed the old one (osp), 2. done some other memory allocation, 3. allocated a new _larger_ array whose address happens to concide with osp (e.g., in (2) the page was recycled for a different pool cache), and 4. updated cd_devs back to osp but increased cd_ndevs. In that case, the memory may be corrupted: we try to copy the wrong number of device_t pointers into nsp and we free osp with the wrong (stale) length. Avoid this by checking whether cd_ndevs has changed too -- if not, osp might have been recycled but at least the lengths we're about to copy and free are still correct so there's no harm in an ABA situation. To generate a diff of this commit: cvs rdiff -u -r1.306.4.1 -r1.306.4.2 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.306.4.1 src/sys/kern/subr_autoconf.c:1.306.4.2 --- src/sys/kern/subr_autoconf.c:1.306.4.1 Sun Jul 30 12:04:22 2023 +++ src/sys/kern/subr_autoconf.c Tue Aug 1 14:53:54 2023 @@ -1,4 +1,4 @@ -/* $NetBSD: subr_autoconf.c,v 1.306.4.1 2023/07/30 12:04:22 martin Exp $ */ +/* $NetBSD: subr_autoconf.c,v 1.306.4.2 2023/08/01 14:53:54 martin Exp $ */ /* * Copyright (c) 1996, 2000 Christopher G. Demetriou @@ -77,7 +77,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.306.4.1 2023/07/30 12:04:22 martin Exp $"); +__KERNEL_RCSID(0, "$NetBSD: subr_autoconf.c,v 1.306.4.2 2023/08/01 14:53:54 martin Exp $"); #ifdef _KERNEL_OPT #include "opt_ddb.h" @@ -1347,7 +1347,7 @@ config_makeroom(int n, struct cfdriver * * If another thread moved the array while we did * not hold alldevs_lock, try again. */ - if (cd->cd_devs != osp) { + if (cd->cd_devs != osp || cd->cd_ndevs != ondevs) { mutex_exit(&alldevs_lock); kmem_free(nsp, sizeof(device_t) * nndevs); mutex_enter(&alldevs_lock);