Module Name: src Committed By: martin Date: Thu Apr 18 18:22:10 UTC 2024
Modified Files: src/sys/kern [netbsd-10]: init_main.c kern_hook.c vfs_mount.c src/sys/miscfs/procfs [netbsd-10]: procfs.h procfs_subr.c procfs_vfsops.c procfs_vnops.c Log Message: Pull up following revision(s) (requested by hannken in ticket #668): sys/miscfs/procfs/procfs.h: revision 1.83 sys/miscfs/procfs/procfs.h: revision 1.84 sys/kern/vfs_mount.c: revision 1.104 sys/miscfs/procfs/procfs_vnops.c: revision 1.230 sys/kern/init_main.c: revision 1.547 sys/kern/kern_hook.c: revision 1.15 sys/miscfs/procfs/procfs_vfsops.c: revision 1.112 sys/miscfs/procfs/procfs_vfsops.c: revision 1.113 sys/miscfs/procfs/procfs_vfsops.c: revision 1.114 sys/miscfs/procfs/procfs_subr.c: revision 1.117 Print dangling vnode before panic() to help debug. PR kern/57775 ""panic: unmount: dangling vnode" while umounting procfs" Protect kernel hooks exechook, exithook and forkhook with rwlock. Lock as writer on establish/disestablish and as reader on list traverse. For exechook ride "exec_lock" as it is already take as reader when traversing the list. Add local locks for exithook and forkhook. Move exec_init before signal_init as signal_init calls exechook_establish() that needs "exec_lock". PR kern/39913 "exec, fork, exit hooks need locking" Add a hashmap to access all procfs nodes by pid. Using the exechook to revoke procfs nodes is racy and may deadlock: one thread runs doexechooks() -> procfs_revoke_vnodes() and wants to suspend the file system for vgone(), while another thread runs a forced unmount, has the file system suspended, tries to disestablish the exechook and waits for doexechooks() to complete. Establish/disestablish the exechook on module load/unload instead mount/unmount and use the hashmap to access all procfs nodes for this pid. May fix PR kern/57775 ""panic: unmount: dangling vnode" while umounting procfs" Remove all procfs nodes for this process on process exit. To generate a diff of this commit: cvs rdiff -u -r1.541 -r1.541.2.1 src/sys/kern/init_main.c cvs rdiff -u -r1.14 -r1.14.2.1 src/sys/kern/kern_hook.c cvs rdiff -u -r1.101 -r1.101.2.1 src/sys/kern/vfs_mount.c cvs rdiff -u -r1.82 -r1.82.4.1 src/sys/miscfs/procfs/procfs.h cvs rdiff -u -r1.116 -r1.116.20.1 src/sys/miscfs/procfs/procfs_subr.c cvs rdiff -u -r1.111 -r1.111.4.1 src/sys/miscfs/procfs/procfs_vfsops.c cvs rdiff -u -r1.229 -r1.229.4.1 src/sys/miscfs/procfs/procfs_vnops.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/init_main.c diff -u src/sys/kern/init_main.c:1.541 src/sys/kern/init_main.c:1.541.2.1 --- src/sys/kern/init_main.c:1.541 Wed Oct 26 23:20:47 2022 +++ src/sys/kern/init_main.c Thu Apr 18 18:22:10 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: init_main.c,v 1.541 2022/10/26 23:20:47 riastradh Exp $ */ +/* $NetBSD: init_main.c,v 1.541.2.1 2024/04/18 18:22:10 martin Exp $ */ /*- * Copyright (c) 2008, 2009, 2019 The NetBSD Foundation, Inc. @@ -97,7 +97,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.541 2022/10/26 23:20:47 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.541.2.1 2024/04/18 18:22:10 martin Exp $"); #include "opt_cnmagic.h" #include "opt_ddb.h" @@ -409,6 +409,9 @@ main(void) /* Must be called after lwpinit (lwpinit_specificdata) */ psref_init(); + /* Initialize exec structures */ + exec_init(1); /* signal_init calls exechook_establish() */ + /* Initialize signal-related data structures. */ signal_init(); @@ -578,9 +581,6 @@ main(void) vmem_rehash_start(); /* must be before exec_init */ - /* Initialize exec structures */ - exec_init(1); /* seminit calls exithook_establish() */ - #if NVERIEXEC > 0 /* * Initialise the Veriexec subsystem. Index: src/sys/kern/kern_hook.c diff -u src/sys/kern/kern_hook.c:1.14 src/sys/kern/kern_hook.c:1.14.2.1 --- src/sys/kern/kern_hook.c:1.14 Wed Oct 26 23:21:06 2022 +++ src/sys/kern/kern_hook.c Thu Apr 18 18:22:10 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: kern_hook.c,v 1.14 2022/10/26 23:21:06 riastradh Exp $ */ +/* $NetBSD: kern_hook.c,v 1.14.2.1 2024/04/18 18:22:10 martin Exp $ */ /*- * Copyright (c) 1997, 1998, 1999, 2002, 2007, 2008 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: kern_hook.c,v 1.14 2022/10/26 23:21:06 riastradh Exp $"); +__KERNEL_RCSID(0, "$NetBSD: kern_hook.c,v 1.14.2.1 2024/04/18 18:22:10 martin Exp $"); #include <sys/param.h> @@ -42,6 +42,7 @@ __KERNEL_RCSID(0, "$NetBSD: kern_hook.c, #include <sys/hook.h> #include <sys/kmem.h> #include <sys/malloc.h> +#include <sys/once.h> #include <sys/rwlock.h> #include <sys/systm.h> @@ -74,25 +75,48 @@ struct khook_list { int powerhook_debug = 0; +static ONCE_DECL(hook_control); +static krwlock_t exithook_lock; +static krwlock_t forkhook_lock; + +static int +hook_init(void) +{ + + rw_init(&exithook_lock); + rw_init(&forkhook_lock); + + return 0; +} + static void * -hook_establish(hook_list_t *list, void (*fn)(void *), void *arg) +hook_establish(hook_list_t *list, krwlock_t *lock, + void (*fn)(void *), void *arg) { struct hook_desc *hd; - hd = malloc(sizeof(*hd), M_DEVBUF, M_NOWAIT); - if (hd == NULL) - return (NULL); + RUN_ONCE(&hook_control, hook_init); - hd->hk_fn = fn; - hd->hk_arg = arg; - LIST_INSERT_HEAD(list, hd, hk_list); + hd = malloc(sizeof(*hd), M_DEVBUF, M_NOWAIT); + if (hd != NULL) { + if (lock) + rw_enter(lock, RW_WRITER); + hd->hk_fn = fn; + hd->hk_arg = arg; + LIST_INSERT_HEAD(list, hd, hk_list); + if (lock) + rw_exit(lock); + } return (hd); } static void -hook_disestablish(hook_list_t *list, void *vhook) +hook_disestablish(hook_list_t *list, krwlock_t *lock, void *vhook) { + + if (lock) + rw_enter(lock, RW_WRITER); #ifdef DIAGNOSTIC struct hook_desc *hd; @@ -106,6 +130,8 @@ hook_disestablish(hook_list_t *list, voi #endif LIST_REMOVE((struct hook_desc *)vhook, hk_list); free(vhook, M_DEVBUF); + if (lock) + rw_exit(lock); } static void @@ -120,14 +146,20 @@ hook_destroy(hook_list_t *list) } static void -hook_proc_run(hook_list_t *list, struct proc *p) +hook_proc_run(hook_list_t *list, krwlock_t *lock, struct proc *p) { struct hook_desc *hd; + RUN_ONCE(&hook_control, hook_init); + + if (lock) + rw_enter(lock, RW_READER); LIST_FOREACH(hd, list, hk_list) { __FPTRCAST(void (*)(struct proc *, void *), *hd->hk_fn)(p, hd->hk_arg); } + if (lock) + rw_exit(lock); } /* @@ -146,13 +178,13 @@ static hook_list_t shutdownhook_list = L void * shutdownhook_establish(void (*fn)(void *), void *arg) { - return hook_establish(&shutdownhook_list, fn, arg); + return hook_establish(&shutdownhook_list, NULL, fn, arg); } void shutdownhook_disestablish(void *vhook) { - hook_disestablish(&shutdownhook_list, vhook); + hook_disestablish(&shutdownhook_list, NULL, vhook); } /* @@ -193,14 +225,14 @@ static hook_list_t mountroothook_list=LI void * mountroothook_establish(void (*fn)(device_t), device_t dev) { - return hook_establish(&mountroothook_list, __FPTRCAST(void (*), fn), - dev); + return hook_establish(&mountroothook_list, NULL, + __FPTRCAST(void (*), fn), dev); } void mountroothook_disestablish(void *vhook) { - hook_disestablish(&mountroothook_list, vhook); + hook_disestablish(&mountroothook_list, NULL, vhook); } void @@ -227,14 +259,14 @@ static hook_list_t exechook_list = LIST_ void * exechook_establish(void (*fn)(struct proc *, void *), void *arg) { - return hook_establish(&exechook_list, __FPTRCAST(void (*)(void *), fn), - arg); + return hook_establish(&exechook_list, &exec_lock, + __FPTRCAST(void (*)(void *), fn), arg); } void exechook_disestablish(void *vhook) { - hook_disestablish(&exechook_list, vhook); + hook_disestablish(&exechook_list, &exec_lock, vhook); } /* @@ -243,7 +275,9 @@ exechook_disestablish(void *vhook) void doexechooks(struct proc *p) { - hook_proc_run(&exechook_list, p); + KASSERT(rw_lock_held(&exec_lock)); + + hook_proc_run(&exechook_list, NULL, p); } static hook_list_t exithook_list = LIST_HEAD_INITIALIZER(exithook_list); @@ -251,22 +285,16 @@ static hook_list_t exithook_list = LIST_ void * exithook_establish(void (*fn)(struct proc *, void *), void *arg) { - void *rv; - rw_enter(&exec_lock, RW_WRITER); - rv = hook_establish(&exithook_list, __FPTRCAST(void (*)(void *), fn), - arg); - rw_exit(&exec_lock); - return rv; + return hook_establish(&exithook_list, &exithook_lock, + __FPTRCAST(void (*)(void *), fn), arg); } void exithook_disestablish(void *vhook) { - rw_enter(&exec_lock, RW_WRITER); - hook_disestablish(&exithook_list, vhook); - rw_exit(&exec_lock); + hook_disestablish(&exithook_list, &exithook_lock, vhook); } /* @@ -275,7 +303,7 @@ exithook_disestablish(void *vhook) void doexithooks(struct proc *p) { - hook_proc_run(&exithook_list, p); + hook_proc_run(&exithook_list, &exithook_lock, p); } static hook_list_t forkhook_list = LIST_HEAD_INITIALIZER(forkhook_list); @@ -283,14 +311,14 @@ static hook_list_t forkhook_list = LIST_ void * forkhook_establish(void (*fn)(struct proc *, struct proc *)) { - return hook_establish(&forkhook_list, __FPTRCAST(void (*)(void *), fn), - NULL); + return hook_establish(&forkhook_list, &forkhook_lock, + __FPTRCAST(void (*)(void *), fn), NULL); } void forkhook_disestablish(void *vhook) { - hook_disestablish(&forkhook_list, vhook); + hook_disestablish(&forkhook_list, &forkhook_lock, vhook); } /* @@ -301,10 +329,14 @@ doforkhooks(struct proc *p2, struct proc { struct hook_desc *hd; + RUN_ONCE(&hook_control, hook_init); + + rw_enter(&forkhook_lock, RW_READER); LIST_FOREACH(hd, &forkhook_list, hk_list) { __FPTRCAST(void (*)(struct proc *, struct proc *), *hd->hk_fn) (p2, p1); } + rw_exit(&forkhook_lock); } static hook_list_t critpollhook_list = LIST_HEAD_INITIALIZER(critpollhook_list); @@ -312,13 +344,13 @@ static hook_list_t critpollhook_list = L void * critpollhook_establish(void (*fn)(void *), void *arg) { - return hook_establish(&critpollhook_list, fn, arg); + return hook_establish(&critpollhook_list, NULL, fn, arg); } void critpollhook_disestablish(void *vhook) { - hook_disestablish(&critpollhook_list, vhook); + hook_disestablish(&critpollhook_list, NULL, vhook); } /* Index: src/sys/kern/vfs_mount.c diff -u src/sys/kern/vfs_mount.c:1.101 src/sys/kern/vfs_mount.c:1.101.2.1 --- src/sys/kern/vfs_mount.c:1.101 Fri Dec 9 10:33:18 2022 +++ src/sys/kern/vfs_mount.c Thu Apr 18 18:22:10 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: vfs_mount.c,v 1.101 2022/12/09 10:33:18 hannken Exp $ */ +/* $NetBSD: vfs_mount.c,v 1.101.2.1 2024/04/18 18:22:10 martin Exp $ */ /*- * Copyright (c) 1997-2020 The NetBSD Foundation, Inc. @@ -67,7 +67,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.101 2022/12/09 10:33:18 hannken Exp $"); +__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.101.2.1 2024/04/18 18:22:10 martin Exp $"); #include <sys/param.h> #include <sys/kernel.h> @@ -937,7 +937,7 @@ err_mounted: int dounmount(struct mount *mp, int flags, struct lwp *l) { - vnode_t *coveredvp; + vnode_t *coveredvp, *vp; int error, async, used_syncer, used_extattr; const bool was_suspended = fstrans_is_owner(mp); @@ -1004,8 +1004,10 @@ dounmount(struct mount *mp, int flags, s vfs_resume(mp); mountlist_remove(mp); - if (TAILQ_FIRST(&mp->mnt_vnodelist) != NULL) + if ((vp = VIMPL_TO_VNODE(TAILQ_FIRST(&mp->mnt_vnodelist))) != NULL) { + vprint("dangling", vp); panic("unmount: dangling vnode"); + } vfs_hooks_unmount(mp); vfs_set_lowermount(mp, NULL); Index: src/sys/miscfs/procfs/procfs.h diff -u src/sys/miscfs/procfs/procfs.h:1.82 src/sys/miscfs/procfs/procfs.h:1.82.4.1 --- src/sys/miscfs/procfs/procfs.h:1.82 Wed Jan 19 10:23:00 2022 +++ src/sys/miscfs/procfs/procfs.h Thu Apr 18 18:22:10 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: procfs.h,v 1.82 2022/01/19 10:23:00 martin Exp $ */ +/* $NetBSD: procfs.h,v 1.82.4.1 2024/04/18 18:22:10 martin Exp $ */ /* * Copyright (c) 1993 @@ -129,7 +129,9 @@ struct pfskey { int pk_fd; /* associated fd if not -1 */ }; struct pfsnode { + LIST_ENTRY(pfsnode) pfs_hash; /* per pid hash list */ struct vnode *pfs_vnode; /* vnode associated with this pfsnode */ + struct mount *pfs_mount; /* mount associated with this pfsnode */ struct pfskey pfs_key; #define pfs_type pfs_key.pk_type #define pfs_pid pfs_key.pk_pid @@ -190,7 +192,6 @@ procfs_fileno(pid_t _pid, pfstype _type, #define PROCFS_TYPE(type) ((type) % PFSlast) struct procfsmount { - void *pmnt_exechook; int pmnt_flags; }; @@ -269,7 +270,7 @@ int procfs_doauxv(struct lwp *, struct p int procfs_dolimit(struct lwp *, struct proc *, struct pfsnode *, struct uio *); -void procfs_revoke_vnodes(struct proc *, void *); +void procfs_hashrem(struct pfsnode *); int procfs_getfp(struct pfsnode *, struct proc *, struct file **); /* functions to check whether or not files should be displayed */ Index: src/sys/miscfs/procfs/procfs_subr.c diff -u src/sys/miscfs/procfs/procfs_subr.c:1.116 src/sys/miscfs/procfs/procfs_subr.c:1.116.20.1 --- src/sys/miscfs/procfs/procfs_subr.c:1.116 Sat May 23 23:42:43 2020 +++ src/sys/miscfs/procfs/procfs_subr.c Thu Apr 18 18:22:10 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: procfs_subr.c,v 1.116 2020/05/23 23:42:43 ad Exp $ */ +/* $NetBSD: procfs_subr.c,v 1.116.20.1 2024/04/18 18:22:10 martin Exp $ */ /*- * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. @@ -102,7 +102,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: procfs_subr.c,v 1.116 2020/05/23 23:42:43 ad Exp $"); +__KERNEL_RCSID(0, "$NetBSD: procfs_subr.c,v 1.116.20.1 2024/04/18 18:22:10 martin Exp $"); #include <sys/param.h> #include <sys/systm.h> @@ -358,57 +358,6 @@ vfs_findname(const vfs_namemap_t *nm, co return (0); } -static bool -procfs_revoke_selector(void *arg, struct vnode *vp) -{ - struct proc *p = arg; - struct pfsnode *pfs; - - KASSERT(mutex_owned(vp->v_interlock)); - - pfs = VTOPFS(vp); - - return (pfs != NULL && pfs->pfs_pid == p->p_pid); -} - -void -procfs_revoke_vnodes(struct proc *p, void *arg) -{ - int error; - bool suspended; - struct vnode *vp; - struct vnode_iterator *marker; - struct mount *mp = (struct mount *)arg; - - if (!(p->p_flag & PK_SUGID)) - return; - - suspended = false; - vfs_vnode_iterator_init(mp, &marker); - - while ((vp = vfs_vnode_iterator_next(marker, - procfs_revoke_selector, p)) != NULL) { - if (vrecycle(vp)) - continue; - /* Vnode is busy, we have to suspend the mount for vgone(). */ - while (! suspended) { - error = vfs_suspend(mp, 0); - if (error == 0) { - suspended = true; - } else if (error != EINTR && error != ERESTART) { - KASSERT(error == EOPNOTSUPP); - break; - } - } - vgone(vp); - } - - if (suspended) - vfs_resume(mp); - - vfs_vnode_iterator_destroy(marker); -} - bool procfs_use_linux_compat(struct mount *mp) { Index: src/sys/miscfs/procfs/procfs_vfsops.c diff -u src/sys/miscfs/procfs/procfs_vfsops.c:1.111 src/sys/miscfs/procfs/procfs_vfsops.c:1.111.4.1 --- src/sys/miscfs/procfs/procfs_vfsops.c:1.111 Mon Jan 17 11:20:00 2022 +++ src/sys/miscfs/procfs/procfs_vfsops.c Thu Apr 18 18:22:10 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: procfs_vfsops.c,v 1.111 2022/01/17 11:20:00 bouyer Exp $ */ +/* $NetBSD: procfs_vfsops.c,v 1.111.4.1 2024/04/18 18:22:10 martin Exp $ */ /* * Copyright (c) 1993 @@ -76,7 +76,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.111 2022/01/17 11:20:00 bouyer Exp $"); +__KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.111.4.1 2024/04/18 18:22:10 martin Exp $"); #if defined(_KERNEL_OPT) #include "opt_compat_netbsd.h" @@ -88,6 +88,7 @@ __KERNEL_RCSID(0, "$NetBSD: procfs_vfsop #include <sys/dirent.h> #include <sys/file.h> #include <sys/filedesc.h> +#include <sys/fstrans.h> #include <sys/kauth.h> #include <sys/kernel.h> #include <sys/module.h> @@ -110,7 +111,33 @@ MODULE(MODULE_CLASS_VFS, procfs, "ptrace VFS_PROTOS(procfs); +#define PROCFS_HASHSIZE 256 +#define PROCFS_EXEC_HOOK ((void *)1) +#define PROCFS_EXIT_HOOK ((void *)2) + static kauth_listener_t procfs_listener; +static void *procfs_exechook; +static void *procfs_exithook; +LIST_HEAD(hashhead, pfsnode); +static u_long procfs_hashmask; +static struct hashhead *procfs_hashtab; +static kmutex_t procfs_hashlock; + +static struct hashhead * +procfs_hashhead(pid_t pid) +{ + + return &procfs_hashtab[pid & procfs_hashmask]; +} + +void +procfs_hashrem(struct pfsnode *pfs) +{ + + mutex_enter(&procfs_hashlock); + LIST_REMOVE(pfs, pfs_hash); + mutex_exit(&procfs_hashlock); +} /* * VFS Operations. @@ -166,7 +193,6 @@ procfs_mount( error = set_statvfs_info(path, UIO_USERSPACE, "procfs", UIO_SYSSPACE, mp->mnt_op->vfs_name, mp, l); - pmnt->pmnt_exechook = exechook_establish(procfs_revoke_vnodes, mp); if (*data_len >= sizeof *args) pmnt->pmnt_flags = args->flags; else @@ -191,8 +217,6 @@ procfs_unmount(struct mount *mp, int mnt if ((error = vflush(mp, 0, flags)) != 0) return (error); - exechook_disestablish(VFSTOPROC(mp)->pmnt_exechook); - kmem_free(mp->mnt_data, sizeof(struct procfsmount)); mp->mnt_data = NULL; @@ -279,6 +303,7 @@ procfs_loadvnode(struct mount *mp, struc pfs->pfs_type = pfskey.pk_type; pfs->pfs_fd = pfskey.pk_fd; pfs->pfs_vnode = vp; + pfs->pfs_mount = mp; pfs->pfs_flags = 0; pfs->pfs_fileno = PROCFS_FILENO(pfs->pfs_pid, pfs->pfs_type, pfs->pfs_fd); @@ -421,6 +446,10 @@ procfs_loadvnode(struct mount *mp, struc panic("procfs_allocvp"); } + mutex_enter(&procfs_hashlock); + LIST_INSERT_HEAD(procfs_hashhead(pfs->pfs_pid), pfs, pfs_hash); + mutex_exit(&procfs_hashlock); + uvm_vnp_setsize(vp, 0); *new_key = &pfs->pfs_key; @@ -486,6 +515,48 @@ struct vfsops procfs_vfsops = { .vfs_opv_descs = procfs_vnodeopv_descs }; +static void +procfs_exechook_cb(struct proc *p, void *arg) +{ + struct hashhead *head; + struct pfsnode *pfs; + struct mount *mp; + struct pfskey key; + struct vnode *vp; + int error; + + if (arg == PROCFS_EXEC_HOOK && !(p->p_flag & PK_SUGID)) + return; + + head = procfs_hashhead(p->p_pid); + +again: + mutex_enter(&procfs_hashlock); + LIST_FOREACH(pfs, head, pfs_hash) { + if (pfs->pfs_pid != p->p_pid) + continue; + mp = pfs->pfs_mount; + key = pfs->pfs_key; + vfs_ref(mp); + mutex_exit(&procfs_hashlock); + + error = vcache_get(mp, &key, sizeof(key), &vp); + vfs_rele(mp); + if (error != 0) + goto again; + if (vrecycle(vp)) + goto again; + do { + error = vfs_suspend(mp, 0); + } while (error == EINTR || error == ERESTART); + vgone(vp); + if (error == 0) + vfs_resume(mp); + goto again; + } + mutex_exit(&procfs_hashlock); +} + static int procfs_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) @@ -548,12 +619,25 @@ procfs_modcmd(modcmd_t cmd, void *arg) procfs_listener = kauth_listen_scope(KAUTH_SCOPE_PROCESS, procfs_listener_cb, NULL); + procfs_exechook = exechook_establish(procfs_exechook_cb, + PROCFS_EXEC_HOOK); + procfs_exithook = exithook_establish(procfs_exechook_cb, + PROCFS_EXIT_HOOK); + + mutex_init(&procfs_hashlock, MUTEX_DEFAULT, IPL_NONE); + procfs_hashtab = hashinit(PROCFS_HASHSIZE, HASH_LIST, true, + &procfs_hashmask); + break; case MODULE_CMD_FINI: error = vfs_detach(&procfs_vfsops); if (error != 0) break; kauth_unlisten_scope(procfs_listener); + exechook_disestablish(procfs_exechook); + exithook_disestablish(procfs_exithook); + mutex_destroy(&procfs_hashlock); + hashdone(procfs_hashtab, HASH_LIST, procfs_hashmask); break; default: error = ENOTTY; Index: src/sys/miscfs/procfs/procfs_vnops.c diff -u src/sys/miscfs/procfs/procfs_vnops.c:1.229 src/sys/miscfs/procfs/procfs_vnops.c:1.229.4.1 --- src/sys/miscfs/procfs/procfs_vnops.c:1.229 Fri Jun 17 14:30:37 2022 +++ src/sys/miscfs/procfs/procfs_vnops.c Thu Apr 18 18:22:10 2024 @@ -1,4 +1,4 @@ -/* $NetBSD: procfs_vnops.c,v 1.229 2022/06/17 14:30:37 shm Exp $ */ +/* $NetBSD: procfs_vnops.c,v 1.229.4.1 2024/04/18 18:22:10 martin Exp $ */ /*- * Copyright (c) 2006, 2007, 2008, 2020 The NetBSD Foundation, Inc. @@ -105,7 +105,7 @@ */ #include <sys/cdefs.h> -__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.229 2022/06/17 14:30:37 shm Exp $"); +__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.229.4.1 2024/04/18 18:22:10 martin Exp $"); #include <sys/param.h> #include <sys/atomic.h> @@ -437,6 +437,7 @@ procfs_reclaim(void *v) mutex_enter(vp->v_interlock); vp->v_data = NULL; mutex_exit(vp->v_interlock); + procfs_hashrem(pfs); kmem_free(pfs, sizeof(*pfs)); return 0; }