Thu Apr 18 18:22:10 2024 UTC (21d)
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.


(martin)
diff -r1.541 -r1.541.2.1 src/sys/kern/init_main.c
diff -r1.14 -r1.14.2.1 src/sys/kern/kern_hook.c
diff -r1.101 -r1.101.2.1 src/sys/kern/vfs_mount.c
diff -r1.82 -r1.82.4.1 src/sys/miscfs/procfs/procfs.h
diff -r1.116 -r1.116.20.1 src/sys/miscfs/procfs/procfs_subr.c
diff -r1.111 -r1.111.4.1 src/sys/miscfs/procfs/procfs_vfsops.c
diff -r1.229 -r1.229.4.1 src/sys/miscfs/procfs/procfs_vnops.c

cvs diff -r1.541 -r1.541.2.1 src/sys/kern/init_main.c (expand / switch to unified diff)

--- src/sys/kern/init_main.c 2022/10/26 23:20:47 1.541
+++ src/sys/kern/init_main.c 2024/04/18 18:22:10 1.541.2.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: init_main.c,v 1.541 2022/10/26 23:20:47 riastradh Exp $ */ 1/* $NetBSD: init_main.c,v 1.541.2.1 2024/04/18 18:22:10 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2008, 2009, 2019 The NetBSD Foundation, Inc. 4 * Copyright (c) 2008, 2009, 2019 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * Redistribution and use in source and binary forms, with or without 7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions 8 * modification, are permitted provided that the following conditions
9 * are met: 9 * are met:
10 * 1. Redistributions of source code must retain the above copyright 10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer. 11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright 12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the 13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution. 14 * documentation and/or other materials provided with the distribution.
@@ -87,27 +87,27 @@ @@ -87,27 +87,27 @@
87 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 87 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
88 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 88 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
89 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 89 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
90 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 90 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
91 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 91 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
92 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 92 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
93 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 93 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
94 * SUCH DAMAGE. 94 * SUCH DAMAGE.
95 * 95 *
96 * @(#)init_main.c 8.16 (Berkeley) 5/14/95 96 * @(#)init_main.c 8.16 (Berkeley) 5/14/95
97 */ 97 */
98 98
99#include <sys/cdefs.h> 99#include <sys/cdefs.h>
100__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.541 2022/10/26 23:20:47 riastradh Exp $"); 100__KERNEL_RCSID(0, "$NetBSD: init_main.c,v 1.541.2.1 2024/04/18 18:22:10 martin Exp $");
101 101
102#include "opt_cnmagic.h" 102#include "opt_cnmagic.h"
103#include "opt_ddb.h" 103#include "opt_ddb.h"
104#include "opt_inet.h" 104#include "opt_inet.h"
105#include "opt_ipsec.h" 105#include "opt_ipsec.h"
106#include "opt_modular.h" 106#include "opt_modular.h"
107#include "opt_ntp.h" 107#include "opt_ntp.h"
108#include "opt_pipe.h" 108#include "opt_pipe.h"
109#include "opt_syscall_debug.h" 109#include "opt_syscall_debug.h"
110#include "opt_sysv.h" 110#include "opt_sysv.h"
111#include "opt_fileassoc.h" 111#include "opt_fileassoc.h"
112#include "opt_ktrace.h" 112#include "opt_ktrace.h"
113#include "opt_pax.h" 113#include "opt_pax.h"
@@ -399,26 +399,29 @@ main(void) @@ -399,26 +399,29 @@ main(void)
399 * The following things must be done before autoconfiguration. 399 * The following things must be done before autoconfiguration.
400 */ 400 */
401 rnd_init(); /* initialize entropy pool */ 401 rnd_init(); /* initialize entropy pool */
402 402
403 cprng_init(); /* initialize cryptographic PRNG */ 403 cprng_init(); /* initialize cryptographic PRNG */
404 404
405 /* Initialize process and pgrp structures. */ 405 /* Initialize process and pgrp structures. */
406 procinit(); 406 procinit();
407 lwpinit(); 407 lwpinit();
408 408
409 /* Must be called after lwpinit (lwpinit_specificdata) */ 409 /* Must be called after lwpinit (lwpinit_specificdata) */
410 psref_init(); 410 psref_init();
411 411
 412 /* Initialize exec structures */
 413 exec_init(1); /* signal_init calls exechook_establish() */
 414
412 /* Initialize signal-related data structures. */ 415 /* Initialize signal-related data structures. */
413 signal_init(); 416 signal_init();
414 417
415 /* Initialize resource management. */ 418 /* Initialize resource management. */
416 resource_init(); 419 resource_init();
417 420
418 /* Create process 0. */ 421 /* Create process 0. */
419 proc0_init(); 422 proc0_init();
420 lwp0_init(); 423 lwp0_init();
421 424
422 /* Disable preemption during boot. */ 425 /* Disable preemption during boot. */
423 kpreempt_disable(); 426 kpreempt_disable();
424 427
@@ -568,29 +571,26 @@ main(void) @@ -568,29 +571,26 @@ main(void)
568 /* Initialize the rest of ipi(9) after CPUs have been detected. */ 571 /* Initialize the rest of ipi(9) after CPUs have been detected. */
569 ipi_percpu_init(); 572 ipi_percpu_init();
570 573
571 futex_sys_init(); 574 futex_sys_init();
572 575
573 /* Now timer is working. Enable preemption. */ 576 /* Now timer is working. Enable preemption. */
574 kpreempt_enable(); 577 kpreempt_enable();
575 578
576 /* Get the threads going and into any sleeps before continuing. */ 579 /* Get the threads going and into any sleeps before continuing. */
577 yield(); 580 yield();
578 581
579 vmem_rehash_start(); /* must be before exec_init */ 582 vmem_rehash_start(); /* must be before exec_init */
580 583
581 /* Initialize exec structures */ 
582 exec_init(1); /* seminit calls exithook_establish() */ 
583 
584#if NVERIEXEC > 0 584#if NVERIEXEC > 0
585 /* 585 /*
586 * Initialise the Veriexec subsystem. 586 * Initialise the Veriexec subsystem.
587 */ 587 */
588 veriexec_init(); 588 veriexec_init();
589#endif /* NVERIEXEC > 0 */ 589#endif /* NVERIEXEC > 0 */
590 590
591 pax_init(); 591 pax_init();
592 592
593#ifdef IPSEC 593#ifdef IPSEC
594 /* Attach network crypto subsystem */ 594 /* Attach network crypto subsystem */
595 ipsec_attach(); 595 ipsec_attach();
596#endif 596#endif

cvs diff -r1.14 -r1.14.2.1 src/sys/kern/kern_hook.c (expand / switch to unified diff)

--- src/sys/kern/kern_hook.c 2022/10/26 23:21:06 1.14
+++ src/sys/kern/kern_hook.c 2024/04/18 18:22:10 1.14.2.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: kern_hook.c,v 1.14 2022/10/26 23:21:06 riastradh Exp $ */ 1/* $NetBSD: kern_hook.c,v 1.14.2.1 2024/04/18 18:22:10 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1997, 1998, 1999, 2002, 2007, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 1997, 1998, 1999, 2002, 2007, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center, and by Luke Mewburn. 9 * NASA Ames Research Center, and by Luke Mewburn.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -21,37 +21,38 @@ @@ -21,37 +21,38 @@
21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 21 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 23 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 24 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 25 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 26 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 27 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 28 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 29 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30 * POSSIBILITY OF SUCH DAMAGE. 30 * POSSIBILITY OF SUCH DAMAGE.
31 */ 31 */
32 32
33#include <sys/cdefs.h> 33#include <sys/cdefs.h>
34__KERNEL_RCSID(0, "$NetBSD: kern_hook.c,v 1.14 2022/10/26 23:21:06 riastradh Exp $"); 34__KERNEL_RCSID(0, "$NetBSD: kern_hook.c,v 1.14.2.1 2024/04/18 18:22:10 martin Exp $");
35 35
36#include <sys/param.h> 36#include <sys/param.h>
37 37
38#include <sys/condvar.h> 38#include <sys/condvar.h>
39#include <sys/cpu.h> 39#include <sys/cpu.h>
40#include <sys/device.h> 40#include <sys/device.h>
41#include <sys/exec.h> 41#include <sys/exec.h>
42#include <sys/hook.h> 42#include <sys/hook.h>
43#include <sys/kmem.h> 43#include <sys/kmem.h>
44#include <sys/malloc.h> 44#include <sys/malloc.h>
 45#include <sys/once.h>
45#include <sys/rwlock.h> 46#include <sys/rwlock.h>
46#include <sys/systm.h> 47#include <sys/systm.h>
47 48
48/* 49/*
49 * A generic linear hook. 50 * A generic linear hook.
50 */ 51 */
51struct hook_desc { 52struct hook_desc {
52 LIST_ENTRY(hook_desc) hk_list; 53 LIST_ENTRY(hook_desc) hk_list;
53 void (*hk_fn)(void *); 54 void (*hk_fn)(void *);
54 void *hk_arg; 55 void *hk_arg;
55}; 56};
56typedef LIST_HEAD(, hook_desc) hook_list_t; 57typedef LIST_HEAD(, hook_desc) hook_list_t;
57 58
@@ -64,105 +65,136 @@ struct khook_list { @@ -64,105 +65,136 @@ struct khook_list {
64 hook_list_t hl_list; 65 hook_list_t hl_list;
65 kmutex_t hl_lock; 66 kmutex_t hl_lock;
66 kmutex_t *hl_cvlock; 67 kmutex_t *hl_cvlock;
67 struct lwp *hl_lwp; 68 struct lwp *hl_lwp;
68 kcondvar_t hl_cv; 69 kcondvar_t hl_cv;
69 enum hook_list_st 70 enum hook_list_st
70 hl_state; 71 hl_state;
71 khook_t *hl_active_hk; 72 khook_t *hl_active_hk;
72 char hl_namebuf[HOOKNAMSIZ]; 73 char hl_namebuf[HOOKNAMSIZ];
73}; 74};
74 75
75int powerhook_debug = 0; 76int powerhook_debug = 0;
76 77
 78static ONCE_DECL(hook_control);
 79static krwlock_t exithook_lock;
 80static krwlock_t forkhook_lock;
 81
 82static int
 83hook_init(void)
 84{
 85
 86 rw_init(&exithook_lock);
 87 rw_init(&forkhook_lock);
 88
 89 return 0;
 90}
 91
77static void * 92static void *
78hook_establish(hook_list_t *list, void (*fn)(void *), void *arg) 93hook_establish(hook_list_t *list, krwlock_t *lock,
 94 void (*fn)(void *), void *arg)
79{ 95{
80 struct hook_desc *hd; 96 struct hook_desc *hd;
81 97
82 hd = malloc(sizeof(*hd), M_DEVBUF, M_NOWAIT); 98 RUN_ONCE(&hook_control, hook_init);
83 if (hd == NULL) 
84 return (NULL); 
85 99
86 hd->hk_fn = fn; 100 hd = malloc(sizeof(*hd), M_DEVBUF, M_NOWAIT);
87 hd->hk_arg = arg; 101 if (hd != NULL) {
88 LIST_INSERT_HEAD(list, hd, hk_list); 102 if (lock)
 103 rw_enter(lock, RW_WRITER);
 104 hd->hk_fn = fn;
 105 hd->hk_arg = arg;
 106 LIST_INSERT_HEAD(list, hd, hk_list);
 107 if (lock)
 108 rw_exit(lock);
 109 }
89 110
90 return (hd); 111 return (hd);
91} 112}
92 113
93static void 114static void
94hook_disestablish(hook_list_t *list, void *vhook) 115hook_disestablish(hook_list_t *list, krwlock_t *lock, void *vhook)
95{ 116{
 117
 118 if (lock)
 119 rw_enter(lock, RW_WRITER);
96#ifdef DIAGNOSTIC 120#ifdef DIAGNOSTIC
97 struct hook_desc *hd; 121 struct hook_desc *hd;
98 122
99 LIST_FOREACH(hd, list, hk_list) { 123 LIST_FOREACH(hd, list, hk_list) {
100 if (hd == vhook) 124 if (hd == vhook)
101 break; 125 break;
102 } 126 }
103 127
104 if (hd == NULL) 128 if (hd == NULL)
105 panic("hook_disestablish: hook %p not established", vhook); 129 panic("hook_disestablish: hook %p not established", vhook);
106#endif 130#endif
107 LIST_REMOVE((struct hook_desc *)vhook, hk_list); 131 LIST_REMOVE((struct hook_desc *)vhook, hk_list);
108 free(vhook, M_DEVBUF); 132 free(vhook, M_DEVBUF);
 133 if (lock)
 134 rw_exit(lock);
109} 135}
110 136
111static void 137static void
112hook_destroy(hook_list_t *list) 138hook_destroy(hook_list_t *list)
113{ 139{
114 struct hook_desc *hd; 140 struct hook_desc *hd;
115 141
116 while ((hd = LIST_FIRST(list)) != NULL) { 142 while ((hd = LIST_FIRST(list)) != NULL) {
117 LIST_REMOVE(hd, hk_list); 143 LIST_REMOVE(hd, hk_list);
118 free(hd, M_DEVBUF); 144 free(hd, M_DEVBUF);
119 } 145 }
120} 146}
121 147
122static void 148static void
123hook_proc_run(hook_list_t *list, struct proc *p) 149hook_proc_run(hook_list_t *list, krwlock_t *lock, struct proc *p)
124{ 150{
125 struct hook_desc *hd; 151 struct hook_desc *hd;
126 152
 153 RUN_ONCE(&hook_control, hook_init);
 154
 155 if (lock)
 156 rw_enter(lock, RW_READER);
127 LIST_FOREACH(hd, list, hk_list) { 157 LIST_FOREACH(hd, list, hk_list) {
128 __FPTRCAST(void (*)(struct proc *, void *), *hd->hk_fn)(p, 158 __FPTRCAST(void (*)(struct proc *, void *), *hd->hk_fn)(p,
129 hd->hk_arg); 159 hd->hk_arg);
130 } 160 }
 161 if (lock)
 162 rw_exit(lock);
131} 163}
132 164
133/* 165/*
134 * "Shutdown hook" types, functions, and variables. 166 * "Shutdown hook" types, functions, and variables.
135 * 167 *
136 * Should be invoked immediately before the 168 * Should be invoked immediately before the
137 * system is halted or rebooted, i.e. after file systems unmounted, 169 * system is halted or rebooted, i.e. after file systems unmounted,
138 * after crash dump done, etc. 170 * after crash dump done, etc.
139 * 171 *
140 * Each shutdown hook is removed from the list before it's run, so that 172 * Each shutdown hook is removed from the list before it's run, so that
141 * it won't be run again. 173 * it won't be run again.
142 */ 174 */
143 175
144static hook_list_t shutdownhook_list = LIST_HEAD_INITIALIZER(shutdownhook_list); 176static hook_list_t shutdownhook_list = LIST_HEAD_INITIALIZER(shutdownhook_list);
145 177
146void * 178void *
147shutdownhook_establish(void (*fn)(void *), void *arg) 179shutdownhook_establish(void (*fn)(void *), void *arg)
148{ 180{
149 return hook_establish(&shutdownhook_list, fn, arg); 181 return hook_establish(&shutdownhook_list, NULL, fn, arg);
150} 182}
151 183
152void 184void
153shutdownhook_disestablish(void *vhook) 185shutdownhook_disestablish(void *vhook)
154{ 186{
155 hook_disestablish(&shutdownhook_list, vhook); 187 hook_disestablish(&shutdownhook_list, NULL, vhook);
156} 188}
157 189
158/* 190/*
159 * Run shutdown hooks. Should be invoked immediately before the 191 * Run shutdown hooks. Should be invoked immediately before the
160 * system is halted or rebooted, i.e. after file systems unmounted, 192 * system is halted or rebooted, i.e. after file systems unmounted,
161 * after crash dump done, etc. 193 * after crash dump done, etc.
162 * 194 *
163 * Each shutdown hook is removed from the list before it's run, so that 195 * Each shutdown hook is removed from the list before it's run, so that
164 * it won't be run again. 196 * it won't be run again.
165 */ 197 */
166void 198void
167doshutdownhooks(void) 199doshutdownhooks(void)
168{ 200{
@@ -183,152 +215,152 @@ doshutdownhooks(void) @@ -183,152 +215,152 @@ doshutdownhooks(void)
183#endif 215#endif
184 } 216 }
185} 217}
186 218
187/* 219/*
188 * "Mountroot hook" types, functions, and variables. 220 * "Mountroot hook" types, functions, and variables.
189 */ 221 */
190 222
191static hook_list_t mountroothook_list=LIST_HEAD_INITIALIZER(mountroothook_list); 223static hook_list_t mountroothook_list=LIST_HEAD_INITIALIZER(mountroothook_list);
192 224
193void * 225void *
194mountroothook_establish(void (*fn)(device_t), device_t dev) 226mountroothook_establish(void (*fn)(device_t), device_t dev)
195{ 227{
196 return hook_establish(&mountroothook_list, __FPTRCAST(void (*), fn), 228 return hook_establish(&mountroothook_list, NULL,
197 dev); 229 __FPTRCAST(void (*), fn), dev);
198} 230}
199 231
200void 232void
201mountroothook_disestablish(void *vhook) 233mountroothook_disestablish(void *vhook)
202{ 234{
203 hook_disestablish(&mountroothook_list, vhook); 235 hook_disestablish(&mountroothook_list, NULL, vhook);
204} 236}
205 237
206void 238void
207mountroothook_destroy(void) 239mountroothook_destroy(void)
208{ 240{
209 hook_destroy(&mountroothook_list); 241 hook_destroy(&mountroothook_list);
210} 242}
211 243
212void 244void
213domountroothook(device_t therootdev) 245domountroothook(device_t therootdev)
214{ 246{
215 struct hook_desc *hd; 247 struct hook_desc *hd;
216 248
217 LIST_FOREACH(hd, &mountroothook_list, hk_list) { 249 LIST_FOREACH(hd, &mountroothook_list, hk_list) {
218 if (hd->hk_arg == therootdev) { 250 if (hd->hk_arg == therootdev) {
219 (*hd->hk_fn)(hd->hk_arg); 251 (*hd->hk_fn)(hd->hk_arg);
220 return; 252 return;
221 } 253 }
222 } 254 }
223} 255}
224 256
225static hook_list_t exechook_list = LIST_HEAD_INITIALIZER(exechook_list); 257static hook_list_t exechook_list = LIST_HEAD_INITIALIZER(exechook_list);
226 258
227void * 259void *
228exechook_establish(void (*fn)(struct proc *, void *), void *arg) 260exechook_establish(void (*fn)(struct proc *, void *), void *arg)
229{ 261{
230 return hook_establish(&exechook_list, __FPTRCAST(void (*)(void *), fn), 262 return hook_establish(&exechook_list, &exec_lock,
231 arg); 263 __FPTRCAST(void (*)(void *), fn), arg);
232} 264}
233 265
234void 266void
235exechook_disestablish(void *vhook) 267exechook_disestablish(void *vhook)
236{ 268{
237 hook_disestablish(&exechook_list, vhook); 269 hook_disestablish(&exechook_list, &exec_lock, vhook);
238} 270}
239 271
240/* 272/*
241 * Run exec hooks. 273 * Run exec hooks.
242 */ 274 */
243void 275void
244doexechooks(struct proc *p) 276doexechooks(struct proc *p)
245{ 277{
246 hook_proc_run(&exechook_list, p); 278 KASSERT(rw_lock_held(&exec_lock));
 279
 280 hook_proc_run(&exechook_list, NULL, p);
247} 281}
248 282
249static hook_list_t exithook_list = LIST_HEAD_INITIALIZER(exithook_list); 283static hook_list_t exithook_list = LIST_HEAD_INITIALIZER(exithook_list);
250 284
251void * 285void *
252exithook_establish(void (*fn)(struct proc *, void *), void *arg) 286exithook_establish(void (*fn)(struct proc *, void *), void *arg)
253{ 287{
254 void *rv; 
255 288
256 rw_enter(&exec_lock, RW_WRITER); 289 return hook_establish(&exithook_list, &exithook_lock,
257 rv = hook_establish(&exithook_list, __FPTRCAST(void (*)(void *), fn), 290 __FPTRCAST(void (*)(void *), fn), arg);
258 arg); 
259 rw_exit(&exec_lock); 
260 return rv; 
261} 291}
262 292
263void 293void
264exithook_disestablish(void *vhook) 294exithook_disestablish(void *vhook)
265{ 295{
266 296
267 rw_enter(&exec_lock, RW_WRITER); 297 hook_disestablish(&exithook_list, &exithook_lock, vhook);
268 hook_disestablish(&exithook_list, vhook); 
269 rw_exit(&exec_lock); 
270} 298}
271 299
272/* 300/*
273 * Run exit hooks. 301 * Run exit hooks.
274 */ 302 */
275void 303void
276doexithooks(struct proc *p) 304doexithooks(struct proc *p)
277{ 305{
278 hook_proc_run(&exithook_list, p); 306 hook_proc_run(&exithook_list, &exithook_lock, p);
279} 307}
280 308
281static hook_list_t forkhook_list = LIST_HEAD_INITIALIZER(forkhook_list); 309static hook_list_t forkhook_list = LIST_HEAD_INITIALIZER(forkhook_list);
282 310
283void * 311void *
284forkhook_establish(void (*fn)(struct proc *, struct proc *)) 312forkhook_establish(void (*fn)(struct proc *, struct proc *))
285{ 313{
286 return hook_establish(&forkhook_list, __FPTRCAST(void (*)(void *), fn), 314 return hook_establish(&forkhook_list, &forkhook_lock,
287 NULL); 315 __FPTRCAST(void (*)(void *), fn), NULL);
288} 316}
289 317
290void 318void
291forkhook_disestablish(void *vhook) 319forkhook_disestablish(void *vhook)
292{ 320{
293 hook_disestablish(&forkhook_list, vhook); 321 hook_disestablish(&forkhook_list, &forkhook_lock, vhook);
294} 322}
295 323
296/* 324/*
297 * Run fork hooks. 325 * Run fork hooks.
298 */ 326 */
299void 327void
300doforkhooks(struct proc *p2, struct proc *p1) 328doforkhooks(struct proc *p2, struct proc *p1)
301{ 329{
302 struct hook_desc *hd; 330 struct hook_desc *hd;
303 331
 332 RUN_ONCE(&hook_control, hook_init);
 333
 334 rw_enter(&forkhook_lock, RW_READER);
304 LIST_FOREACH(hd, &forkhook_list, hk_list) { 335 LIST_FOREACH(hd, &forkhook_list, hk_list) {
305 __FPTRCAST(void (*)(struct proc *, struct proc *), *hd->hk_fn) 336 __FPTRCAST(void (*)(struct proc *, struct proc *), *hd->hk_fn)
306 (p2, p1); 337 (p2, p1);
307 } 338 }
 339 rw_exit(&forkhook_lock);
308} 340}
309 341
310static hook_list_t critpollhook_list = LIST_HEAD_INITIALIZER(critpollhook_list); 342static hook_list_t critpollhook_list = LIST_HEAD_INITIALIZER(critpollhook_list);
311 343
312void * 344void *
313critpollhook_establish(void (*fn)(void *), void *arg) 345critpollhook_establish(void (*fn)(void *), void *arg)
314{ 346{
315 return hook_establish(&critpollhook_list, fn, arg); 347 return hook_establish(&critpollhook_list, NULL, fn, arg);
316} 348}
317 349
318void 350void
319critpollhook_disestablish(void *vhook) 351critpollhook_disestablish(void *vhook)
320{ 352{
321 hook_disestablish(&critpollhook_list, vhook); 353 hook_disestablish(&critpollhook_list, NULL, vhook);
322} 354}
323 355
324/* 356/*
325 * Run critical polling hooks. 357 * Run critical polling hooks.
326 */ 358 */
327void 359void
328docritpollhooks(void) 360docritpollhooks(void)
329{ 361{
330 struct hook_desc *hd; 362 struct hook_desc *hd;
331 363
332 LIST_FOREACH(hd, &critpollhook_list, hk_list) { 364 LIST_FOREACH(hd, &critpollhook_list, hk_list) {
333 (*hd->hk_fn)(hd->hk_arg); 365 (*hd->hk_fn)(hd->hk_arg);
334 } 366 }

cvs diff -r1.101 -r1.101.2.1 src/sys/kern/vfs_mount.c (expand / switch to unified diff)

--- src/sys/kern/vfs_mount.c 2022/12/09 10:33:18 1.101
+++ src/sys/kern/vfs_mount.c 2024/04/18 18:22:10 1.101.2.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: vfs_mount.c,v 1.101 2022/12/09 10:33:18 hannken Exp $ */ 1/* $NetBSD: vfs_mount.c,v 1.101.2.1 2024/04/18 18:22:10 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 1997-2020 The NetBSD Foundation, Inc. 4 * Copyright (c) 1997-2020 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility, 8 * by Jason R. Thorpe of the Numerical Aerospace Simulation Facility,
9 * NASA Ames Research Center, by Charles M. Hannum, and by Andrew Doran. 9 * NASA Ames Research Center, by Charles M. Hannum, and by Andrew Doran.
10 * 10 *
11 * Redistribution and use in source and binary forms, with or without 11 * Redistribution and use in source and binary forms, with or without
12 * modification, are permitted provided that the following conditions 12 * modification, are permitted provided that the following conditions
13 * are met: 13 * are met:
14 * 1. Redistributions of source code must retain the above copyright 14 * 1. Redistributions of source code must retain the above copyright
@@ -57,27 +57,27 @@ @@ -57,27 +57,27 @@
57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 57 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 58 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 59 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 60 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 61 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 62 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 63 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
64 * SUCH DAMAGE. 64 * SUCH DAMAGE.
65 * 65 *
66 * @(#)vfs_subr.c 8.13 (Berkeley) 4/18/94 66 * @(#)vfs_subr.c 8.13 (Berkeley) 4/18/94
67 */ 67 */
68 68
69#include <sys/cdefs.h> 69#include <sys/cdefs.h>
70__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.101 2022/12/09 10:33:18 hannken Exp $"); 70__KERNEL_RCSID(0, "$NetBSD: vfs_mount.c,v 1.101.2.1 2024/04/18 18:22:10 martin Exp $");
71 71
72#include <sys/param.h> 72#include <sys/param.h>
73#include <sys/kernel.h> 73#include <sys/kernel.h>
74 74
75#include <sys/atomic.h> 75#include <sys/atomic.h>
76#include <sys/buf.h> 76#include <sys/buf.h>
77#include <sys/conf.h> 77#include <sys/conf.h>
78#include <sys/fcntl.h> 78#include <sys/fcntl.h>
79#include <sys/filedesc.h> 79#include <sys/filedesc.h>
80#include <sys/device.h> 80#include <sys/device.h>
81#include <sys/kauth.h> 81#include <sys/kauth.h>
82#include <sys/kmem.h> 82#include <sys/kmem.h>
83#include <sys/module.h> 83#include <sys/module.h>
@@ -927,27 +927,27 @@ err_mounted: @@ -927,27 +927,27 @@ err_mounted:
927 927
928 return error; 928 return error;
929} 929}
930 930
931/* 931/*
932 * Do the actual file system unmount. File system is assumed to have 932 * Do the actual file system unmount. File system is assumed to have
933 * been locked by the caller. 933 * been locked by the caller.
934 * 934 *
935 * => Caller hold reference to the mount, explicitly for dounmount(). 935 * => Caller hold reference to the mount, explicitly for dounmount().
936 */ 936 */
937int 937int
938dounmount(struct mount *mp, int flags, struct lwp *l) 938dounmount(struct mount *mp, int flags, struct lwp *l)
939{ 939{
940 vnode_t *coveredvp; 940 vnode_t *coveredvp, *vp;
941 int error, async, used_syncer, used_extattr; 941 int error, async, used_syncer, used_extattr;
942 const bool was_suspended = fstrans_is_owner(mp); 942 const bool was_suspended = fstrans_is_owner(mp);
943 943
944#if NVERIEXEC > 0 944#if NVERIEXEC > 0
945 error = veriexec_unmountchk(mp); 945 error = veriexec_unmountchk(mp);
946 if (error) 946 if (error)
947 return (error); 947 return (error);
948#endif /* NVERIEXEC > 0 */ 948#endif /* NVERIEXEC > 0 */
949 949
950 if (!was_suspended) { 950 if (!was_suspended) {
951 error = vfs_suspend(mp, 0); 951 error = vfs_suspend(mp, 0);
952 if (error) { 952 if (error) {
953 return error; 953 return error;
@@ -994,28 +994,30 @@ dounmount(struct mount *mp, int flags, s @@ -994,28 +994,30 @@ dounmount(struct mount *mp, int flags, s
994 /* 994 /*
995 * mark filesystem as gone to prevent further umounts 995 * mark filesystem as gone to prevent further umounts
996 * after mnt_umounting lock is gone, this also prevents 996 * after mnt_umounting lock is gone, this also prevents
997 * vfs_busy() from succeeding. 997 * vfs_busy() from succeeding.
998 */ 998 */
999 mp->mnt_iflag |= IMNT_GONE; 999 mp->mnt_iflag |= IMNT_GONE;
1000 if ((coveredvp = mp->mnt_vnodecovered) != NULLVP) { 1000 if ((coveredvp = mp->mnt_vnodecovered) != NULLVP) {
1001 coveredvp->v_mountedhere = NULL; 1001 coveredvp->v_mountedhere = NULL;
1002 } 1002 }
1003 if (!was_suspended) 1003 if (!was_suspended)
1004 vfs_resume(mp); 1004 vfs_resume(mp);
1005 1005
1006 mountlist_remove(mp); 1006 mountlist_remove(mp);
1007 if (TAILQ_FIRST(&mp->mnt_vnodelist) != NULL) 1007 if ((vp = VIMPL_TO_VNODE(TAILQ_FIRST(&mp->mnt_vnodelist))) != NULL) {
 1008 vprint("dangling", vp);
1008 panic("unmount: dangling vnode"); 1009 panic("unmount: dangling vnode");
 1010 }
1009 vfs_hooks_unmount(mp); 1011 vfs_hooks_unmount(mp);
1010 1012
1011 vfs_set_lowermount(mp, NULL); 1013 vfs_set_lowermount(mp, NULL);
1012 vfs_rele(mp); /* reference from mount() */ 1014 vfs_rele(mp); /* reference from mount() */
1013 if (coveredvp != NULLVP) { 1015 if (coveredvp != NULLVP) {
1014 vrele(coveredvp); 1016 vrele(coveredvp);
1015 } 1017 }
1016 return (0); 1018 return (0);
1017} 1019}
1018 1020
1019/* 1021/*
1020 * Unmount all file systems. 1022 * Unmount all file systems.
1021 * We traverse the list in reverse order under the assumption that doing so 1023 * We traverse the list in reverse order under the assumption that doing so

cvs diff -r1.82 -r1.82.4.1 src/sys/miscfs/procfs/procfs.h (expand / switch to unified diff)

--- src/sys/miscfs/procfs/procfs.h 2022/01/19 10:23:00 1.82
+++ src/sys/miscfs/procfs/procfs.h 2024/04/18 18:22:10 1.82.4.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: procfs.h,v 1.82 2022/01/19 10:23:00 martin Exp $ */ 1/* $NetBSD: procfs.h,v 1.82.4.1 2024/04/18 18:22:10 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1993 4 * Copyright (c) 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Jan-Simon Pendry. 8 * Jan-Simon Pendry.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -119,27 +119,29 @@ typedef enum { @@ -119,27 +119,29 @@ typedef enum {
119#endif 119#endif
120 PFSlast, /* track number of types */ 120 PFSlast, /* track number of types */
121} pfstype; 121} pfstype;
122 122
123/* 123/*
124 * control data for the proc file system. 124 * control data for the proc file system.
125 */ 125 */
126struct pfskey { 126struct pfskey {
127 pfstype pk_type; /* type of procfs node */ 127 pfstype pk_type; /* type of procfs node */
128 pid_t pk_pid; /* associated process */ 128 pid_t pk_pid; /* associated process */
129 int pk_fd; /* associated fd if not -1 */ 129 int pk_fd; /* associated fd if not -1 */
130}; 130};
131struct pfsnode { 131struct pfsnode {
 132 LIST_ENTRY(pfsnode) pfs_hash; /* per pid hash list */
132 struct vnode *pfs_vnode; /* vnode associated with this pfsnode */ 133 struct vnode *pfs_vnode; /* vnode associated with this pfsnode */
 134 struct mount *pfs_mount; /* mount associated with this pfsnode */
133 struct pfskey pfs_key; 135 struct pfskey pfs_key;
134#define pfs_type pfs_key.pk_type 136#define pfs_type pfs_key.pk_type
135#define pfs_pid pfs_key.pk_pid 137#define pfs_pid pfs_key.pk_pid
136#define pfs_fd pfs_key.pk_fd 138#define pfs_fd pfs_key.pk_fd
137 mode_t pfs_mode; /* mode bits for stat() */ 139 mode_t pfs_mode; /* mode bits for stat() */
138 u_long pfs_flags; /* open flags */ 140 u_long pfs_flags; /* open flags */
139 uint64_t pfs_fileno; /* unique file id */ 141 uint64_t pfs_fileno; /* unique file id */
140}; 142};
141 143
142#define PROCFS_NOTELEN 64 /* max length of a note (/proc/$pid/note) */ 144#define PROCFS_NOTELEN 64 /* max length of a note (/proc/$pid/note) */
143#define PROCFS_MAXNAMLEN 255 145#define PROCFS_MAXNAMLEN 255
144 146
145#endif /* _KERNEL */ 147#endif /* _KERNEL */
@@ -180,27 +182,26 @@ procfs_fileno(pid_t _pid, pfstype _type, @@ -180,27 +182,26 @@ procfs_fileno(pid_t _pid, pfstype _type,
180 default: 182 default:
181 _ino = _pid + 1; 183 _ino = _pid + 1;
182 if (_fd != -1) 184 if (_fd != -1)
183 _ino = _ino << 32 | _fd; 185 _ino = _ino << 32 | _fd;
184 return _ino * PFSlast + _type; 186 return _ino * PFSlast + _type;
185 } 187 }
186} 188}
187 189
188#define PROCFS_FILENO(pid, type, fd) procfs_fileno(pid, type, fd) 190#define PROCFS_FILENO(pid, type, fd) procfs_fileno(pid, type, fd)
189 191
190#define PROCFS_TYPE(type) ((type) % PFSlast) 192#define PROCFS_TYPE(type) ((type) % PFSlast)
191 193
192struct procfsmount { 194struct procfsmount {
193 void *pmnt_exechook; 
194 int pmnt_flags; 195 int pmnt_flags;
195}; 196};
196 197
197#define VFSTOPROC(mp) ((struct procfsmount *)(mp)->mnt_data) 198#define VFSTOPROC(mp) ((struct procfsmount *)(mp)->mnt_data)
198 199
199/* 200/*
200 * Convert between pfsnode vnode 201 * Convert between pfsnode vnode
201 */ 202 */
202#define VTOPFS(vp) ((struct pfsnode *)(vp)->v_data) 203#define VTOPFS(vp) ((struct pfsnode *)(vp)->v_data)
203#define PFSTOV(pfs) ((pfs)->pfs_vnode) 204#define PFSTOV(pfs) ((pfs)->pfs_vnode)
204 205
205typedef struct vfs_namemap vfs_namemap_t; 206typedef struct vfs_namemap vfs_namemap_t;
206struct vfs_namemap { 207struct vfs_namemap {
@@ -259,27 +260,27 @@ int procfs_dofd(struct lwp *, struct pro @@ -259,27 +260,27 @@ int procfs_dofd(struct lwp *, struct pro
259int procfs_douptime(struct lwp *, struct proc *, struct pfsnode *, 260int procfs_douptime(struct lwp *, struct proc *, struct pfsnode *,
260 struct uio *); 261 struct uio *);
261int procfs_domounts(struct lwp *, struct proc *, struct pfsnode *, 262int procfs_domounts(struct lwp *, struct proc *, struct pfsnode *,
262 struct uio *); 263 struct uio *);
263int procfs_doemul(struct lwp *, struct proc *, struct pfsnode *, 264int procfs_doemul(struct lwp *, struct proc *, struct pfsnode *,
264 struct uio *); 265 struct uio *);
265int procfs_doversion(struct lwp *, struct proc *, struct pfsnode *, 266int procfs_doversion(struct lwp *, struct proc *, struct pfsnode *,
266 struct uio *); 267 struct uio *);
267int procfs_doauxv(struct lwp *, struct proc *, struct pfsnode *, 268int procfs_doauxv(struct lwp *, struct proc *, struct pfsnode *,
268 struct uio *); 269 struct uio *);
269int procfs_dolimit(struct lwp *, struct proc *, struct pfsnode *, 270int procfs_dolimit(struct lwp *, struct proc *, struct pfsnode *,
270 struct uio *); 271 struct uio *);
271 272
272void procfs_revoke_vnodes(struct proc *, void *); 273void procfs_hashrem(struct pfsnode *);
273int procfs_getfp(struct pfsnode *, struct proc *, struct file **); 274int procfs_getfp(struct pfsnode *, struct proc *, struct file **);
274 275
275/* functions to check whether or not files should be displayed */ 276/* functions to check whether or not files should be displayed */
276int procfs_validauxv(struct lwp *, struct mount *); 277int procfs_validauxv(struct lwp *, struct mount *);
277int procfs_validfile(struct lwp *, struct mount *); 278int procfs_validfile(struct lwp *, struct mount *);
278int procfs_validfpregs(struct lwp *, struct mount *); 279int procfs_validfpregs(struct lwp *, struct mount *);
279int procfs_validregs(struct lwp *, struct mount *); 280int procfs_validregs(struct lwp *, struct mount *);
280int procfs_validmap(struct lwp *, struct mount *); 281int procfs_validmap(struct lwp *, struct mount *);
281 282
282int procfs_rw(void *); 283int procfs_rw(void *);
283 284
284int procfs_getcpuinfstr(char *, size_t *); 285int procfs_getcpuinfstr(char *, size_t *);
285 286

cvs diff -r1.116 -r1.116.20.1 src/sys/miscfs/procfs/procfs_subr.c (expand / switch to unified diff)

--- src/sys/miscfs/procfs/procfs_subr.c 2020/05/23 23:42:43 1.116
+++ src/sys/miscfs/procfs/procfs_subr.c 2024/04/18 18:22:10 1.116.20.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: procfs_subr.c,v 1.116 2020/05/23 23:42:43 ad Exp $ */ 1/* $NetBSD: procfs_subr.c,v 1.116.20.1 2024/04/18 18:22:10 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc. 4 * Copyright (c) 2006, 2007, 2008 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -92,27 +92,27 @@ @@ -92,27 +92,27 @@
92 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 92 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
93 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 93 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
94 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 94 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
95 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 95 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
96 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 96 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
97 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 97 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
98 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 98 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
99 * SUCH DAMAGE. 99 * SUCH DAMAGE.
100 * 100 *
101 * @(#)procfs_subr.c 8.6 (Berkeley) 5/14/95 101 * @(#)procfs_subr.c 8.6 (Berkeley) 5/14/95
102 */ 102 */
103 103
104#include <sys/cdefs.h> 104#include <sys/cdefs.h>
105__KERNEL_RCSID(0, "$NetBSD: procfs_subr.c,v 1.116 2020/05/23 23:42:43 ad Exp $"); 105__KERNEL_RCSID(0, "$NetBSD: procfs_subr.c,v 1.116.20.1 2024/04/18 18:22:10 martin Exp $");
106 106
107#include <sys/param.h> 107#include <sys/param.h>
108#include <sys/systm.h> 108#include <sys/systm.h>
109#include <sys/time.h> 109#include <sys/time.h>
110#include <sys/kernel.h> 110#include <sys/kernel.h>
111#include <sys/proc.h> 111#include <sys/proc.h>
112#include <sys/fstrans.h> 112#include <sys/fstrans.h>
113#include <sys/vnode.h> 113#include <sys/vnode.h>
114#include <sys/stat.h> 114#include <sys/stat.h>
115#include <sys/file.h> 115#include <sys/file.h>
116#include <sys/filedesc.h> 116#include <sys/filedesc.h>
117#include <sys/kauth.h> 117#include <sys/kauth.h>
118#include <sys/sysctl.h> 118#include <sys/sysctl.h>
@@ -348,77 +348,26 @@ vfs_getuserstr(struct uio *uio, char *bf @@ -348,77 +348,26 @@ vfs_getuserstr(struct uio *uio, char *bf
348} 348}
349 349
350const vfs_namemap_t * 350const vfs_namemap_t *
351vfs_findname(const vfs_namemap_t *nm, const char *bf, int buflen) 351vfs_findname(const vfs_namemap_t *nm, const char *bf, int buflen)
352{ 352{
353 353
354 for (; nm->nm_name; nm++) 354 for (; nm->nm_name; nm++)
355 if (memcmp(bf, nm->nm_name, buflen+1) == 0) 355 if (memcmp(bf, nm->nm_name, buflen+1) == 0)
356 return (nm); 356 return (nm);
357 357
358 return (0); 358 return (0);
359} 359}
360 360
361static bool 
362procfs_revoke_selector(void *arg, struct vnode *vp) 
363{ 
364 struct proc *p = arg; 
365 struct pfsnode *pfs; 
366 
367 KASSERT(mutex_owned(vp->v_interlock)); 
368 
369 pfs = VTOPFS(vp); 
370 
371 return (pfs != NULL && pfs->pfs_pid == p->p_pid); 
372} 
373 
374void 
375procfs_revoke_vnodes(struct proc *p, void *arg) 
376{ 
377 int error; 
378 bool suspended; 
379 struct vnode *vp; 
380 struct vnode_iterator *marker; 
381 struct mount *mp = (struct mount *)arg; 
382 
383 if (!(p->p_flag & PK_SUGID)) 
384 return; 
385 
386 suspended = false; 
387 vfs_vnode_iterator_init(mp, &marker); 
388 
389 while ((vp = vfs_vnode_iterator_next(marker, 
390 procfs_revoke_selector, p)) != NULL) { 
391 if (vrecycle(vp)) 
392 continue; 
393 /* Vnode is busy, we have to suspend the mount for vgone(). */ 
394 while (! suspended) { 
395 error = vfs_suspend(mp, 0); 
396 if (error == 0) { 
397 suspended = true; 
398 } else if (error != EINTR && error != ERESTART) { 
399 KASSERT(error == EOPNOTSUPP); 
400 break; 
401 } 
402 } 
403 vgone(vp); 
404 } 
405 
406 if (suspended) 
407 vfs_resume(mp); 
408 
409 vfs_vnode_iterator_destroy(marker); 
410} 
411 
412bool 361bool
413procfs_use_linux_compat(struct mount *mp) 362procfs_use_linux_compat(struct mount *mp)
414{ 363{
415 const int flags = VFSTOPROC(mp)->pmnt_flags; 364 const int flags = VFSTOPROC(mp)->pmnt_flags;
416 365
417 return (flags & PROCFSMNT_LINUXCOMPAT) ? true : false; 366 return (flags & PROCFSMNT_LINUXCOMPAT) ? true : false;
418} 367}
419 368
420struct proc * 369struct proc *
421procfs_proc_find(struct mount *mp, pid_t pid) 370procfs_proc_find(struct mount *mp, pid_t pid)
422{ 371{
423 372
424 KASSERT(mutex_owned(&proc_lock)); 373 KASSERT(mutex_owned(&proc_lock));

cvs diff -r1.111 -r1.111.4.1 src/sys/miscfs/procfs/procfs_vfsops.c (expand / switch to unified diff)

--- src/sys/miscfs/procfs/procfs_vfsops.c 2022/01/17 11:20:00 1.111
+++ src/sys/miscfs/procfs/procfs_vfsops.c 2024/04/18 18:22:10 1.111.4.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: procfs_vfsops.c,v 1.111 2022/01/17 11:20:00 bouyer Exp $ */ 1/* $NetBSD: procfs_vfsops.c,v 1.111.4.1 2024/04/18 18:22:10 martin Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1993 4 * Copyright (c) 1993
5 * The Regents of the University of California. All rights reserved. 5 * The Regents of the University of California. All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to Berkeley by 7 * This code is derived from software contributed to Berkeley by
8 * Jan-Simon Pendry. 8 * Jan-Simon Pendry.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -66,61 +66,88 @@ @@ -66,61 +66,88 @@
66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69 * SUCH DAMAGE. 69 * SUCH DAMAGE.
70 * 70 *
71 * @(#)procfs_vfsops.c 8.7 (Berkeley) 5/10/95 71 * @(#)procfs_vfsops.c 8.7 (Berkeley) 5/10/95
72 */ 72 */
73 73
74/* 74/*
75 * procfs VFS interface 75 * procfs VFS interface
76 */ 76 */
77 77
78#include <sys/cdefs.h> 78#include <sys/cdefs.h>
79__KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.111 2022/01/17 11:20:00 bouyer Exp $"); 79__KERNEL_RCSID(0, "$NetBSD: procfs_vfsops.c,v 1.111.4.1 2024/04/18 18:22:10 martin Exp $");
80 80
81#if defined(_KERNEL_OPT) 81#if defined(_KERNEL_OPT)
82#include "opt_compat_netbsd.h" 82#include "opt_compat_netbsd.h"
83#endif 83#endif
84 84
85#include <sys/param.h> 85#include <sys/param.h>
86#include <sys/atomic.h> 86#include <sys/atomic.h>
87#include <sys/buf.h> 87#include <sys/buf.h>
88#include <sys/dirent.h> 88#include <sys/dirent.h>
89#include <sys/file.h> 89#include <sys/file.h>
90#include <sys/filedesc.h> 90#include <sys/filedesc.h>
 91#include <sys/fstrans.h>
91#include <sys/kauth.h> 92#include <sys/kauth.h>
92#include <sys/kernel.h> 93#include <sys/kernel.h>
93#include <sys/module.h> 94#include <sys/module.h>
94#include <sys/mount.h> 95#include <sys/mount.h>
95#include <sys/proc.h> 96#include <sys/proc.h>
96#include <sys/signalvar.h> 97#include <sys/signalvar.h>
97#include <sys/sysctl.h> 98#include <sys/sysctl.h>
98#include <sys/syslog.h> 99#include <sys/syslog.h>
99#include <sys/systm.h> 100#include <sys/systm.h>
100#include <sys/time.h> 101#include <sys/time.h>
101#include <sys/vnode.h> 102#include <sys/vnode.h>
102 103
103#include <miscfs/genfs/genfs.h> 104#include <miscfs/genfs/genfs.h>
104 105
105#include <miscfs/procfs/procfs.h> 106#include <miscfs/procfs/procfs.h>
106 107
107#include <uvm/uvm_extern.h> /* for PAGE_SIZE */ 108#include <uvm/uvm_extern.h> /* for PAGE_SIZE */
108 109
109MODULE(MODULE_CLASS_VFS, procfs, "ptrace_common"); 110MODULE(MODULE_CLASS_VFS, procfs, "ptrace_common");
110 111
111VFS_PROTOS(procfs); 112VFS_PROTOS(procfs);
112 113
 114#define PROCFS_HASHSIZE 256
 115#define PROCFS_EXEC_HOOK ((void *)1)
 116#define PROCFS_EXIT_HOOK ((void *)2)
 117
113static kauth_listener_t procfs_listener; 118static kauth_listener_t procfs_listener;
 119static void *procfs_exechook;
 120static void *procfs_exithook;
 121LIST_HEAD(hashhead, pfsnode);
 122static u_long procfs_hashmask;
 123static struct hashhead *procfs_hashtab;
 124static kmutex_t procfs_hashlock;
 125
 126static struct hashhead *
 127procfs_hashhead(pid_t pid)
 128{
 129
 130 return &procfs_hashtab[pid & procfs_hashmask];
 131}
 132
 133void
 134procfs_hashrem(struct pfsnode *pfs)
 135{
 136
 137 mutex_enter(&procfs_hashlock);
 138 LIST_REMOVE(pfs, pfs_hash);
 139 mutex_exit(&procfs_hashlock);
 140}
114 141
115/* 142/*
116 * VFS Operations. 143 * VFS Operations.
117 * 144 *
118 * mount system call 145 * mount system call
119 */ 146 */
120/* ARGSUSED */ 147/* ARGSUSED */
121int 148int
122procfs_mount( 149procfs_mount(
123 struct mount *mp, 150 struct mount *mp,
124 const char *path, 151 const char *path,
125 void *data, 152 void *data,
126 size_t *data_len) 153 size_t *data_len)
@@ -156,53 +183,50 @@ procfs_mount( @@ -156,53 +183,50 @@ procfs_mount(
156 183
157 if (*data_len >= sizeof *args && args->version != PROCFS_ARGSVERSION) 184 if (*data_len >= sizeof *args && args->version != PROCFS_ARGSVERSION)
158 return EINVAL; 185 return EINVAL;
159 186
160 pmnt = kmem_zalloc(sizeof(struct procfsmount), KM_SLEEP); 187 pmnt = kmem_zalloc(sizeof(struct procfsmount), KM_SLEEP);
161 188
162 mp->mnt_stat.f_namemax = PROCFS_MAXNAMLEN; 189 mp->mnt_stat.f_namemax = PROCFS_MAXNAMLEN;
163 mp->mnt_flag |= MNT_LOCAL; 190 mp->mnt_flag |= MNT_LOCAL;
164 mp->mnt_data = pmnt; 191 mp->mnt_data = pmnt;
165 vfs_getnewfsid(mp); 192 vfs_getnewfsid(mp);
166 193
167 error = set_statvfs_info(path, UIO_USERSPACE, "procfs", UIO_SYSSPACE, 194 error = set_statvfs_info(path, UIO_USERSPACE, "procfs", UIO_SYSSPACE,
168 mp->mnt_op->vfs_name, mp, l); 195 mp->mnt_op->vfs_name, mp, l);
169 pmnt->pmnt_exechook = exechook_establish(procfs_revoke_vnodes, mp); 
170 if (*data_len >= sizeof *args) 196 if (*data_len >= sizeof *args)
171 pmnt->pmnt_flags = args->flags; 197 pmnt->pmnt_flags = args->flags;
172 else 198 else
173 pmnt->pmnt_flags = 0; 199 pmnt->pmnt_flags = 0;
174 200
175 mp->mnt_iflag |= IMNT_MPSAFE | IMNT_SHRLOOKUP; 201 mp->mnt_iflag |= IMNT_MPSAFE | IMNT_SHRLOOKUP;
176 return error; 202 return error;
177} 203}
178 204
179/* 205/*
180 * unmount system call 206 * unmount system call
181 */ 207 */
182int 208int
183procfs_unmount(struct mount *mp, int mntflags) 209procfs_unmount(struct mount *mp, int mntflags)
184{ 210{
185 int error; 211 int error;
186 int flags = 0; 212 int flags = 0;
187 213
188 if (mntflags & MNT_FORCE) 214 if (mntflags & MNT_FORCE)
189 flags |= FORCECLOSE; 215 flags |= FORCECLOSE;
190 216
191 if ((error = vflush(mp, 0, flags)) != 0) 217 if ((error = vflush(mp, 0, flags)) != 0)
192 return (error); 218 return (error);
193 219
194 exechook_disestablish(VFSTOPROC(mp)->pmnt_exechook); 
195 
196 kmem_free(mp->mnt_data, sizeof(struct procfsmount)); 220 kmem_free(mp->mnt_data, sizeof(struct procfsmount));
197 mp->mnt_data = NULL; 221 mp->mnt_data = NULL;
198 222
199 return 0; 223 return 0;
200} 224}
201 225
202int 226int
203procfs_root(struct mount *mp, int lktype, struct vnode **vpp) 227procfs_root(struct mount *mp, int lktype, struct vnode **vpp)
204{ 228{
205 int error; 229 int error;
206 230
207 error = procfs_allocvp(mp, vpp, 0, PFSroot, -1); 231 error = procfs_allocvp(mp, vpp, 0, PFSroot, -1);
208 if (error == 0) { 232 if (error == 0) {
@@ -269,26 +293,27 @@ procfs_loadvnode(struct mount *mp, struc @@ -269,26 +293,27 @@ procfs_loadvnode(struct mount *mp, struc
269{ 293{
270 int error; 294 int error;
271 struct pfskey pfskey; 295 struct pfskey pfskey;
272 struct pfsnode *pfs; 296 struct pfsnode *pfs;
273 297
274 KASSERT(key_len == sizeof(pfskey)); 298 KASSERT(key_len == sizeof(pfskey));
275 memcpy(&pfskey, key, key_len); 299 memcpy(&pfskey, key, key_len);
276 300
277 pfs = kmem_alloc(sizeof(*pfs), KM_SLEEP); 301 pfs = kmem_alloc(sizeof(*pfs), KM_SLEEP);
278 pfs->pfs_pid = pfskey.pk_pid; 302 pfs->pfs_pid = pfskey.pk_pid;
279 pfs->pfs_type = pfskey.pk_type; 303 pfs->pfs_type = pfskey.pk_type;
280 pfs->pfs_fd = pfskey.pk_fd; 304 pfs->pfs_fd = pfskey.pk_fd;
281 pfs->pfs_vnode = vp; 305 pfs->pfs_vnode = vp;
 306 pfs->pfs_mount = mp;
282 pfs->pfs_flags = 0; 307 pfs->pfs_flags = 0;
283 pfs->pfs_fileno = 308 pfs->pfs_fileno =
284 PROCFS_FILENO(pfs->pfs_pid, pfs->pfs_type, pfs->pfs_fd); 309 PROCFS_FILENO(pfs->pfs_pid, pfs->pfs_type, pfs->pfs_fd);
285 vp->v_tag = VT_PROCFS; 310 vp->v_tag = VT_PROCFS;
286 vp->v_op = procfs_vnodeop_p; 311 vp->v_op = procfs_vnodeop_p;
287 vp->v_data = pfs; 312 vp->v_data = pfs;
288 313
289 switch (pfs->pfs_type) { 314 switch (pfs->pfs_type) {
290 case PFSroot: /* /proc = dr-xr-xr-x */ 315 case PFSroot: /* /proc = dr-xr-xr-x */
291 vp->v_vflag |= VV_ROOT; 316 vp->v_vflag |= VV_ROOT;
292 /*FALLTHROUGH*/ 317 /*FALLTHROUGH*/
293 case PFSproc: /* /proc/N = dr-xr-xr-x */ 318 case PFSproc: /* /proc/N = dr-xr-xr-x */
294 pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH; 319 pfs->pfs_mode = S_IRUSR|S_IXUSR|S_IRGRP|S_IXGRP|S_IROTH|S_IXOTH;
@@ -411,26 +436,30 @@ procfs_loadvnode(struct mount *mp, struc @@ -411,26 +436,30 @@ procfs_loadvnode(struct mount *mp, struc
411 vp->v_type = VREG; 436 vp->v_type = VREG;
412 break; 437 break;
413 438
414#ifdef __HAVE_PROCFS_MACHDEP 439#ifdef __HAVE_PROCFS_MACHDEP
415 PROCFS_MACHDEP_NODETYPE_CASES 440 PROCFS_MACHDEP_NODETYPE_CASES
416 procfs_machdep_allocvp(vp); 441 procfs_machdep_allocvp(vp);
417 break; 442 break;
418#endif 443#endif
419 444
420 default: 445 default:
421 panic("procfs_allocvp"); 446 panic("procfs_allocvp");
422 } 447 }
423 448
 449 mutex_enter(&procfs_hashlock);
 450 LIST_INSERT_HEAD(procfs_hashhead(pfs->pfs_pid), pfs, pfs_hash);
 451 mutex_exit(&procfs_hashlock);
 452
424 uvm_vnp_setsize(vp, 0); 453 uvm_vnp_setsize(vp, 0);
425 *new_key = &pfs->pfs_key; 454 *new_key = &pfs->pfs_key;
426 455
427 return 0; 456 return 0;
428 457
429bad: 458bad:
430 vp->v_tag =VT_NON; 459 vp->v_tag =VT_NON;
431 vp->v_type = VNON; 460 vp->v_type = VNON;
432 vp->v_op = NULL; 461 vp->v_op = NULL;
433 vp->v_data = NULL; 462 vp->v_data = NULL;
434 kmem_free(pfs, sizeof(*pfs)); 463 kmem_free(pfs, sizeof(*pfs));
435 return error; 464 return error;
436} 465}
@@ -476,26 +505,68 @@ struct vfsops procfs_vfsops = { @@ -476,26 +505,68 @@ struct vfsops procfs_vfsops = {
476 .vfs_vptofh = (void *)eopnotsupp, 505 .vfs_vptofh = (void *)eopnotsupp,
477 .vfs_init = procfs_init, 506 .vfs_init = procfs_init,
478 .vfs_reinit = procfs_reinit, 507 .vfs_reinit = procfs_reinit,
479 .vfs_done = procfs_done, 508 .vfs_done = procfs_done,
480 .vfs_snapshot = (void *)eopnotsupp, 509 .vfs_snapshot = (void *)eopnotsupp,
481 .vfs_extattrctl = vfs_stdextattrctl, 510 .vfs_extattrctl = vfs_stdextattrctl,
482 .vfs_suspendctl = genfs_suspendctl, 511 .vfs_suspendctl = genfs_suspendctl,
483 .vfs_renamelock_enter = genfs_renamelock_enter, 512 .vfs_renamelock_enter = genfs_renamelock_enter,
484 .vfs_renamelock_exit = genfs_renamelock_exit, 513 .vfs_renamelock_exit = genfs_renamelock_exit,
485 .vfs_fsync = (void *)eopnotsupp, 514 .vfs_fsync = (void *)eopnotsupp,
486 .vfs_opv_descs = procfs_vnodeopv_descs 515 .vfs_opv_descs = procfs_vnodeopv_descs
487}; 516};
488 517
 518static void
 519procfs_exechook_cb(struct proc *p, void *arg)
 520{
 521 struct hashhead *head;
 522 struct pfsnode *pfs;
 523 struct mount *mp;
 524 struct pfskey key;
 525 struct vnode *vp;
 526 int error;
 527
 528 if (arg == PROCFS_EXEC_HOOK && !(p->p_flag & PK_SUGID))
 529 return;
 530
 531 head = procfs_hashhead(p->p_pid);
 532
 533again:
 534 mutex_enter(&procfs_hashlock);
 535 LIST_FOREACH(pfs, head, pfs_hash) {
 536 if (pfs->pfs_pid != p->p_pid)
 537 continue;
 538 mp = pfs->pfs_mount;
 539 key = pfs->pfs_key;
 540 vfs_ref(mp);
 541 mutex_exit(&procfs_hashlock);
 542
 543 error = vcache_get(mp, &key, sizeof(key), &vp);
 544 vfs_rele(mp);
 545 if (error != 0)
 546 goto again;
 547 if (vrecycle(vp))
 548 goto again;
 549 do {
 550 error = vfs_suspend(mp, 0);
 551 } while (error == EINTR || error == ERESTART);
 552 vgone(vp);
 553 if (error == 0)
 554 vfs_resume(mp);
 555 goto again;
 556 }
 557 mutex_exit(&procfs_hashlock);
 558}
 559
489static int 560static int
490procfs_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie, 561procfs_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
491 void *arg0, void *arg1, void *arg2, void *arg3) 562 void *arg0, void *arg1, void *arg2, void *arg3)
492{ 563{
493 struct proc *p; 564 struct proc *p;
494 struct pfsnode *pfs; 565 struct pfsnode *pfs;
495 int result; 566 int result;
496 567
497 result = KAUTH_RESULT_DEFER; 568 result = KAUTH_RESULT_DEFER;
498 p = arg0; 569 p = arg0;
499 pfs = arg1; 570 pfs = arg1;
500 571
501 if (action != KAUTH_PROCESS_PROCFS) 572 if (action != KAUTH_PROCESS_PROCFS)
@@ -538,27 +609,40 @@ static int @@ -538,27 +609,40 @@ static int
538procfs_modcmd(modcmd_t cmd, void *arg) 609procfs_modcmd(modcmd_t cmd, void *arg)
539{ 610{
540 int error; 611 int error;
541 612
542 switch (cmd) { 613 switch (cmd) {
543 case MODULE_CMD_INIT: 614 case MODULE_CMD_INIT:
544 error = vfs_attach(&procfs_vfsops); 615 error = vfs_attach(&procfs_vfsops);
545 if (error != 0) 616 if (error != 0)
546 break; 617 break;
547 618
548 procfs_listener = kauth_listen_scope(KAUTH_SCOPE_PROCESS, 619 procfs_listener = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
549 procfs_listener_cb, NULL); 620 procfs_listener_cb, NULL);
550 621
 622 procfs_exechook = exechook_establish(procfs_exechook_cb,
 623 PROCFS_EXEC_HOOK);
 624 procfs_exithook = exithook_establish(procfs_exechook_cb,
 625 PROCFS_EXIT_HOOK);
 626
 627 mutex_init(&procfs_hashlock, MUTEX_DEFAULT, IPL_NONE);
 628 procfs_hashtab = hashinit(PROCFS_HASHSIZE, HASH_LIST, true,
 629 &procfs_hashmask);
 630
551 break; 631 break;
552 case MODULE_CMD_FINI: 632 case MODULE_CMD_FINI:
553 error = vfs_detach(&procfs_vfsops); 633 error = vfs_detach(&procfs_vfsops);
554 if (error != 0) 634 if (error != 0)
555 break; 635 break;
556 kauth_unlisten_scope(procfs_listener); 636 kauth_unlisten_scope(procfs_listener);
 637 exechook_disestablish(procfs_exechook);
 638 exithook_disestablish(procfs_exithook);
 639 mutex_destroy(&procfs_hashlock);
 640 hashdone(procfs_hashtab, HASH_LIST, procfs_hashmask);
557 break; 641 break;
558 default: 642 default:
559 error = ENOTTY; 643 error = ENOTTY;
560 break; 644 break;
561 } 645 }
562 646
563 return (error); 647 return (error);
564} 648}

cvs diff -r1.229 -r1.229.4.1 src/sys/miscfs/procfs/procfs_vnops.c (expand / switch to unified diff)

--- src/sys/miscfs/procfs/procfs_vnops.c 2022/06/17 14:30:37 1.229
+++ src/sys/miscfs/procfs/procfs_vnops.c 2024/04/18 18:22:10 1.229.4.1
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: procfs_vnops.c,v 1.229 2022/06/17 14:30:37 shm Exp $ */ 1/* $NetBSD: procfs_vnops.c,v 1.229.4.1 2024/04/18 18:22:10 martin Exp $ */
2 2
3/*- 3/*-
4 * Copyright (c) 2006, 2007, 2008, 2020 The NetBSD Foundation, Inc. 4 * Copyright (c) 2006, 2007, 2008, 2020 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Andrew Doran. 8 * by Andrew Doran.
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -95,27 +95,27 @@ @@ -95,27 +95,27 @@
95 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 95 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
96 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 96 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
97 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 97 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
98 * SUCH DAMAGE. 98 * SUCH DAMAGE.
99 * 99 *
100 * @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95 100 * @(#)procfs_vnops.c 8.18 (Berkeley) 5/21/95
101 */ 101 */
102 102
103/* 103/*
104 * procfs vnode interface 104 * procfs vnode interface
105 */ 105 */
106 106
107#include <sys/cdefs.h> 107#include <sys/cdefs.h>
108__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.229 2022/06/17 14:30:37 shm Exp $"); 108__KERNEL_RCSID(0, "$NetBSD: procfs_vnops.c,v 1.229.4.1 2024/04/18 18:22:10 martin Exp $");
109 109
110#include <sys/param.h> 110#include <sys/param.h>
111#include <sys/atomic.h> 111#include <sys/atomic.h>
112#include <sys/systm.h> 112#include <sys/systm.h>
113#include <sys/time.h> 113#include <sys/time.h>
114#include <sys/kernel.h> 114#include <sys/kernel.h>
115#include <sys/file.h> 115#include <sys/file.h>
116#include <sys/filedesc.h> 116#include <sys/filedesc.h>
117#include <sys/proc.h> 117#include <sys/proc.h>
118#include <sys/vnode.h> 118#include <sys/vnode.h>
119#include <sys/namei.h> 119#include <sys/namei.h>
120#include <sys/malloc.h> 120#include <sys/malloc.h>
121#include <sys/mount.h> 121#include <sys/mount.h>
@@ -427,26 +427,27 @@ procfs_reclaim(void *v) @@ -427,26 +427,27 @@ procfs_reclaim(void *v)
427 struct vnode *a_vp; 427 struct vnode *a_vp;
428 } */ *ap = v; 428 } */ *ap = v;
429 struct vnode *vp = ap->a_vp; 429 struct vnode *vp = ap->a_vp;
430 struct pfsnode *pfs = VTOPFS(vp); 430 struct pfsnode *pfs = VTOPFS(vp);
431 431
432 VOP_UNLOCK(vp); 432 VOP_UNLOCK(vp);
433 433
434 /* 434 /*
435 * To interlock with procfs_revoke_vnodes(). 435 * To interlock with procfs_revoke_vnodes().
436 */ 436 */
437 mutex_enter(vp->v_interlock); 437 mutex_enter(vp->v_interlock);
438 vp->v_data = NULL; 438 vp->v_data = NULL;
439 mutex_exit(vp->v_interlock); 439 mutex_exit(vp->v_interlock);
 440 procfs_hashrem(pfs);
440 kmem_free(pfs, sizeof(*pfs)); 441 kmem_free(pfs, sizeof(*pfs));
441 return 0; 442 return 0;
442} 443}
443 444
444/* 445/*
445 * Return POSIX pathconf information applicable to special devices. 446 * Return POSIX pathconf information applicable to special devices.
446 */ 447 */
447int 448int
448procfs_pathconf(void *v) 449procfs_pathconf(void *v)
449{ 450{
450 struct vop_pathconf_args /* { 451 struct vop_pathconf_args /* {
451 struct vnode *a_vp; 452 struct vnode *a_vp;
452 int a_name; 453 int a_name;