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;
}