Fri Oct 2 21:47:35 2009 UTC ()
Move ktrace's subsystem security policy to the subsystem itself, and keep
just the suser-related logic in the suser secmodel.


(elad)
diff -r1.149 -r1.150 src/sys/kern/kern_ktrace.c
diff -r1.1 -r1.2 src/sys/secmodel/suser/secmodel_suser.c

cvs diff -r1.149 -r1.150 src/sys/kern/kern_ktrace.c (switch to unified diff)

--- src/sys/kern/kern_ktrace.c 2009/08/05 19:53:42 1.149
+++ src/sys/kern/kern_ktrace.c 2009/10/02 21:47:35 1.150
@@ -1,1248 +1,1286 @@ @@ -1,1248 +1,1286 @@
1/* $NetBSD: kern_ktrace.c,v 1.149 2009/08/05 19:53:42 dsl Exp $ */ 1/* $NetBSD: kern_ktrace.c,v 1.150 2009/10/02 21:47:35 elad 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.
15 * 2. Redistributions in binary form must reproduce the above copyright 15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the 16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution. 17 * documentation and/or other materials provided with the distribution.
18 * 18 *
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS 19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED 20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31 31
32/* 32/*
33 * Copyright (c) 1989, 1993 33 * Copyright (c) 1989, 1993
34 * The Regents of the University of California. All rights reserved. 34 * The Regents of the University of California. All rights reserved.
35 * 35 *
36 * Redistribution and use in source and binary forms, with or without 36 * Redistribution and use in source and binary forms, with or without
37 * modification, are permitted provided that the following conditions 37 * modification, are permitted provided that the following conditions
38 * are met: 38 * are met:
39 * 1. Redistributions of source code must retain the above copyright 39 * 1. Redistributions of source code must retain the above copyright
40 * notice, this list of conditions and the following disclaimer. 40 * notice, this list of conditions and the following disclaimer.
41 * 2. Redistributions in binary form must reproduce the above copyright 41 * 2. Redistributions in binary form must reproduce the above copyright
42 * notice, this list of conditions and the following disclaimer in the 42 * notice, this list of conditions and the following disclaimer in the
43 * documentation and/or other materials provided with the distribution. 43 * documentation and/or other materials provided with the distribution.
44 * 3. Neither the name of the University nor the names of its contributors 44 * 3. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software 45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission. 46 * without specific prior written permission.
47 * 47 *
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
58 * SUCH DAMAGE. 58 * SUCH DAMAGE.
59 * 59 *
60 * @(#)kern_ktrace.c 8.5 (Berkeley) 5/14/95 60 * @(#)kern_ktrace.c 8.5 (Berkeley) 5/14/95
61 */ 61 */
62 62
63#include <sys/cdefs.h> 63#include <sys/cdefs.h>
64__KERNEL_RCSID(0, "$NetBSD: kern_ktrace.c,v 1.149 2009/08/05 19:53:42 dsl Exp $"); 64__KERNEL_RCSID(0, "$NetBSD: kern_ktrace.c,v 1.150 2009/10/02 21:47:35 elad Exp $");
65 65
66#include <sys/param.h> 66#include <sys/param.h>
67#include <sys/systm.h> 67#include <sys/systm.h>
68#include <sys/proc.h> 68#include <sys/proc.h>
69#include <sys/file.h> 69#include <sys/file.h>
70#include <sys/namei.h> 70#include <sys/namei.h>
71#include <sys/vnode.h> 71#include <sys/vnode.h>
72#include <sys/kernel.h> 72#include <sys/kernel.h>
73#include <sys/kthread.h> 73#include <sys/kthread.h>
74#include <sys/ktrace.h> 74#include <sys/ktrace.h>
75#include <sys/kmem.h> 75#include <sys/kmem.h>
76#include <sys/syslog.h> 76#include <sys/syslog.h>
77#include <sys/filedesc.h> 77#include <sys/filedesc.h>
78#include <sys/ioctl.h> 78#include <sys/ioctl.h>
79#include <sys/callout.h> 79#include <sys/callout.h>
80#include <sys/kauth.h> 80#include <sys/kauth.h>
81 81
82#include <sys/mount.h> 82#include <sys/mount.h>
83#include <sys/sa.h> 83#include <sys/sa.h>
84#include <sys/syscallargs.h> 84#include <sys/syscallargs.h>
85 85
86/* 86/*
87 * TODO: 87 * TODO:
88 * - need better error reporting? 88 * - need better error reporting?
89 * - userland utility to sort ktrace.out by timestamp. 89 * - userland utility to sort ktrace.out by timestamp.
90 * - keep minimum information in ktrace_entry when rest of alloc failed. 90 * - keep minimum information in ktrace_entry when rest of alloc failed.
91 * - per trace control of configurable parameters. 91 * - per trace control of configurable parameters.
92 */ 92 */
93 93
94struct ktrace_entry { 94struct ktrace_entry {
95 TAILQ_ENTRY(ktrace_entry) kte_list; 95 TAILQ_ENTRY(ktrace_entry) kte_list;
96 struct ktr_header kte_kth; 96 struct ktr_header kte_kth;
97 void *kte_buf; 97 void *kte_buf;
98 size_t kte_bufsz;  98 size_t kte_bufsz;
99#define KTE_SPACE 32 99#define KTE_SPACE 32
100 uint8_t kte_space[KTE_SPACE]; 100 uint8_t kte_space[KTE_SPACE];
101}; 101};
102 102
103struct ktr_desc { 103struct ktr_desc {
104 TAILQ_ENTRY(ktr_desc) ktd_list; 104 TAILQ_ENTRY(ktr_desc) ktd_list;
105 int ktd_flags; 105 int ktd_flags;
106#define KTDF_WAIT 0x0001 106#define KTDF_WAIT 0x0001
107#define KTDF_DONE 0x0002 107#define KTDF_DONE 0x0002
108#define KTDF_BLOCKING 0x0004 108#define KTDF_BLOCKING 0x0004
109#define KTDF_INTERACTIVE 0x0008 109#define KTDF_INTERACTIVE 0x0008
110 int ktd_error; 110 int ktd_error;
111#define KTDE_ENOMEM 0x0001 111#define KTDE_ENOMEM 0x0001
112#define KTDE_ENOSPC 0x0002 112#define KTDE_ENOSPC 0x0002
113 int ktd_errcnt; 113 int ktd_errcnt;
114 int ktd_ref; /* # of reference */ 114 int ktd_ref; /* # of reference */
115 int ktd_qcount; /* # of entry in the queue */ 115 int ktd_qcount; /* # of entry in the queue */
116 116
117 /* 117 /*
118 * Params to control behaviour. 118 * Params to control behaviour.
119 */ 119 */
120 int ktd_delayqcnt; /* # of entry allowed to delay */ 120 int ktd_delayqcnt; /* # of entry allowed to delay */
121 int ktd_wakedelay; /* delay of wakeup in *tick* */ 121 int ktd_wakedelay; /* delay of wakeup in *tick* */
122 int ktd_intrwakdl; /* ditto, but when interactive */ 122 int ktd_intrwakdl; /* ditto, but when interactive */
123 123
124 file_t *ktd_fp; /* trace output file */ 124 file_t *ktd_fp; /* trace output file */
125 lwp_t *ktd_lwp; /* our kernel thread */ 125 lwp_t *ktd_lwp; /* our kernel thread */
126 TAILQ_HEAD(, ktrace_entry) ktd_queue; 126 TAILQ_HEAD(, ktrace_entry) ktd_queue;
127 callout_t ktd_wakch; /* delayed wakeup */ 127 callout_t ktd_wakch; /* delayed wakeup */
128 kcondvar_t ktd_sync_cv; 128 kcondvar_t ktd_sync_cv;
129 kcondvar_t ktd_cv; 129 kcondvar_t ktd_cv;
130}; 130};
131 131
132static int ktealloc(struct ktrace_entry **, void **, lwp_t *, int, 132static int ktealloc(struct ktrace_entry **, void **, lwp_t *, int,
133 size_t); 133 size_t);
134static void ktrwrite(struct ktr_desc *, struct ktrace_entry *); 134static void ktrwrite(struct ktr_desc *, struct ktrace_entry *);
135static int ktrace_common(lwp_t *, int, int, int, file_t *); 135static int ktrace_common(lwp_t *, int, int, int, file_t *);
136static int ktrops(lwp_t *, struct proc *, int, int, 136static int ktrops(lwp_t *, struct proc *, int, int,
137 struct ktr_desc *); 137 struct ktr_desc *);
138static int ktrsetchildren(lwp_t *, struct proc *, int, int, 138static int ktrsetchildren(lwp_t *, struct proc *, int, int,
139 struct ktr_desc *); 139 struct ktr_desc *);
140static int ktrcanset(lwp_t *, struct proc *); 140static int ktrcanset(lwp_t *, struct proc *);
141static int ktrsamefile(file_t *, file_t *); 141static int ktrsamefile(file_t *, file_t *);
142static void ktr_kmem(lwp_t *, int, const void *, size_t); 142static void ktr_kmem(lwp_t *, int, const void *, size_t);
143static void ktr_io(lwp_t *, int, enum uio_rw, struct iovec *, size_t); 143static void ktr_io(lwp_t *, int, enum uio_rw, struct iovec *, size_t);
144 144
145static struct ktr_desc * 145static struct ktr_desc *
146 ktd_lookup(file_t *); 146 ktd_lookup(file_t *);
147static void ktdrel(struct ktr_desc *); 147static void ktdrel(struct ktr_desc *);
148static void ktdref(struct ktr_desc *); 148static void ktdref(struct ktr_desc *);
149static void ktraddentry(lwp_t *, struct ktrace_entry *, int); 149static void ktraddentry(lwp_t *, struct ktrace_entry *, int);
150/* Flags for ktraddentry (3rd arg) */ 150/* Flags for ktraddentry (3rd arg) */
151#define KTA_NOWAIT 0x0000 151#define KTA_NOWAIT 0x0000
152#define KTA_WAITOK 0x0001 152#define KTA_WAITOK 0x0001
153#define KTA_LARGE 0x0002 153#define KTA_LARGE 0x0002
154static void ktefree(struct ktrace_entry *); 154static void ktefree(struct ktrace_entry *);
155static void ktd_logerrl(struct ktr_desc *, int); 155static void ktd_logerrl(struct ktr_desc *, int);
156static void ktrace_thread(void *); 156static void ktrace_thread(void *);
157static int ktrderefall(struct ktr_desc *, int); 157static int ktrderefall(struct ktr_desc *, int);
158 158
159/* 159/*
160 * Default vaules. 160 * Default vaules.
161 */ 161 */
162#define KTD_MAXENTRY 1000 /* XXX: tune */ 162#define KTD_MAXENTRY 1000 /* XXX: tune */
163#define KTD_TIMEOUT 5 /* XXX: tune */ 163#define KTD_TIMEOUT 5 /* XXX: tune */
164#define KTD_DELAYQCNT 100 /* XXX: tune */ 164#define KTD_DELAYQCNT 100 /* XXX: tune */
165#define KTD_WAKEDELAY 5000 /* XXX: tune */ 165#define KTD_WAKEDELAY 5000 /* XXX: tune */
166#define KTD_INTRWAKDL 100 /* XXX: tune */ 166#define KTD_INTRWAKDL 100 /* XXX: tune */
167 167
168/* 168/*
169 * Patchable variables. 169 * Patchable variables.
170 */ 170 */
171int ktd_maxentry = KTD_MAXENTRY; /* max # of entry in the queue */ 171int ktd_maxentry = KTD_MAXENTRY; /* max # of entry in the queue */
172int ktd_timeout = KTD_TIMEOUT; /* timeout in seconds */ 172int ktd_timeout = KTD_TIMEOUT; /* timeout in seconds */
173int ktd_delayqcnt = KTD_DELAYQCNT; /* # of entry allowed to delay */ 173int ktd_delayqcnt = KTD_DELAYQCNT; /* # of entry allowed to delay */
174int ktd_wakedelay = KTD_WAKEDELAY; /* delay of wakeup in *ms* */ 174int ktd_wakedelay = KTD_WAKEDELAY; /* delay of wakeup in *ms* */
175int ktd_intrwakdl = KTD_INTRWAKDL; /* ditto, but when interactive */ 175int ktd_intrwakdl = KTD_INTRWAKDL; /* ditto, but when interactive */
176 176
177kmutex_t ktrace_lock; 177kmutex_t ktrace_lock;
178int ktrace_on; 178int ktrace_on;
179static TAILQ_HEAD(, ktr_desc) ktdq = TAILQ_HEAD_INITIALIZER(ktdq); 179static TAILQ_HEAD(, ktr_desc) ktdq = TAILQ_HEAD_INITIALIZER(ktdq);
180static pool_cache_t kte_cache; 180static pool_cache_t kte_cache;
181 181
 182static kauth_listener_t ktrace_listener;
 183
182static void 184static void
183ktd_wakeup(struct ktr_desc *ktd) 185ktd_wakeup(struct ktr_desc *ktd)
184{ 186{
185 187
186 callout_stop(&ktd->ktd_wakch); 188 callout_stop(&ktd->ktd_wakch);
187 cv_signal(&ktd->ktd_cv); 189 cv_signal(&ktd->ktd_cv);
188} 190}
189 191
190static void 192static void
191ktd_callout(void *arg) 193ktd_callout(void *arg)
192{ 194{
193 195
194 mutex_enter(&ktrace_lock); 196 mutex_enter(&ktrace_lock);
195 ktd_wakeup(arg); 197 ktd_wakeup(arg);
196 mutex_exit(&ktrace_lock); 198 mutex_exit(&ktrace_lock);
197} 199}
198 200
199static void 201static void
200ktd_logerrl(struct ktr_desc *ktd, int error) 202ktd_logerrl(struct ktr_desc *ktd, int error)
201{ 203{
202 204
203 ktd->ktd_error |= error; 205 ktd->ktd_error |= error;
204 ktd->ktd_errcnt++; 206 ktd->ktd_errcnt++;
205} 207}
206 208
207#if 0 209#if 0
208static void 210static void
209ktd_logerr(struct proc *p, int error) 211ktd_logerr(struct proc *p, int error)
210{ 212{
211 struct ktr_desc *ktd; 213 struct ktr_desc *ktd;
212 214
213 KASSERT(mutex_owned(&ktrace_lock)); 215 KASSERT(mutex_owned(&ktrace_lock));
214 216
215 ktd = p->p_tracep; 217 ktd = p->p_tracep;
216 if (ktd == NULL) 218 if (ktd == NULL)
217 return; 219 return;
218 220
219 ktd_logerrl(ktd, error); 221 ktd_logerrl(ktd, error);
220} 222}
221#endif 223#endif
222 224
223static inline int 225static inline int
224ktrenter(lwp_t *l) 226ktrenter(lwp_t *l)
225{ 227{
226 228
227 if ((l->l_pflag & LP_KTRACTIVE) != 0) 229 if ((l->l_pflag & LP_KTRACTIVE) != 0)
228 return 1; 230 return 1;
229 l->l_pflag |= LP_KTRACTIVE; 231 l->l_pflag |= LP_KTRACTIVE;
230 return 0; 232 return 0;
231} 233}
232 234
233static inline void 235static inline void
234ktrexit(lwp_t *l) 236ktrexit(lwp_t *l)
235{ 237{
236 238
237 l->l_pflag &= ~LP_KTRACTIVE; 239 l->l_pflag &= ~LP_KTRACTIVE;
238} 240}
239 241
 242static int
 243ktrace_listener_cb(kauth_cred_t cred, kauth_action_t action, void *cookie,
 244 void *arg0, void *arg1, void *arg2, void *arg3)
 245{
 246 struct proc *p;
 247 int result;
 248 enum kauth_process_req req;
 249
 250 result = KAUTH_RESULT_DEFER;
 251 p = arg0;
 252
 253 if (action != KAUTH_PROCESS_KTRACE)
 254 return result;
 255
 256 req = (enum kauth_process_req)(unsigned long)arg1;
 257
 258 /* Privileged; secmodel should handle these. */
 259 if (req == KAUTH_REQ_PROCESS_KTRACE_PERSISTENT)
 260 return result;
 261
 262 if ((p->p_traceflag & KTRFAC_PERSISTENT) ||
 263 (p->p_flag & PK_SUGID))
 264 return result;
 265
 266 if (kauth_cred_geteuid(cred) == kauth_cred_getuid(p->p_cred) &&
 267 kauth_cred_getuid(cred) == kauth_cred_getsvuid(p->p_cred) &&
 268 kauth_cred_getgid(cred) == kauth_cred_getgid(p->p_cred) &&
 269 kauth_cred_getgid(cred) == kauth_cred_getsvgid(p->p_cred))
 270 result = KAUTH_RESULT_ALLOW;
 271
 272 return result;
 273}
 274
240/* 275/*
241 * Initialise the ktrace system. 276 * Initialise the ktrace system.
242 */ 277 */
243void 278void
244ktrinit(void) 279ktrinit(void)
245{ 280{
246 281
247 mutex_init(&ktrace_lock, MUTEX_DEFAULT, IPL_NONE); 282 mutex_init(&ktrace_lock, MUTEX_DEFAULT, IPL_NONE);
248 kte_cache = pool_cache_init(sizeof(struct ktrace_entry), 0, 0, 0, 283 kte_cache = pool_cache_init(sizeof(struct ktrace_entry), 0, 0, 0,
249 "ktrace", &pool_allocator_nointr, IPL_NONE, NULL, NULL, NULL); 284 "ktrace", &pool_allocator_nointr, IPL_NONE, NULL, NULL, NULL);
 285
 286 ktrace_listener = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
 287 ktrace_listener_cb, NULL);
250} 288}
251 289
252/* 290/*
253 * Release a reference. Called with ktrace_lock held. 291 * Release a reference. Called with ktrace_lock held.
254 */ 292 */
255void 293void
256ktdrel(struct ktr_desc *ktd) 294ktdrel(struct ktr_desc *ktd)
257{ 295{
258 296
259 KASSERT(mutex_owned(&ktrace_lock)); 297 KASSERT(mutex_owned(&ktrace_lock));
260 298
261 KDASSERT(ktd->ktd_ref != 0); 299 KDASSERT(ktd->ktd_ref != 0);
262 KASSERT(ktd->ktd_ref > 0); 300 KASSERT(ktd->ktd_ref > 0);
263 KASSERT(ktrace_on > 0); 301 KASSERT(ktrace_on > 0);
264 ktrace_on--; 302 ktrace_on--;
265 if (--ktd->ktd_ref <= 0) { 303 if (--ktd->ktd_ref <= 0) {
266 ktd->ktd_flags |= KTDF_DONE; 304 ktd->ktd_flags |= KTDF_DONE;
267 cv_signal(&ktd->ktd_cv); 305 cv_signal(&ktd->ktd_cv);
268 } 306 }
269} 307}
270 308
271void 309void
272ktdref(struct ktr_desc *ktd) 310ktdref(struct ktr_desc *ktd)
273{ 311{
274 312
275 KASSERT(mutex_owned(&ktrace_lock)); 313 KASSERT(mutex_owned(&ktrace_lock));
276 314
277 ktd->ktd_ref++; 315 ktd->ktd_ref++;
278 ktrace_on++; 316 ktrace_on++;
279} 317}
280 318
281struct ktr_desc * 319struct ktr_desc *
282ktd_lookup(file_t *fp) 320ktd_lookup(file_t *fp)
283{ 321{
284 struct ktr_desc *ktd; 322 struct ktr_desc *ktd;
285 323
286 KASSERT(mutex_owned(&ktrace_lock)); 324 KASSERT(mutex_owned(&ktrace_lock));
287 325
288 for (ktd = TAILQ_FIRST(&ktdq); ktd != NULL; 326 for (ktd = TAILQ_FIRST(&ktdq); ktd != NULL;
289 ktd = TAILQ_NEXT(ktd, ktd_list)) { 327 ktd = TAILQ_NEXT(ktd, ktd_list)) {
290 if (ktrsamefile(ktd->ktd_fp, fp)) { 328 if (ktrsamefile(ktd->ktd_fp, fp)) {
291 ktdref(ktd); 329 ktdref(ktd);
292 break; 330 break;
293 } 331 }
294 } 332 }
295 333
296 return (ktd); 334 return (ktd);
297} 335}
298 336
299void 337void
300ktraddentry(lwp_t *l, struct ktrace_entry *kte, int flags) 338ktraddentry(lwp_t *l, struct ktrace_entry *kte, int flags)
301{ 339{
302 struct proc *p = l->l_proc; 340 struct proc *p = l->l_proc;
303 struct ktr_desc *ktd; 341 struct ktr_desc *ktd;
304#ifdef DEBUG 342#ifdef DEBUG
305 struct timeval t1, t2; 343 struct timeval t1, t2;
306#endif 344#endif
307 345
308 mutex_enter(&ktrace_lock); 346 mutex_enter(&ktrace_lock);
309 347
310 if (p->p_traceflag & KTRFAC_TRC_EMUL) { 348 if (p->p_traceflag & KTRFAC_TRC_EMUL) {
311 /* Add emulation trace before first entry for this process */ 349 /* Add emulation trace before first entry for this process */
312 p->p_traceflag &= ~KTRFAC_TRC_EMUL; 350 p->p_traceflag &= ~KTRFAC_TRC_EMUL;
313 mutex_exit(&ktrace_lock); 351 mutex_exit(&ktrace_lock);
314 ktrexit(l); 352 ktrexit(l);
315 ktremul(); 353 ktremul();
316 (void)ktrenter(l); 354 (void)ktrenter(l);
317 mutex_enter(&ktrace_lock); 355 mutex_enter(&ktrace_lock);
318 } 356 }
319 357
320 /* Tracing may have been cancelled. */ 358 /* Tracing may have been cancelled. */
321 ktd = p->p_tracep; 359 ktd = p->p_tracep;
322 if (ktd == NULL) 360 if (ktd == NULL)
323 goto freekte; 361 goto freekte;
324 362
325 /* 363 /*
326 * Bump reference count so that the object will remain while 364 * Bump reference count so that the object will remain while
327 * we are here. Note that the trace is controlled by other 365 * we are here. Note that the trace is controlled by other
328 * process. 366 * process.
329 */ 367 */
330 ktdref(ktd); 368 ktdref(ktd);
331 369
332 if (ktd->ktd_flags & KTDF_DONE) 370 if (ktd->ktd_flags & KTDF_DONE)
333 goto relktd; 371 goto relktd;
334 372
335 if (ktd->ktd_qcount > ktd_maxentry) { 373 if (ktd->ktd_qcount > ktd_maxentry) {
336 ktd_logerrl(ktd, KTDE_ENOSPC); 374 ktd_logerrl(ktd, KTDE_ENOSPC);
337 goto relktd; 375 goto relktd;
338 } 376 }
339 TAILQ_INSERT_TAIL(&ktd->ktd_queue, kte, kte_list); 377 TAILQ_INSERT_TAIL(&ktd->ktd_queue, kte, kte_list);
340 ktd->ktd_qcount++; 378 ktd->ktd_qcount++;
341 if (ktd->ktd_flags & KTDF_BLOCKING) 379 if (ktd->ktd_flags & KTDF_BLOCKING)
342 goto skip_sync; 380 goto skip_sync;
343 381
344 if (flags & KTA_WAITOK && 382 if (flags & KTA_WAITOK &&
345 (/* flags & KTA_LARGE */0 || ktd->ktd_flags & KTDF_WAIT || 383 (/* flags & KTA_LARGE */0 || ktd->ktd_flags & KTDF_WAIT ||
346 ktd->ktd_qcount > ktd_maxentry >> 1)) 384 ktd->ktd_qcount > ktd_maxentry >> 1))
347 /* 385 /*
348 * Sync with writer thread since we're requesting rather 386 * Sync with writer thread since we're requesting rather
349 * big one or many requests are pending. 387 * big one or many requests are pending.
350 */ 388 */
351 do { 389 do {
352 ktd->ktd_flags |= KTDF_WAIT; 390 ktd->ktd_flags |= KTDF_WAIT;
353 ktd_wakeup(ktd); 391 ktd_wakeup(ktd);
354#ifdef DEBUG 392#ifdef DEBUG
355 getmicrouptime(&t1); 393 getmicrouptime(&t1);
356#endif 394#endif
357 if (cv_timedwait(&ktd->ktd_sync_cv, &ktrace_lock, 395 if (cv_timedwait(&ktd->ktd_sync_cv, &ktrace_lock,
358 ktd_timeout * hz) != 0) { 396 ktd_timeout * hz) != 0) {
359 ktd->ktd_flags |= KTDF_BLOCKING; 397 ktd->ktd_flags |= KTDF_BLOCKING;
360 /* 398 /*
361 * Maybe the writer thread is blocking 399 * Maybe the writer thread is blocking
362 * completely for some reason, but 400 * completely for some reason, but
363 * don't stop target process forever. 401 * don't stop target process forever.
364 */ 402 */
365 log(LOG_NOTICE, "ktrace timeout\n"); 403 log(LOG_NOTICE, "ktrace timeout\n");
366 break; 404 break;
367 } 405 }
368#ifdef DEBUG 406#ifdef DEBUG
369 getmicrouptime(&t2); 407 getmicrouptime(&t2);
370 timersub(&t2, &t1, &t2); 408 timersub(&t2, &t1, &t2);
371 if (t2.tv_sec > 0) 409 if (t2.tv_sec > 0)
372 log(LOG_NOTICE, 410 log(LOG_NOTICE,
373 "ktrace long wait: %lld.%06ld\n", 411 "ktrace long wait: %lld.%06ld\n",
374 (long long)t2.tv_sec, (long)t2.tv_usec); 412 (long long)t2.tv_sec, (long)t2.tv_usec);
375#endif 413#endif
376 } while (p->p_tracep == ktd && 414 } while (p->p_tracep == ktd &&
377 (ktd->ktd_flags & (KTDF_WAIT | KTDF_DONE)) == KTDF_WAIT); 415 (ktd->ktd_flags & (KTDF_WAIT | KTDF_DONE)) == KTDF_WAIT);
378 else { 416 else {
379 /* Schedule delayed wakeup */ 417 /* Schedule delayed wakeup */
380 if (ktd->ktd_qcount > ktd->ktd_delayqcnt) 418 if (ktd->ktd_qcount > ktd->ktd_delayqcnt)
381 ktd_wakeup(ktd); /* Wakeup now */ 419 ktd_wakeup(ktd); /* Wakeup now */
382 else if (!callout_pending(&ktd->ktd_wakch)) 420 else if (!callout_pending(&ktd->ktd_wakch))
383 callout_reset(&ktd->ktd_wakch, 421 callout_reset(&ktd->ktd_wakch,
384 ktd->ktd_flags & KTDF_INTERACTIVE ? 422 ktd->ktd_flags & KTDF_INTERACTIVE ?
385 ktd->ktd_intrwakdl : ktd->ktd_wakedelay, 423 ktd->ktd_intrwakdl : ktd->ktd_wakedelay,
386 ktd_callout, ktd); 424 ktd_callout, ktd);
387 } 425 }
388 426
389skip_sync: 427skip_sync:
390 ktdrel(ktd); 428 ktdrel(ktd);
391 mutex_exit(&ktrace_lock); 429 mutex_exit(&ktrace_lock);
392 ktrexit(l); 430 ktrexit(l);
393 return; 431 return;
394 432
395relktd: 433relktd:
396 ktdrel(ktd); 434 ktdrel(ktd);
397 435
398freekte: 436freekte:
399 mutex_exit(&ktrace_lock); 437 mutex_exit(&ktrace_lock);
400 ktefree(kte); 438 ktefree(kte);
401 ktrexit(l); 439 ktrexit(l);
402} 440}
403 441
404void 442void
405ktefree(struct ktrace_entry *kte) 443ktefree(struct ktrace_entry *kte)
406{ 444{
407 445
408 if (kte->kte_buf != kte->kte_space) 446 if (kte->kte_buf != kte->kte_space)
409 kmem_free(kte->kte_buf, kte->kte_bufsz); 447 kmem_free(kte->kte_buf, kte->kte_bufsz);
410 pool_cache_put(kte_cache, kte); 448 pool_cache_put(kte_cache, kte);
411} 449}
412 450
413/* 451/*
414 * "deep" compare of two files for the purposes of clearing a trace. 452 * "deep" compare of two files for the purposes of clearing a trace.
415 * Returns true if they're the same open file, or if they point at the 453 * Returns true if they're the same open file, or if they point at the
416 * same underlying vnode/socket. 454 * same underlying vnode/socket.
417 */ 455 */
418 456
419int 457int
420ktrsamefile(file_t *f1, file_t *f2) 458ktrsamefile(file_t *f1, file_t *f2)
421{ 459{
422 460
423 return ((f1 == f2) || 461 return ((f1 == f2) ||
424 ((f1 != NULL) && (f2 != NULL) && 462 ((f1 != NULL) && (f2 != NULL) &&
425 (f1->f_type == f2->f_type) && 463 (f1->f_type == f2->f_type) &&
426 (f1->f_data == f2->f_data))); 464 (f1->f_data == f2->f_data)));
427} 465}
428 466
429void 467void
430ktrderef(struct proc *p) 468ktrderef(struct proc *p)
431{ 469{
432 struct ktr_desc *ktd = p->p_tracep; 470 struct ktr_desc *ktd = p->p_tracep;
433 471
434 KASSERT(mutex_owned(&ktrace_lock)); 472 KASSERT(mutex_owned(&ktrace_lock));
435 473
436 p->p_traceflag = 0; 474 p->p_traceflag = 0;
437 if (ktd == NULL) 475 if (ktd == NULL)
438 return; 476 return;
439 p->p_tracep = NULL; 477 p->p_tracep = NULL;
440 478
441 cv_broadcast(&ktd->ktd_sync_cv); 479 cv_broadcast(&ktd->ktd_sync_cv);
442 ktdrel(ktd); 480 ktdrel(ktd);
443} 481}
444 482
445void 483void
446ktradref(struct proc *p) 484ktradref(struct proc *p)
447{ 485{
448 struct ktr_desc *ktd = p->p_tracep; 486 struct ktr_desc *ktd = p->p_tracep;
449 487
450 KASSERT(mutex_owned(&ktrace_lock)); 488 KASSERT(mutex_owned(&ktrace_lock));
451 489
452 ktdref(ktd); 490 ktdref(ktd);
453} 491}
454 492
455int 493int
456ktrderefall(struct ktr_desc *ktd, int auth) 494ktrderefall(struct ktr_desc *ktd, int auth)
457{ 495{
458 lwp_t *curl = curlwp; 496 lwp_t *curl = curlwp;
459 struct proc *p; 497 struct proc *p;
460 int error = 0; 498 int error = 0;
461 499
462 mutex_enter(proc_lock); 500 mutex_enter(proc_lock);
463 PROCLIST_FOREACH(p, &allproc) { 501 PROCLIST_FOREACH(p, &allproc) {
464 if ((p->p_flag & PK_MARKER) != 0 || p->p_tracep != ktd) 502 if ((p->p_flag & PK_MARKER) != 0 || p->p_tracep != ktd)
465 continue; 503 continue;
466 mutex_enter(p->p_lock); 504 mutex_enter(p->p_lock);
467 mutex_enter(&ktrace_lock); 505 mutex_enter(&ktrace_lock);
468 if (p->p_tracep == ktd) { 506 if (p->p_tracep == ktd) {
469 if (!auth || ktrcanset(curl, p)) 507 if (!auth || ktrcanset(curl, p))
470 ktrderef(p); 508 ktrderef(p);
471 else 509 else
472 error = EPERM; 510 error = EPERM;
473 } 511 }
474 mutex_exit(&ktrace_lock); 512 mutex_exit(&ktrace_lock);
475 mutex_exit(p->p_lock); 513 mutex_exit(p->p_lock);
476 } 514 }
477 mutex_exit(proc_lock); 515 mutex_exit(proc_lock);
478 516
479 return error; 517 return error;
480} 518}
481 519
482int 520int
483ktealloc(struct ktrace_entry **ktep, void **bufp, lwp_t *l, int type, 521ktealloc(struct ktrace_entry **ktep, void **bufp, lwp_t *l, int type,
484 size_t sz) 522 size_t sz)
485{ 523{
486 struct proc *p = l->l_proc; 524 struct proc *p = l->l_proc;
487 struct ktrace_entry *kte; 525 struct ktrace_entry *kte;
488 struct ktr_header *kth; 526 struct ktr_header *kth;
489 struct timespec ts; 527 struct timespec ts;
490 void *buf; 528 void *buf;
491 529
492 if (ktrenter(l)) 530 if (ktrenter(l))
493 return EAGAIN; 531 return EAGAIN;
494 532
495 kte = pool_cache_get(kte_cache, PR_WAITOK); 533 kte = pool_cache_get(kte_cache, PR_WAITOK);
496 if (sz > sizeof(kte->kte_space)) { 534 if (sz > sizeof(kte->kte_space)) {
497 if ((buf = kmem_alloc(sz, KM_SLEEP)) == NULL) { 535 if ((buf = kmem_alloc(sz, KM_SLEEP)) == NULL) {
498 pool_cache_put(kte_cache, kte); 536 pool_cache_put(kte_cache, kte);
499 ktrexit(l); 537 ktrexit(l);
500 return ENOMEM; 538 return ENOMEM;
501 } 539 }
502 } else 540 } else
503 buf = kte->kte_space; 541 buf = kte->kte_space;
504 542
505 kte->kte_bufsz = sz; 543 kte->kte_bufsz = sz;
506 kte->kte_buf = buf; 544 kte->kte_buf = buf;
507 545
508 kth = &kte->kte_kth; 546 kth = &kte->kte_kth;
509 (void)memset(kth, 0, sizeof(*kth)); 547 (void)memset(kth, 0, sizeof(*kth));
510 kth->ktr_len = sz; 548 kth->ktr_len = sz;
511 kth->ktr_type = type; 549 kth->ktr_type = type;
512 kth->ktr_pid = p->p_pid; 550 kth->ktr_pid = p->p_pid;
513 memcpy(kth->ktr_comm, p->p_comm, MAXCOMLEN); 551 memcpy(kth->ktr_comm, p->p_comm, MAXCOMLEN);
514 kth->ktr_version = KTRFAC_VERSION(p->p_traceflag); 552 kth->ktr_version = KTRFAC_VERSION(p->p_traceflag);
515 553
516 nanotime(&ts); 554 nanotime(&ts);
517 switch (KTRFAC_VERSION(p->p_traceflag)) { 555 switch (KTRFAC_VERSION(p->p_traceflag)) {
518 case 0: 556 case 0:
519 /* This is the original format */ 557 /* This is the original format */
520 kth->ktr_otv.tv_sec = ts.tv_sec; 558 kth->ktr_otv.tv_sec = ts.tv_sec;
521 kth->ktr_otv.tv_usec = ts.tv_nsec / 1000; 559 kth->ktr_otv.tv_usec = ts.tv_nsec / 1000;
522 break; 560 break;
523 case 1:  561 case 1:
524 kth->ktr_olid = l->l_lid; 562 kth->ktr_olid = l->l_lid;
525 kth->ktr_ots.tv_sec = ts.tv_sec; 563 kth->ktr_ots.tv_sec = ts.tv_sec;
526 kth->ktr_ots.tv_nsec = ts.tv_nsec;  564 kth->ktr_ots.tv_nsec = ts.tv_nsec;
527 break;  565 break;
528 case 2: 566 case 2:
529 kth->ktr_lid = l->l_lid; 567 kth->ktr_lid = l->l_lid;
530 kth->ktr_ts.tv_sec = ts.tv_sec; 568 kth->ktr_ts.tv_sec = ts.tv_sec;
531 kth->ktr_ts.tv_nsec = ts.tv_nsec;  569 kth->ktr_ts.tv_nsec = ts.tv_nsec;
532 break;  570 break;
533 default: 571 default:
534 break;  572 break;
535 } 573 }
536 574
537 *ktep = kte; 575 *ktep = kte;
538 *bufp = buf; 576 *bufp = buf;
539 577
540 return 0; 578 return 0;
541} 579}
542 580
543void 581void
544ktr_syscall(register_t code, const register_t args[], int narg) 582ktr_syscall(register_t code, const register_t args[], int narg)
545{ 583{
546 lwp_t *l = curlwp; 584 lwp_t *l = curlwp;
547 struct proc *p = l->l_proc; 585 struct proc *p = l->l_proc;
548 struct ktrace_entry *kte; 586 struct ktrace_entry *kte;
549 struct ktr_syscall *ktp; 587 struct ktr_syscall *ktp;
550 register_t *argp; 588 register_t *argp;
551 size_t len; 589 size_t len;
552 u_int i; 590 u_int i;
553 591
554 if (!KTRPOINT(p, KTR_SYSCALL)) 592 if (!KTRPOINT(p, KTR_SYSCALL))
555 return; 593 return;
556 594
557 len = sizeof(struct ktr_syscall) + narg * sizeof argp[0]; 595 len = sizeof(struct ktr_syscall) + narg * sizeof argp[0];
558 596
559 if (ktealloc(&kte, (void *)&ktp, l, KTR_SYSCALL, len)) 597 if (ktealloc(&kte, (void *)&ktp, l, KTR_SYSCALL, len))
560 return; 598 return;
561 599
562 ktp->ktr_code = code; 600 ktp->ktr_code = code;
563 ktp->ktr_argsize = narg * sizeof argp[0]; 601 ktp->ktr_argsize = narg * sizeof argp[0];
564 argp = (register_t *)(ktp + 1); 602 argp = (register_t *)(ktp + 1);
565 for (i = 0; i < narg; i++) 603 for (i = 0; i < narg; i++)
566 *argp++ = args[i]; 604 *argp++ = args[i];
567 605
568 ktraddentry(l, kte, KTA_WAITOK); 606 ktraddentry(l, kte, KTA_WAITOK);
569} 607}
570 608
571void 609void
572ktr_sysret(register_t code, int error, register_t *retval) 610ktr_sysret(register_t code, int error, register_t *retval)
573{ 611{
574 lwp_t *l = curlwp; 612 lwp_t *l = curlwp;
575 struct ktrace_entry *kte; 613 struct ktrace_entry *kte;
576 struct ktr_sysret *ktp; 614 struct ktr_sysret *ktp;
577 615
578 if (!KTRPOINT(l->l_proc, KTR_SYSRET)) 616 if (!KTRPOINT(l->l_proc, KTR_SYSRET))
579 return; 617 return;
580 618
581 if (ktealloc(&kte, (void *)&ktp, l, KTR_SYSRET, 619 if (ktealloc(&kte, (void *)&ktp, l, KTR_SYSRET,
582 sizeof(struct ktr_sysret))) 620 sizeof(struct ktr_sysret)))
583 return; 621 return;
584 622
585 ktp->ktr_code = code; 623 ktp->ktr_code = code;
586 ktp->ktr_eosys = 0; /* XXX unused */ 624 ktp->ktr_eosys = 0; /* XXX unused */
587 ktp->ktr_error = error; 625 ktp->ktr_error = error;
588 ktp->ktr_retval = retval ? retval[0] : 0; 626 ktp->ktr_retval = retval ? retval[0] : 0;
589 ktp->ktr_retval_1 = retval ? retval[1] : 0; 627 ktp->ktr_retval_1 = retval ? retval[1] : 0;
590 628
591 ktraddentry(l, kte, KTA_WAITOK); 629 ktraddentry(l, kte, KTA_WAITOK);
592} 630}
593 631
594void 632void
595ktr_namei(const char *path, size_t pathlen) 633ktr_namei(const char *path, size_t pathlen)
596{ 634{
597 lwp_t *l = curlwp; 635 lwp_t *l = curlwp;
598 636
599 if (!KTRPOINT(l->l_proc, KTR_NAMEI)) 637 if (!KTRPOINT(l->l_proc, KTR_NAMEI))
600 return; 638 return;
601 639
602 ktr_kmem(l, KTR_NAMEI, path, pathlen); 640 ktr_kmem(l, KTR_NAMEI, path, pathlen);
603} 641}
604 642
605void 643void
606ktr_namei2(const char *eroot, size_t erootlen, 644ktr_namei2(const char *eroot, size_t erootlen,
607 const char *path, size_t pathlen) 645 const char *path, size_t pathlen)
608{ 646{
609 lwp_t *l = curlwp; 647 lwp_t *l = curlwp;
610 struct ktrace_entry *kte; 648 struct ktrace_entry *kte;
611 void *buf; 649 void *buf;
612 650
613 if (!KTRPOINT(l->l_proc, KTR_NAMEI)) 651 if (!KTRPOINT(l->l_proc, KTR_NAMEI))
614 return; 652 return;
615 653
616 if (ktealloc(&kte, &buf, l, KTR_NAMEI, erootlen + pathlen)) 654 if (ktealloc(&kte, &buf, l, KTR_NAMEI, erootlen + pathlen))
617 return; 655 return;
618 memcpy(buf, eroot, erootlen); 656 memcpy(buf, eroot, erootlen);
619 buf = (char *)buf + erootlen; 657 buf = (char *)buf + erootlen;
620 memcpy(buf, path, pathlen); 658 memcpy(buf, path, pathlen);
621 ktraddentry(l, kte, KTA_WAITOK); 659 ktraddentry(l, kte, KTA_WAITOK);
622} 660}
623 661
624void 662void
625ktr_emul(void) 663ktr_emul(void)
626{ 664{
627 lwp_t *l = curlwp; 665 lwp_t *l = curlwp;
628 const char *emul = l->l_proc->p_emul->e_name; 666 const char *emul = l->l_proc->p_emul->e_name;
629 667
630 if (!KTRPOINT(l->l_proc, KTR_EMUL)) 668 if (!KTRPOINT(l->l_proc, KTR_EMUL))
631 return; 669 return;
632 670
633 ktr_kmem(l, KTR_EMUL, emul, strlen(emul)); 671 ktr_kmem(l, KTR_EMUL, emul, strlen(emul));
634} 672}
635 673
636void 674void
637ktr_execarg(const void *bf, size_t len) 675ktr_execarg(const void *bf, size_t len)
638{ 676{
639 lwp_t *l = curlwp; 677 lwp_t *l = curlwp;
640 678
641 if (!KTRPOINT(l->l_proc, KTR_EXEC_ARG)) 679 if (!KTRPOINT(l->l_proc, KTR_EXEC_ARG))
642 return; 680 return;
643 681
644 ktr_kmem(l, KTR_EXEC_ARG, bf, len); 682 ktr_kmem(l, KTR_EXEC_ARG, bf, len);
645} 683}
646 684
647void 685void
648ktr_execenv(const void *bf, size_t len) 686ktr_execenv(const void *bf, size_t len)
649{ 687{
650 lwp_t *l = curlwp; 688 lwp_t *l = curlwp;
651 689
652 if (!KTRPOINT(l->l_proc, KTR_EXEC_ENV)) 690 if (!KTRPOINT(l->l_proc, KTR_EXEC_ENV))
653 return; 691 return;
654 692
655 ktr_kmem(l, KTR_EXEC_ENV, bf, len); 693 ktr_kmem(l, KTR_EXEC_ENV, bf, len);
656} 694}
657 695
658static void 696static void
659ktr_kmem(lwp_t *l, int type, const void *bf, size_t len) 697ktr_kmem(lwp_t *l, int type, const void *bf, size_t len)
660{ 698{
661 struct ktrace_entry *kte; 699 struct ktrace_entry *kte;
662 void *buf; 700 void *buf;
663 701
664 if (ktealloc(&kte, &buf, l, type, len)) 702 if (ktealloc(&kte, &buf, l, type, len))
665 return; 703 return;
666 memcpy(buf, bf, len); 704 memcpy(buf, bf, len);
667 ktraddentry(l, kte, KTA_WAITOK); 705 ktraddentry(l, kte, KTA_WAITOK);
668} 706}
669 707
670static void 708static void
671ktr_io(lwp_t *l, int fd, enum uio_rw rw, struct iovec *iov, size_t len) 709ktr_io(lwp_t *l, int fd, enum uio_rw rw, struct iovec *iov, size_t len)
672{ 710{
673 struct ktrace_entry *kte; 711 struct ktrace_entry *kte;
674 struct ktr_genio *ktp; 712 struct ktr_genio *ktp;
675 size_t resid = len, cnt, buflen; 713 size_t resid = len, cnt, buflen;
676 char *cp; 714 char *cp;
677 715
678 next: 716 next:
679 buflen = min(PAGE_SIZE, resid + sizeof(struct ktr_genio)); 717 buflen = min(PAGE_SIZE, resid + sizeof(struct ktr_genio));
680 718
681 if (ktealloc(&kte, (void *)&ktp, l, KTR_GENIO, buflen)) 719 if (ktealloc(&kte, (void *)&ktp, l, KTR_GENIO, buflen))
682 return; 720 return;
683 721
684 ktp->ktr_fd = fd; 722 ktp->ktr_fd = fd;
685 ktp->ktr_rw = rw; 723 ktp->ktr_rw = rw;
686 724
687 cp = (void *)(ktp + 1); 725 cp = (void *)(ktp + 1);
688 buflen -= sizeof(struct ktr_genio); 726 buflen -= sizeof(struct ktr_genio);
689 kte->kte_kth.ktr_len = sizeof(struct ktr_genio); 727 kte->kte_kth.ktr_len = sizeof(struct ktr_genio);
690 728
691 while (buflen > 0) { 729 while (buflen > 0) {
692 cnt = min(iov->iov_len, buflen); 730 cnt = min(iov->iov_len, buflen);
693 if (copyin(iov->iov_base, cp, cnt) != 0) 731 if (copyin(iov->iov_base, cp, cnt) != 0)
694 goto out; 732 goto out;
695 kte->kte_kth.ktr_len += cnt; 733 kte->kte_kth.ktr_len += cnt;
696 cp += cnt; 734 cp += cnt;
697 buflen -= cnt; 735 buflen -= cnt;
698 resid -= cnt; 736 resid -= cnt;
699 iov->iov_len -= cnt; 737 iov->iov_len -= cnt;
700 if (iov->iov_len == 0) 738 if (iov->iov_len == 0)
701 iov++; 739 iov++;
702 else 740 else
703 iov->iov_base = (char *)iov->iov_base + cnt; 741 iov->iov_base = (char *)iov->iov_base + cnt;
704 } 742 }
705 743
706 /* 744 /*
707 * Don't push so many entry at once. It will cause kmem map 745 * Don't push so many entry at once. It will cause kmem map
708 * shortage. 746 * shortage.
709 */ 747 */
710 ktraddentry(l, kte, KTA_WAITOK | KTA_LARGE); 748 ktraddentry(l, kte, KTA_WAITOK | KTA_LARGE);
711 if (resid > 0) { 749 if (resid > 0) {
712 if (curcpu()->ci_schedstate.spc_flags & SPCF_SHOULDYIELD) { 750 if (curcpu()->ci_schedstate.spc_flags & SPCF_SHOULDYIELD) {
713 (void)ktrenter(l); 751 (void)ktrenter(l);
714 preempt(); 752 preempt();
715 ktrexit(l); 753 ktrexit(l);
716 } 754 }
717 755
718 goto next; 756 goto next;
719 } 757 }
720 758
721 return; 759 return;
722 760
723out: 761out:
724 ktefree(kte); 762 ktefree(kte);
725 ktrexit(l); 763 ktrexit(l);
726} 764}
727 765
728void 766void
729ktr_genio(int fd, enum uio_rw rw, const void *addr, size_t len, int error) 767ktr_genio(int fd, enum uio_rw rw, const void *addr, size_t len, int error)
730{ 768{
731 lwp_t *l = curlwp; 769 lwp_t *l = curlwp;
732 struct iovec iov; 770 struct iovec iov;
733 771
734 if (!KTRPOINT(l->l_proc, KTR_GENIO) || error != 0) 772 if (!KTRPOINT(l->l_proc, KTR_GENIO) || error != 0)
735 return; 773 return;
736 iov.iov_base = __UNCONST(addr); 774 iov.iov_base = __UNCONST(addr);
737 iov.iov_len = len; 775 iov.iov_len = len;
738 ktr_io(l, fd, rw, &iov, len); 776 ktr_io(l, fd, rw, &iov, len);
739} 777}
740 778
741void 779void
742ktr_geniov(int fd, enum uio_rw rw, struct iovec *iov, size_t len, int error) 780ktr_geniov(int fd, enum uio_rw rw, struct iovec *iov, size_t len, int error)
743{ 781{
744 lwp_t *l = curlwp; 782 lwp_t *l = curlwp;
745 783
746 if (!KTRPOINT(l->l_proc, KTR_GENIO) || error != 0) 784 if (!KTRPOINT(l->l_proc, KTR_GENIO) || error != 0)
747 return; 785 return;
748 ktr_io(l, fd, rw, iov, len); 786 ktr_io(l, fd, rw, iov, len);
749} 787}
750 788
751void 789void
752ktr_mibio(int fd, enum uio_rw rw, const void *addr, size_t len, int error) 790ktr_mibio(int fd, enum uio_rw rw, const void *addr, size_t len, int error)
753{ 791{
754 lwp_t *l = curlwp; 792 lwp_t *l = curlwp;
755 struct iovec iov; 793 struct iovec iov;
756 794
757 if (!KTRPOINT(l->l_proc, KTR_MIB) || error != 0) 795 if (!KTRPOINT(l->l_proc, KTR_MIB) || error != 0)
758 return; 796 return;
759 iov.iov_base = __UNCONST(addr); 797 iov.iov_base = __UNCONST(addr);
760 iov.iov_len = len; 798 iov.iov_len = len;
761 ktr_io(l, fd, rw, &iov, len); 799 ktr_io(l, fd, rw, &iov, len);
762} 800}
763 801
764void 802void
765ktr_psig(int sig, sig_t action, const sigset_t *mask, 803ktr_psig(int sig, sig_t action, const sigset_t *mask,
766 const ksiginfo_t *ksi) 804 const ksiginfo_t *ksi)
767{ 805{
768 struct ktrace_entry *kte; 806 struct ktrace_entry *kte;
769 lwp_t *l = curlwp; 807 lwp_t *l = curlwp;
770 struct { 808 struct {
771 struct ktr_psig kp; 809 struct ktr_psig kp;
772 siginfo_t si; 810 siginfo_t si;
773 } *kbuf; 811 } *kbuf;
774 812
775 if (!KTRPOINT(l->l_proc, KTR_PSIG)) 813 if (!KTRPOINT(l->l_proc, KTR_PSIG))
776 return; 814 return;
777 815
778 if (ktealloc(&kte, (void *)&kbuf, l, KTR_PSIG, sizeof(*kbuf))) 816 if (ktealloc(&kte, (void *)&kbuf, l, KTR_PSIG, sizeof(*kbuf)))
779 return; 817 return;
780 818
781 kbuf->kp.signo = (char)sig; 819 kbuf->kp.signo = (char)sig;
782 kbuf->kp.action = action; 820 kbuf->kp.action = action;
783 kbuf->kp.mask = *mask; 821 kbuf->kp.mask = *mask;
784 822
785 if (ksi) { 823 if (ksi) {
786 kbuf->kp.code = KSI_TRAPCODE(ksi); 824 kbuf->kp.code = KSI_TRAPCODE(ksi);
787 (void)memset(&kbuf->si, 0, sizeof(kbuf->si)); 825 (void)memset(&kbuf->si, 0, sizeof(kbuf->si));
788 kbuf->si._info = ksi->ksi_info; 826 kbuf->si._info = ksi->ksi_info;
789 kte->kte_kth.ktr_len = sizeof(*kbuf); 827 kte->kte_kth.ktr_len = sizeof(*kbuf);
790 } else { 828 } else {
791 kbuf->kp.code = 0; 829 kbuf->kp.code = 0;
792 kte->kte_kth.ktr_len = sizeof(struct ktr_psig); 830 kte->kte_kth.ktr_len = sizeof(struct ktr_psig);
793 } 831 }
794 832
795 ktraddentry(l, kte, KTA_WAITOK); 833 ktraddentry(l, kte, KTA_WAITOK);
796} 834}
797 835
798void 836void
799ktr_csw(int out, int user) 837ktr_csw(int out, int user)
800{ 838{
801 lwp_t *l = curlwp; 839 lwp_t *l = curlwp;
802 struct proc *p = l->l_proc; 840 struct proc *p = l->l_proc;
803 struct ktrace_entry *kte; 841 struct ktrace_entry *kte;
804 struct ktr_csw *kc; 842 struct ktr_csw *kc;
805 843
806 if (!KTRPOINT(p, KTR_CSW)) 844 if (!KTRPOINT(p, KTR_CSW))
807 return; 845 return;
808 846
809 /* 847 /*
810 * Don't record context switches resulting from blocking on  848 * Don't record context switches resulting from blocking on
811 * locks; it's too easy to get duff results. 849 * locks; it's too easy to get duff results.
812 */ 850 */
813 if (l->l_syncobj == &mutex_syncobj || l->l_syncobj == &rw_syncobj) 851 if (l->l_syncobj == &mutex_syncobj || l->l_syncobj == &rw_syncobj)
814 return; 852 return;
815 853
816 /* 854 /*
817 * We can't sleep if we're already going to sleep (if original 855 * We can't sleep if we're already going to sleep (if original
818 * condition is met during sleep, we hang up). 856 * condition is met during sleep, we hang up).
819 * 857 *
820 * XXX This is not ideal: it would be better to maintain a pool 858 * XXX This is not ideal: it would be better to maintain a pool
821 * of ktes and actually push this to the kthread when context 859 * of ktes and actually push this to the kthread when context
822 * switch happens, however given the points where we are called 860 * switch happens, however given the points where we are called
823 * from that is difficult to do.  861 * from that is difficult to do.
824 */ 862 */
825 if (out) { 863 if (out) {
826 struct timespec ts; 864 struct timespec ts;
827 if (ktrenter(l)) 865 if (ktrenter(l))
828 return; 866 return;
829 867
830 nanotime(&l->l_ktrcsw); 868 nanotime(&l->l_ktrcsw);
831 l->l_pflag |= LP_KTRCSW; 869 l->l_pflag |= LP_KTRCSW;
832 nanotime(&ts); 870 nanotime(&ts);
833 if (user) 871 if (user)
834 l->l_pflag |= LP_KTRCSWUSER; 872 l->l_pflag |= LP_KTRCSWUSER;
835 else 873 else
836 l->l_pflag &= ~LP_KTRCSWUSER; 874 l->l_pflag &= ~LP_KTRCSWUSER;
837 875
838 ktrexit(l); 876 ktrexit(l);
839 return; 877 return;
840 } 878 }
841 879
842 /* 880 /*
843 * On the way back in, we need to record twice: once for entry, and 881 * On the way back in, we need to record twice: once for entry, and
844 * once for exit. 882 * once for exit.
845 */ 883 */
846 if ((l->l_pflag & LP_KTRCSW) != 0) { 884 if ((l->l_pflag & LP_KTRCSW) != 0) {
847 struct timespec *ts; 885 struct timespec *ts;
848 l->l_pflag &= ~LP_KTRCSW; 886 l->l_pflag &= ~LP_KTRCSW;
849 887
850 if (ktealloc(&kte, (void *)&kc, l, KTR_CSW, sizeof(*kc))) 888 if (ktealloc(&kte, (void *)&kc, l, KTR_CSW, sizeof(*kc)))
851 return; 889 return;
852 890
853 kc->out = 1; 891 kc->out = 1;
854 kc->user = ((l->l_pflag & LP_KTRCSWUSER) != 0); 892 kc->user = ((l->l_pflag & LP_KTRCSWUSER) != 0);
855 893
856 ts = &l->l_ktrcsw; 894 ts = &l->l_ktrcsw;
857 switch (KTRFAC_VERSION(p->p_traceflag)) { 895 switch (KTRFAC_VERSION(p->p_traceflag)) {
858 case 0: 896 case 0:
859 kte->kte_kth.ktr_otv.tv_sec = ts->tv_sec; 897 kte->kte_kth.ktr_otv.tv_sec = ts->tv_sec;
860 kte->kte_kth.ktr_otv.tv_usec = ts->tv_nsec / 1000; 898 kte->kte_kth.ktr_otv.tv_usec = ts->tv_nsec / 1000;
861 break; 899 break;
862 case 1:  900 case 1:
863 kte->kte_kth.ktr_ots.tv_sec = ts->tv_sec; 901 kte->kte_kth.ktr_ots.tv_sec = ts->tv_sec;
864 kte->kte_kth.ktr_ots.tv_nsec = ts->tv_nsec;  902 kte->kte_kth.ktr_ots.tv_nsec = ts->tv_nsec;
865 break;  903 break;
866 case 2: 904 case 2:
867 kte->kte_kth.ktr_ts.tv_sec = ts->tv_sec; 905 kte->kte_kth.ktr_ts.tv_sec = ts->tv_sec;
868 kte->kte_kth.ktr_ts.tv_nsec = ts->tv_nsec;  906 kte->kte_kth.ktr_ts.tv_nsec = ts->tv_nsec;
869 break;  907 break;
870 default: 908 default:
871 break;  909 break;
872 } 910 }
873 911
874 ktraddentry(l, kte, KTA_WAITOK); 912 ktraddentry(l, kte, KTA_WAITOK);
875 } 913 }
876 914
877 if (ktealloc(&kte, (void *)&kc, l, KTR_CSW, sizeof(*kc))) 915 if (ktealloc(&kte, (void *)&kc, l, KTR_CSW, sizeof(*kc)))
878 return; 916 return;
879 917
880 kc->out = 0; 918 kc->out = 0;
881 kc->user = user; 919 kc->user = user;
882 920
883 ktraddentry(l, kte, KTA_WAITOK); 921 ktraddentry(l, kte, KTA_WAITOK);
884} 922}
885 923
886bool 924bool
887ktr_point(int fac_bit) 925ktr_point(int fac_bit)
888{ 926{
889 return curlwp->l_proc->p_traceflag & fac_bit; 927 return curlwp->l_proc->p_traceflag & fac_bit;
890} 928}
891 929
892int 930int
893ktruser(const char *id, void *addr, size_t len, int ustr) 931ktruser(const char *id, void *addr, size_t len, int ustr)
894{ 932{
895 struct ktrace_entry *kte; 933 struct ktrace_entry *kte;
896 struct ktr_user *ktp; 934 struct ktr_user *ktp;
897 lwp_t *l = curlwp; 935 lwp_t *l = curlwp;
898 void *user_dta; 936 void *user_dta;
899 int error; 937 int error;
900 938
901 if (!KTRPOINT(l->l_proc, KTR_USER)) 939 if (!KTRPOINT(l->l_proc, KTR_USER))
902 return 0; 940 return 0;
903 941
904 if (len > KTR_USER_MAXLEN) 942 if (len > KTR_USER_MAXLEN)
905 return ENOSPC; 943 return ENOSPC;
906 944
907 error = ktealloc(&kte, (void *)&ktp, l, KTR_USER, sizeof(*ktp) + len); 945 error = ktealloc(&kte, (void *)&ktp, l, KTR_USER, sizeof(*ktp) + len);
908 if (error != 0) 946 if (error != 0)
909 return error; 947 return error;
910 948
911 if (ustr) { 949 if (ustr) {
912 if (copyinstr(id, ktp->ktr_id, KTR_USER_MAXIDLEN, NULL) != 0) 950 if (copyinstr(id, ktp->ktr_id, KTR_USER_MAXIDLEN, NULL) != 0)
913 ktp->ktr_id[0] = '\0'; 951 ktp->ktr_id[0] = '\0';
914 } else 952 } else
915 strncpy(ktp->ktr_id, id, KTR_USER_MAXIDLEN); 953 strncpy(ktp->ktr_id, id, KTR_USER_MAXIDLEN);
916 ktp->ktr_id[KTR_USER_MAXIDLEN-1] = '\0'; 954 ktp->ktr_id[KTR_USER_MAXIDLEN-1] = '\0';
917 955
918 user_dta = (void *)(ktp + 1); 956 user_dta = (void *)(ktp + 1);
919 if ((error = copyin(addr, (void *)user_dta, len)) != 0) 957 if ((error = copyin(addr, (void *)user_dta, len)) != 0)
920 len = 0; 958 len = 0;
921 959
922 ktraddentry(l, kte, KTA_WAITOK); 960 ktraddentry(l, kte, KTA_WAITOK);
923 return error; 961 return error;
924} 962}
925 963
926void 964void
927ktr_kuser(const char *id, void *addr, size_t len) 965ktr_kuser(const char *id, void *addr, size_t len)
928{ 966{
929 struct ktrace_entry *kte; 967 struct ktrace_entry *kte;
930 struct ktr_user *ktp; 968 struct ktr_user *ktp;
931 lwp_t *l = curlwp; 969 lwp_t *l = curlwp;
932 int error; 970 int error;
933 971
934 if (!KTRPOINT(l->l_proc, KTR_USER)) 972 if (!KTRPOINT(l->l_proc, KTR_USER))
935 return; 973 return;
936 974
937 if (len > KTR_USER_MAXLEN) 975 if (len > KTR_USER_MAXLEN)
938 return; 976 return;
939 977
940 error = ktealloc(&kte, (void *)&ktp, l, KTR_USER, sizeof(*ktp) + len); 978 error = ktealloc(&kte, (void *)&ktp, l, KTR_USER, sizeof(*ktp) + len);
941 if (error != 0) 979 if (error != 0)
942 return; 980 return;
943 981
944 strlcpy(ktp->ktr_id, id, KTR_USER_MAXIDLEN); 982 strlcpy(ktp->ktr_id, id, KTR_USER_MAXIDLEN);
945 983
946 memcpy(ktp + 1, addr, len); 984 memcpy(ktp + 1, addr, len);
947 985
948 ktraddentry(l, kte, KTA_WAITOK); 986 ktraddentry(l, kte, KTA_WAITOK);
949} 987}
950 988
951void 989void
952ktr_mmsg(const void *msgh, size_t size) 990ktr_mmsg(const void *msgh, size_t size)
953{ 991{
954 lwp_t *l = curlwp; 992 lwp_t *l = curlwp;
955 993
956 if (!KTRPOINT(l->l_proc, KTR_MMSG)) 994 if (!KTRPOINT(l->l_proc, KTR_MMSG))
957 return; 995 return;
958 996
959 ktr_kmem(l, KTR_MMSG, msgh, size); 997 ktr_kmem(l, KTR_MMSG, msgh, size);
960} 998}
961 999
962void 1000void
963ktr_mool(const void *kaddr, size_t size, const void *uaddr) 1001ktr_mool(const void *kaddr, size_t size, const void *uaddr)
964{ 1002{
965 struct ktrace_entry *kte; 1003 struct ktrace_entry *kte;
966 struct ktr_mool *kp; 1004 struct ktr_mool *kp;
967 struct ktr_mool *bf; 1005 struct ktr_mool *bf;
968 lwp_t *l = curlwp; 1006 lwp_t *l = curlwp;
969 1007
970 if (!KTRPOINT(l->l_proc, KTR_MOOL)) 1008 if (!KTRPOINT(l->l_proc, KTR_MOOL))
971 return; 1009 return;
972 1010
973 if (ktealloc(&kte, (void *)&kp, l, KTR_MOOL, size + sizeof(*kp))) 1011 if (ktealloc(&kte, (void *)&kp, l, KTR_MOOL, size + sizeof(*kp)))
974 return; 1012 return;
975 1013
976 kp->uaddr = uaddr; 1014 kp->uaddr = uaddr;
977 kp->size = size; 1015 kp->size = size;
978 bf = kp + 1; /* Skip uaddr and size */ 1016 bf = kp + 1; /* Skip uaddr and size */
979 (void)memcpy(bf, kaddr, size); 1017 (void)memcpy(bf, kaddr, size);
980 1018
981 ktraddentry(l, kte, KTA_WAITOK); 1019 ktraddentry(l, kte, KTA_WAITOK);
982} 1020}
983 1021
984void 1022void
985ktr_saupcall(struct lwp *l, int type, int nevent, int nint, void *sas, 1023ktr_saupcall(struct lwp *l, int type, int nevent, int nint, void *sas,
986 void *ap, void *ksas) 1024 void *ap, void *ksas)
987{ 1025{
988 struct ktrace_entry *kte; 1026 struct ktrace_entry *kte;
989 struct ktr_saupcall *ktp; 1027 struct ktr_saupcall *ktp;
990 size_t len, sz; 1028 size_t len, sz;
991 struct sa_t **sapp; 1029 struct sa_t **sapp;
992 int i; 1030 int i;
993 1031
994 if (!KTRPOINT(l->l_proc, KTR_SAUPCALL)) 1032 if (!KTRPOINT(l->l_proc, KTR_SAUPCALL))
995 return; 1033 return;
996 1034
997 len = sizeof(struct ktr_saupcall); 1035 len = sizeof(struct ktr_saupcall);
998 sz = len + sizeof(struct sa_t) * (nevent + nint + 1); 1036 sz = len + sizeof(struct sa_t) * (nevent + nint + 1);
999 1037
1000 if (ktealloc(&kte, (void *)&ktp, l, KTR_SAUPCALL, sz)) 1038 if (ktealloc(&kte, (void *)&ktp, l, KTR_SAUPCALL, sz))
1001 return; 1039 return;
1002 1040
1003 ktp->ktr_type = type; 1041 ktp->ktr_type = type;
1004 ktp->ktr_nevent = nevent; 1042 ktp->ktr_nevent = nevent;
1005 ktp->ktr_nint = nint; 1043 ktp->ktr_nint = nint;
1006 ktp->ktr_sas = sas; 1044 ktp->ktr_sas = sas;
1007 ktp->ktr_ap = ap; 1045 ktp->ktr_ap = ap;
1008 1046
1009 /* Copy the sa_t's */ 1047 /* Copy the sa_t's */
1010 sapp = (struct sa_t **) ksas; 1048 sapp = (struct sa_t **) ksas;
1011 1049
1012 for (i = nevent + nint; i >= 0; i--) { 1050 for (i = nevent + nint; i >= 0; i--) {
1013 memcpy((char *)ktp + len, *sapp, sizeof(struct sa_t)); 1051 memcpy((char *)ktp + len, *sapp, sizeof(struct sa_t));
1014 len += sizeof(struct sa_t); 1052 len += sizeof(struct sa_t);
1015 sapp++; 1053 sapp++;
1016 } 1054 }
1017 1055
1018 kte->kte_kth.ktr_len = len; 1056 kte->kte_kth.ktr_len = len;
1019 ktraddentry(l, kte, KTA_WAITOK); 1057 ktraddentry(l, kte, KTA_WAITOK);
1020} 1058}
1021 1059
1022void 1060void
1023ktr_mib(const int *name, u_int namelen) 1061ktr_mib(const int *name, u_int namelen)
1024{ 1062{
1025 struct ktrace_entry *kte; 1063 struct ktrace_entry *kte;
1026 int *namep; 1064 int *namep;
1027 size_t size; 1065 size_t size;
1028 lwp_t *l = curlwp; 1066 lwp_t *l = curlwp;
1029 1067
1030 if (!KTRPOINT(l->l_proc, KTR_MIB)) 1068 if (!KTRPOINT(l->l_proc, KTR_MIB))
1031 return; 1069 return;
1032 1070
1033 size = namelen * sizeof(*name); 1071 size = namelen * sizeof(*name);
1034 1072
1035 if (ktealloc(&kte, (void *)&namep, l, KTR_MIB, size)) 1073 if (ktealloc(&kte, (void *)&namep, l, KTR_MIB, size))
1036 return; 1074 return;
1037 1075
1038 (void)memcpy(namep, name, namelen * sizeof(*name)); 1076 (void)memcpy(namep, name, namelen * sizeof(*name));
1039 1077
1040 ktraddentry(l, kte, KTA_WAITOK); 1078 ktraddentry(l, kte, KTA_WAITOK);
1041} 1079}
1042 1080
1043/* Interface and common routines */ 1081/* Interface and common routines */
1044 1082
1045int 1083int
1046ktrace_common(lwp_t *curl, int ops, int facs, int pid, file_t *fp) 1084ktrace_common(lwp_t *curl, int ops, int facs, int pid, file_t *fp)
1047{ 1085{
1048 struct proc *curp; 1086 struct proc *curp;
1049 struct proc *p; 1087 struct proc *p;
1050 struct pgrp *pg; 1088 struct pgrp *pg;
1051 struct ktr_desc *ktd = NULL; 1089 struct ktr_desc *ktd = NULL;
1052 int ret = 0; 1090 int ret = 0;
1053 int error = 0; 1091 int error = 0;
1054 int descend; 1092 int descend;
1055 1093
1056 curp = curl->l_proc; 1094 curp = curl->l_proc;
1057 descend = ops & KTRFLAG_DESCEND; 1095 descend = ops & KTRFLAG_DESCEND;
1058 facs = facs & ~((unsigned) KTRFAC_PERSISTENT); 1096 facs = facs & ~((unsigned) KTRFAC_PERSISTENT);
1059 1097
1060 (void)ktrenter(curl); 1098 (void)ktrenter(curl);
1061 1099
1062 switch (KTROP(ops)) { 1100 switch (KTROP(ops)) {
1063 1101
1064 case KTROP_CLEARFILE: 1102 case KTROP_CLEARFILE:
1065 /* 1103 /*
1066 * Clear all uses of the tracefile 1104 * Clear all uses of the tracefile
1067 */ 1105 */
1068 mutex_enter(&ktrace_lock); 1106 mutex_enter(&ktrace_lock);
1069 ktd = ktd_lookup(fp); 1107 ktd = ktd_lookup(fp);
1070 mutex_exit(&ktrace_lock); 1108 mutex_exit(&ktrace_lock);
1071 if (ktd == NULL) 1109 if (ktd == NULL)
1072 goto done; 1110 goto done;
1073 error = ktrderefall(ktd, 1); 1111 error = ktrderefall(ktd, 1);
1074 goto done; 1112 goto done;
1075 1113
1076 case KTROP_SET: 1114 case KTROP_SET:
1077 mutex_enter(&ktrace_lock); 1115 mutex_enter(&ktrace_lock);
1078 ktd = ktd_lookup(fp); 1116 ktd = ktd_lookup(fp);
1079 mutex_exit(&ktrace_lock); 1117 mutex_exit(&ktrace_lock);
1080 if (ktd == NULL) { 1118 if (ktd == NULL) {
1081 ktd = kmem_alloc(sizeof(*ktd), KM_SLEEP); 1119 ktd = kmem_alloc(sizeof(*ktd), KM_SLEEP);
1082 TAILQ_INIT(&ktd->ktd_queue); 1120 TAILQ_INIT(&ktd->ktd_queue);
1083 callout_init(&ktd->ktd_wakch, CALLOUT_MPSAFE); 1121 callout_init(&ktd->ktd_wakch, CALLOUT_MPSAFE);
1084 cv_init(&ktd->ktd_cv, "ktrwait"); 1122 cv_init(&ktd->ktd_cv, "ktrwait");
1085 cv_init(&ktd->ktd_sync_cv, "ktrsync"); 1123 cv_init(&ktd->ktd_sync_cv, "ktrsync");
1086 ktd->ktd_flags = 0; 1124 ktd->ktd_flags = 0;
1087 ktd->ktd_qcount = 0; 1125 ktd->ktd_qcount = 0;
1088 ktd->ktd_error = 0; 1126 ktd->ktd_error = 0;
1089 ktd->ktd_errcnt = 0; 1127 ktd->ktd_errcnt = 0;
1090 ktd->ktd_delayqcnt = ktd_delayqcnt; 1128 ktd->ktd_delayqcnt = ktd_delayqcnt;
1091 ktd->ktd_wakedelay = mstohz(ktd_wakedelay); 1129 ktd->ktd_wakedelay = mstohz(ktd_wakedelay);
1092 ktd->ktd_intrwakdl = mstohz(ktd_intrwakdl); 1130 ktd->ktd_intrwakdl = mstohz(ktd_intrwakdl);
1093 ktd->ktd_ref = 0; 1131 ktd->ktd_ref = 0;
1094 ktd->ktd_fp = fp; 1132 ktd->ktd_fp = fp;
1095 mutex_enter(&ktrace_lock); 1133 mutex_enter(&ktrace_lock);
1096 ktdref(ktd); 1134 ktdref(ktd);
1097 mutex_exit(&ktrace_lock); 1135 mutex_exit(&ktrace_lock);
1098 1136
1099 /* 1137 /*
1100 * XXX: not correct. needs an way to detect 1138 * XXX: not correct. needs an way to detect
1101 * whether ktruss or ktrace. 1139 * whether ktruss or ktrace.
1102 */ 1140 */
1103 if (fp->f_type == DTYPE_PIPE) 1141 if (fp->f_type == DTYPE_PIPE)
1104 ktd->ktd_flags |= KTDF_INTERACTIVE; 1142 ktd->ktd_flags |= KTDF_INTERACTIVE;
1105 1143
1106 mutex_enter(&fp->f_lock); 1144 mutex_enter(&fp->f_lock);
1107 fp->f_count++; 1145 fp->f_count++;
1108 mutex_exit(&fp->f_lock); 1146 mutex_exit(&fp->f_lock);
1109 error = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL, 1147 error = kthread_create(PRI_NONE, KTHREAD_MPSAFE, NULL,
1110 ktrace_thread, ktd, &ktd->ktd_lwp, "ktrace"); 1148 ktrace_thread, ktd, &ktd->ktd_lwp, "ktrace");
1111 if (error != 0) { 1149 if (error != 0) {
1112 kmem_free(ktd, sizeof(*ktd)); 1150 kmem_free(ktd, sizeof(*ktd));
1113 mutex_enter(&fp->f_lock); 1151 mutex_enter(&fp->f_lock);
1114 fp->f_count--; 1152 fp->f_count--;
1115 mutex_exit(&fp->f_lock); 1153 mutex_exit(&fp->f_lock);
1116 goto done; 1154 goto done;
1117 } 1155 }
1118 1156
1119 mutex_enter(&ktrace_lock); 1157 mutex_enter(&ktrace_lock);
1120 if (ktd_lookup(fp) != NULL) { 1158 if (ktd_lookup(fp) != NULL) {
1121 ktdrel(ktd); 1159 ktdrel(ktd);
1122 ktd = NULL; 1160 ktd = NULL;
1123 } else 1161 } else
1124 TAILQ_INSERT_TAIL(&ktdq, ktd, ktd_list); 1162 TAILQ_INSERT_TAIL(&ktdq, ktd, ktd_list);
1125 if (ktd == NULL) 1163 if (ktd == NULL)
1126 cv_wait(&lbolt, &ktrace_lock); 1164 cv_wait(&lbolt, &ktrace_lock);
1127 mutex_exit(&ktrace_lock); 1165 mutex_exit(&ktrace_lock);
1128 if (ktd == NULL) 1166 if (ktd == NULL)
1129 goto done; 1167 goto done;
1130 } 1168 }
1131 break; 1169 break;
1132 1170
1133 case KTROP_CLEAR: 1171 case KTROP_CLEAR:
1134 break; 1172 break;
1135 } 1173 }
1136 1174
1137 /* 1175 /*
1138 * need something to (un)trace (XXX - why is this here?) 1176 * need something to (un)trace (XXX - why is this here?)
1139 */ 1177 */
1140 if (!facs) { 1178 if (!facs) {
1141 error = EINVAL; 1179 error = EINVAL;
1142 goto done; 1180 goto done;
1143 } 1181 }
1144 1182
1145 /* 1183 /*
1146 * do it 1184 * do it
1147 */ 1185 */
1148 mutex_enter(proc_lock); 1186 mutex_enter(proc_lock);
1149 if (pid < 0) { 1187 if (pid < 0) {
1150 /* 1188 /*
1151 * by process group 1189 * by process group
1152 */ 1190 */
1153 pg = pg_find(-pid, PFIND_LOCKED); 1191 pg = pg_find(-pid, PFIND_LOCKED);
1154 if (pg == NULL) 1192 if (pg == NULL)
1155 error = ESRCH; 1193 error = ESRCH;
1156 else { 1194 else {
1157 LIST_FOREACH(p, &pg->pg_members, p_pglist) { 1195 LIST_FOREACH(p, &pg->pg_members, p_pglist) {
1158 if (descend) 1196 if (descend)
1159 ret |= ktrsetchildren(curl, p, ops, 1197 ret |= ktrsetchildren(curl, p, ops,
1160 facs, ktd); 1198 facs, ktd);
1161 else 1199 else
1162 ret |= ktrops(curl, p, ops, facs, 1200 ret |= ktrops(curl, p, ops, facs,
1163 ktd); 1201 ktd);
1164 } 1202 }
1165 } 1203 }
1166 1204
1167 } else { 1205 } else {
1168 /* 1206 /*
1169 * by pid 1207 * by pid
1170 */ 1208 */
1171 p = p_find(pid, PFIND_LOCKED); 1209 p = p_find(pid, PFIND_LOCKED);
1172 if (p == NULL) 1210 if (p == NULL)
1173 error = ESRCH; 1211 error = ESRCH;
1174 else if (descend) 1212 else if (descend)
1175 ret |= ktrsetchildren(curl, p, ops, facs, ktd); 1213 ret |= ktrsetchildren(curl, p, ops, facs, ktd);
1176 else 1214 else
1177 ret |= ktrops(curl, p, ops, facs, ktd); 1215 ret |= ktrops(curl, p, ops, facs, ktd);
1178 } 1216 }
1179 mutex_exit(proc_lock); 1217 mutex_exit(proc_lock);
1180 if (error == 0 && !ret) 1218 if (error == 0 && !ret)
1181 error = EPERM; 1219 error = EPERM;
1182done: 1220done:
1183 if (ktd != NULL) { 1221 if (ktd != NULL) {
1184 mutex_enter(&ktrace_lock); 1222 mutex_enter(&ktrace_lock);
1185 if (error != 0) { 1223 if (error != 0) {
1186 /* 1224 /*
1187 * Wakeup the thread so that it can be die if we 1225 * Wakeup the thread so that it can be die if we
1188 * can't trace any process. 1226 * can't trace any process.
1189 */ 1227 */
1190 ktd_wakeup(ktd); 1228 ktd_wakeup(ktd);
1191 } 1229 }
1192 if (KTROP(ops) == KTROP_SET || KTROP(ops) == KTROP_CLEARFILE) 1230 if (KTROP(ops) == KTROP_SET || KTROP(ops) == KTROP_CLEARFILE)
1193 ktdrel(ktd); 1231 ktdrel(ktd);
1194 mutex_exit(&ktrace_lock); 1232 mutex_exit(&ktrace_lock);
1195 } 1233 }
1196 ktrexit(curl); 1234 ktrexit(curl);
1197 return (error); 1235 return (error);
1198} 1236}
1199 1237
1200/* 1238/*
1201 * fktrace system call 1239 * fktrace system call
1202 */ 1240 */
1203/* ARGSUSED */ 1241/* ARGSUSED */
1204int 1242int
1205sys_fktrace(struct lwp *l, const struct sys_fktrace_args *uap, register_t *retval) 1243sys_fktrace(struct lwp *l, const struct sys_fktrace_args *uap, register_t *retval)
1206{ 1244{
1207 /* { 1245 /* {
1208 syscallarg(int) fd; 1246 syscallarg(int) fd;
1209 syscallarg(int) ops; 1247 syscallarg(int) ops;
1210 syscallarg(int) facs; 1248 syscallarg(int) facs;
1211 syscallarg(int) pid; 1249 syscallarg(int) pid;
1212 } */ 1250 } */
1213 file_t *fp; 1251 file_t *fp;
1214 int error, fd; 1252 int error, fd;
1215 1253
1216 fd = SCARG(uap, fd); 1254 fd = SCARG(uap, fd);
1217 if ((fp = fd_getfile(fd)) == NULL) 1255 if ((fp = fd_getfile(fd)) == NULL)
1218 return (EBADF); 1256 return (EBADF);
1219 if ((fp->f_flag & FWRITE) == 0) 1257 if ((fp->f_flag & FWRITE) == 0)
1220 error = EBADF; 1258 error = EBADF;
1221 else 1259 else
1222 error = ktrace_common(l, SCARG(uap, ops), 1260 error = ktrace_common(l, SCARG(uap, ops),
1223 SCARG(uap, facs), SCARG(uap, pid), fp); 1261 SCARG(uap, facs), SCARG(uap, pid), fp);
1224 fd_putfile(fd); 1262 fd_putfile(fd);
1225 return error; 1263 return error;
1226} 1264}
1227 1265
1228/* 1266/*
1229 * ktrace system call 1267 * ktrace system call
1230 */ 1268 */
1231/* ARGSUSED */ 1269/* ARGSUSED */
1232int 1270int
1233sys_ktrace(struct lwp *l, const struct sys_ktrace_args *uap, register_t *retval) 1271sys_ktrace(struct lwp *l, const struct sys_ktrace_args *uap, register_t *retval)
1234{ 1272{
1235 /* { 1273 /* {
1236 syscallarg(const char *) fname; 1274 syscallarg(const char *) fname;
1237 syscallarg(int) ops; 1275 syscallarg(int) ops;
1238 syscallarg(int) facs; 1276 syscallarg(int) facs;
1239 syscallarg(int) pid; 1277 syscallarg(int) pid;
1240 } */ 1278 } */
1241 struct vnode *vp = NULL; 1279 struct vnode *vp = NULL;
1242 file_t *fp = NULL; 1280 file_t *fp = NULL;
1243 struct nameidata nd; 1281 struct nameidata nd;
1244 int error = 0; 1282 int error = 0;
1245 int fd; 1283 int fd;
1246 1284
1247 if (ktrenter(l)) 1285 if (ktrenter(l))
1248 return EAGAIN; 1286 return EAGAIN;

cvs diff -r1.1 -r1.2 src/sys/secmodel/suser/secmodel_suser.c (switch to unified diff)

--- src/sys/secmodel/suser/secmodel_suser.c 2009/10/02 18:50:13 1.1
+++ src/sys/secmodel/suser/secmodel_suser.c 2009/10/02 21:47:35 1.2
@@ -1,1313 +1,1291 @@ @@ -1,1313 +1,1291 @@
1/* $NetBSD: secmodel_suser.c,v 1.1 2009/10/02 18:50:13 elad Exp $ */ 1/* $NetBSD: secmodel_suser.c,v 1.2 2009/10/02 21:47:35 elad Exp $ */
2/*- 2/*-
3 * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org> 3 * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
4 * All rights reserved. 4 * All rights reserved.
5 * 5 *
6 * Redistribution and use in source and binary forms, with or without 6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions 7 * modification, are permitted provided that the following conditions
8 * are met: 8 * are met:
9 * 1. Redistributions of source code must retain the above copyright 9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer. 10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright 11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the 12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution. 13 * documentation and/or other materials provided with the distribution.
14 * 3. The name of the author may not be used to endorse or promote products 14 * 3. The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission. 15 * derived from this software without specific prior written permission.
16 * 16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */ 27 */
28 28
29/* 29/*
30 * This file contains kauth(9) listeners needed to implement the traditional 30 * This file contains kauth(9) listeners needed to implement the traditional
31 * NetBSD superuser access restrictions. 31 * NetBSD superuser access restrictions.
32 * 32 *
33 * There are two main resources a request can be issued to: user-owned and 33 * There are two main resources a request can be issued to: user-owned and
34 * system owned. For the first, traditional Unix access checks are done, as 34 * system owned. For the first, traditional Unix access checks are done, as
35 * well as superuser checks. If needed, the request context is examined before 35 * well as superuser checks. If needed, the request context is examined before
36 * a decision is made. For the latter, usually only superuser checks are done 36 * a decision is made. For the latter, usually only superuser checks are done
37 * as normal users are not allowed to access system resources. 37 * as normal users are not allowed to access system resources.
38 */ 38 */
39 39
40#include <sys/cdefs.h> 40#include <sys/cdefs.h>
41__KERNEL_RCSID(0, "$NetBSD: secmodel_suser.c,v 1.1 2009/10/02 18:50:13 elad Exp $"); 41__KERNEL_RCSID(0, "$NetBSD: secmodel_suser.c,v 1.2 2009/10/02 21:47:35 elad Exp $");
42 42
43#include <sys/types.h> 43#include <sys/types.h>
44#include <sys/param.h> 44#include <sys/param.h>
45#include <sys/kauth.h> 45#include <sys/kauth.h>
46 46
47#include <sys/acct.h> 47#include <sys/acct.h>
48#include <sys/mutex.h> 48#include <sys/mutex.h>
49#include <sys/ktrace.h> 49#include <sys/ktrace.h>
50#include <sys/mount.h> 50#include <sys/mount.h>
51#include <sys/pset.h> 51#include <sys/pset.h>
52#include <sys/socketvar.h> 52#include <sys/socketvar.h>
53#include <sys/sysctl.h> 53#include <sys/sysctl.h>
54#include <sys/tty.h> 54#include <sys/tty.h>
55#include <net/route.h> 55#include <net/route.h>
56#include <sys/ptrace.h> 56#include <sys/ptrace.h>
57#include <sys/vnode.h> 57#include <sys/vnode.h>
58#include <sys/proc.h> 58#include <sys/proc.h>
59#include <sys/uidinfo.h> 59#include <sys/uidinfo.h>
60#include <sys/module.h> 60#include <sys/module.h>
61 61
62#include <miscfs/procfs/procfs.h> 62#include <miscfs/procfs/procfs.h>
63 63
64#include <secmodel/suser/suser.h> 64#include <secmodel/suser/suser.h>
65 65
66MODULE(MODULE_CLASS_SECMODEL, suser, NULL); 66MODULE(MODULE_CLASS_SECMODEL, suser, NULL);
67 67
68static int secmodel_bsd44_curtain; 68static int secmodel_bsd44_curtain;
69/* static */ int dovfsusermount; 69/* static */ int dovfsusermount;
70 70
71static kauth_listener_t l_generic, l_system, l_process, l_network, l_machdep, 71static kauth_listener_t l_generic, l_system, l_process, l_network, l_machdep,
72 l_device, l_vnode; 72 l_device, l_vnode;
73 73
74static struct sysctllog *suser_sysctl_log; 74static struct sysctllog *suser_sysctl_log;
75 75
76void 76void
77sysctl_security_suser_setup(struct sysctllog **clog) 77sysctl_security_suser_setup(struct sysctllog **clog)
78{ 78{
79 const struct sysctlnode *rnode; 79 const struct sysctlnode *rnode;
80 80
81 sysctl_createv(clog, 0, NULL, &rnode, 81 sysctl_createv(clog, 0, NULL, &rnode,
82 CTLFLAG_PERMANENT, 82 CTLFLAG_PERMANENT,
83 CTLTYPE_NODE, "security", NULL, 83 CTLTYPE_NODE, "security", NULL,
84 NULL, 0, NULL, 0, 84 NULL, 0, NULL, 0,
85 CTL_SECURITY, CTL_EOL); 85 CTL_SECURITY, CTL_EOL);
86 86
87 sysctl_createv(clog, 0, &rnode, &rnode, 87 sysctl_createv(clog, 0, &rnode, &rnode,
88 CTLFLAG_PERMANENT, 88 CTLFLAG_PERMANENT,
89 CTLTYPE_NODE, "models", NULL, 89 CTLTYPE_NODE, "models", NULL,
90 NULL, 0, NULL, 0, 90 NULL, 0, NULL, 0,
91 CTL_CREATE, CTL_EOL); 91 CTL_CREATE, CTL_EOL);
92 92
93 sysctl_createv(clog, 0, &rnode, &rnode, 93 sysctl_createv(clog, 0, &rnode, &rnode,
94 CTLFLAG_PERMANENT, 94 CTLFLAG_PERMANENT,
95 CTLTYPE_NODE, "suser", NULL, 95 CTLTYPE_NODE, "suser", NULL,
96 NULL, 0, NULL, 0, 96 NULL, 0, NULL, 0,
97 CTL_CREATE, CTL_EOL); 97 CTL_CREATE, CTL_EOL);
98 98
99 sysctl_createv(clog, 0, &rnode, NULL, 99 sysctl_createv(clog, 0, &rnode, NULL,
100 CTLFLAG_PERMANENT, 100 CTLFLAG_PERMANENT,
101 CTLTYPE_STRING, "name", NULL, 101 CTLTYPE_STRING, "name", NULL,
102 NULL, 0, __UNCONST("Traditional NetBSD: Superuser"), 0, 102 NULL, 0, __UNCONST("Traditional NetBSD: Superuser"), 0,
103 CTL_CREATE, CTL_EOL); 103 CTL_CREATE, CTL_EOL);
104 104
105 sysctl_createv(clog, 0, &rnode, NULL, 105 sysctl_createv(clog, 0, &rnode, NULL,
106 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 106 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
107 CTLTYPE_INT, "curtain", 107 CTLTYPE_INT, "curtain",
108 SYSCTL_DESCR("Curtain information about objects to "\ 108 SYSCTL_DESCR("Curtain information about objects to "\
109 "users not owning them."), 109 "users not owning them."),
110 NULL, 0, &secmodel_bsd44_curtain, 0, 110 NULL, 0, &secmodel_bsd44_curtain, 0,
111 CTL_CREATE, CTL_EOL); 111 CTL_CREATE, CTL_EOL);
112 112
113 sysctl_createv(clog, 0, &rnode, NULL, 113 sysctl_createv(clog, 0, &rnode, NULL,
114 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 114 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
115 CTLTYPE_INT, "usermount", 115 CTLTYPE_INT, "usermount",
116 SYSCTL_DESCR("Whether unprivileged users may mount " 116 SYSCTL_DESCR("Whether unprivileged users may mount "
117 "filesystems"), 117 "filesystems"),
118 NULL, 0, &dovfsusermount, 0, 118 NULL, 0, &dovfsusermount, 0,
119 CTL_CREATE, CTL_EOL); 119 CTL_CREATE, CTL_EOL);
120 120
121 /* Compatibility: security.curtain */ 121 /* Compatibility: security.curtain */
122 sysctl_createv(clog, 0, NULL, &rnode, 122 sysctl_createv(clog, 0, NULL, &rnode,
123 CTLFLAG_PERMANENT, 123 CTLFLAG_PERMANENT,
124 CTLTYPE_NODE, "security", NULL, 124 CTLTYPE_NODE, "security", NULL,
125 NULL, 0, NULL, 0, 125 NULL, 0, NULL, 0,
126 CTL_SECURITY, CTL_EOL); 126 CTL_SECURITY, CTL_EOL);
127 127
128 sysctl_createv(clog, 0, &rnode, NULL, 128 sysctl_createv(clog, 0, &rnode, NULL,
129 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 129 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
130 CTLTYPE_INT, "curtain", 130 CTLTYPE_INT, "curtain",
131 SYSCTL_DESCR("Curtain information about objects to "\ 131 SYSCTL_DESCR("Curtain information about objects to "\
132 "users not owning them."), 132 "users not owning them."),
133 NULL, 0, &secmodel_bsd44_curtain, 0, 133 NULL, 0, &secmodel_bsd44_curtain, 0,
134 CTL_CREATE, CTL_EOL); 134 CTL_CREATE, CTL_EOL);
135 135
136 /* Compatibility: vfs.generic.usermount */ 136 /* Compatibility: vfs.generic.usermount */
137 sysctl_createv(clog, 0, NULL, NULL, 137 sysctl_createv(clog, 0, NULL, NULL,
138 CTLFLAG_PERMANENT, 138 CTLFLAG_PERMANENT,
139 CTLTYPE_NODE, "vfs", NULL, 139 CTLTYPE_NODE, "vfs", NULL,
140 NULL, 0, NULL, 0, 140 NULL, 0, NULL, 0,
141 CTL_VFS, CTL_EOL); 141 CTL_VFS, CTL_EOL);
142 142
143 sysctl_createv(clog, 0, NULL, NULL, 143 sysctl_createv(clog, 0, NULL, NULL,
144 CTLFLAG_PERMANENT, 144 CTLFLAG_PERMANENT,
145 CTLTYPE_NODE, "generic", 145 CTLTYPE_NODE, "generic",
146 SYSCTL_DESCR("Non-specific vfs related information"), 146 SYSCTL_DESCR("Non-specific vfs related information"),
147 NULL, 0, NULL, 0, 147 NULL, 0, NULL, 0,
148 CTL_VFS, VFS_GENERIC, CTL_EOL); 148 CTL_VFS, VFS_GENERIC, CTL_EOL);
149 149
150 sysctl_createv(clog, 0, NULL, NULL, 150 sysctl_createv(clog, 0, NULL, NULL,
151 CTLFLAG_PERMANENT|CTLFLAG_READWRITE, 151 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
152 CTLTYPE_INT, "usermount", 152 CTLTYPE_INT, "usermount",
153 SYSCTL_DESCR("Whether unprivileged users may mount " 153 SYSCTL_DESCR("Whether unprivileged users may mount "
154 "filesystems"), 154 "filesystems"),
155 NULL, 0, &dovfsusermount, 0, 155 NULL, 0, &dovfsusermount, 0,
156 CTL_VFS, VFS_GENERIC, VFS_USERMOUNT, CTL_EOL); 156 CTL_VFS, VFS_GENERIC, VFS_USERMOUNT, CTL_EOL);
157} 157}
158 158
159void 159void
160secmodel_suser_init(void) 160secmodel_suser_init(void)
161{ 161{
162 secmodel_bsd44_curtain = 0; 162 secmodel_bsd44_curtain = 0;
163 dovfsusermount = 0; 163 dovfsusermount = 0;
164} 164}
165 165
166void 166void
167secmodel_suser_start(void) 167secmodel_suser_start(void)
168{ 168{
169 l_generic = kauth_listen_scope(KAUTH_SCOPE_GENERIC, 169 l_generic = kauth_listen_scope(KAUTH_SCOPE_GENERIC,
170 secmodel_suser_generic_cb, NULL); 170 secmodel_suser_generic_cb, NULL);
171 l_system = kauth_listen_scope(KAUTH_SCOPE_SYSTEM, 171 l_system = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
172 secmodel_suser_system_cb, NULL); 172 secmodel_suser_system_cb, NULL);
173 l_process = kauth_listen_scope(KAUTH_SCOPE_PROCESS, 173 l_process = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
174 secmodel_suser_process_cb, NULL); 174 secmodel_suser_process_cb, NULL);
175 l_network = kauth_listen_scope(KAUTH_SCOPE_NETWORK, 175 l_network = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
176 secmodel_suser_network_cb, NULL); 176 secmodel_suser_network_cb, NULL);
177 l_machdep = kauth_listen_scope(KAUTH_SCOPE_MACHDEP, 177 l_machdep = kauth_listen_scope(KAUTH_SCOPE_MACHDEP,
178 secmodel_suser_machdep_cb, NULL); 178 secmodel_suser_machdep_cb, NULL);
179 l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE, 179 l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
180 secmodel_suser_device_cb, NULL); 180 secmodel_suser_device_cb, NULL);
181 l_vnode = kauth_listen_scope(KAUTH_SCOPE_VNODE, 181 l_vnode = kauth_listen_scope(KAUTH_SCOPE_VNODE,
182 secmodel_suser_vnode_cb, NULL); 182 secmodel_suser_vnode_cb, NULL);
183} 183}
184 184
185void 185void
186secmodel_suser_stop(void) 186secmodel_suser_stop(void)
187{ 187{
188 kauth_unlisten_scope(l_generic); 188 kauth_unlisten_scope(l_generic);
189 kauth_unlisten_scope(l_system); 189 kauth_unlisten_scope(l_system);
190 kauth_unlisten_scope(l_process); 190 kauth_unlisten_scope(l_process);
191 kauth_unlisten_scope(l_network); 191 kauth_unlisten_scope(l_network);
192 kauth_unlisten_scope(l_machdep); 192 kauth_unlisten_scope(l_machdep);
193 kauth_unlisten_scope(l_device); 193 kauth_unlisten_scope(l_device);
194 kauth_unlisten_scope(l_vnode); 194 kauth_unlisten_scope(l_vnode);
195} 195}
196 196
197static int 197static int
198suser_modcmd(modcmd_t cmd, void *arg) 198suser_modcmd(modcmd_t cmd, void *arg)
199{ 199{
200 int error = 0; 200 int error = 0;
201 201
202 switch (cmd) { 202 switch (cmd) {
203 case MODULE_CMD_INIT: 203 case MODULE_CMD_INIT:
204 secmodel_suser_init(); 204 secmodel_suser_init();
205 secmodel_suser_start(); 205 secmodel_suser_start();
206 sysctl_security_suser_setup(&suser_sysctl_log); 206 sysctl_security_suser_setup(&suser_sysctl_log);
207 break; 207 break;
208 208
209 case MODULE_CMD_FINI: 209 case MODULE_CMD_FINI:
210 sysctl_teardown(&suser_sysctl_log); 210 sysctl_teardown(&suser_sysctl_log);
211 secmodel_suser_stop(); 211 secmodel_suser_stop();
212 break; 212 break;
213 213
214 case MODULE_CMD_AUTOUNLOAD: 214 case MODULE_CMD_AUTOUNLOAD:
215 error = EPERM; 215 error = EPERM;
216 break; 216 break;
217 217
218 default: 218 default:
219 error = ENOTTY; 219 error = ENOTTY;
220 break; 220 break;
221 } 221 }
222 222
223 return (error); 223 return (error);
224} 224}
225 225
226/* 226/*
227 * kauth(9) listener 227 * kauth(9) listener
228 * 228 *
229 * Security model: Traditional NetBSD 229 * Security model: Traditional NetBSD
230 * Scope: Generic 230 * Scope: Generic
231 * Responsibility: Superuser access 231 * Responsibility: Superuser access
232 */ 232 */
233int 233int
234secmodel_suser_generic_cb(kauth_cred_t cred, kauth_action_t action, 234secmodel_suser_generic_cb(kauth_cred_t cred, kauth_action_t action,
235 void *cookie, void *arg0, void *arg1, 235 void *cookie, void *arg0, void *arg1,
236 void *arg2, void *arg3) 236 void *arg2, void *arg3)
237{ 237{
238 bool isroot; 238 bool isroot;
239 int result; 239 int result;
240 240
241 isroot = (kauth_cred_geteuid(cred) == 0); 241 isroot = (kauth_cred_geteuid(cred) == 0);
242 result = KAUTH_RESULT_DEFER; 242 result = KAUTH_RESULT_DEFER;
243 243
244 switch (action) { 244 switch (action) {
245 case KAUTH_GENERIC_ISSUSER: 245 case KAUTH_GENERIC_ISSUSER:
246 if (isroot) 246 if (isroot)
247 result = KAUTH_RESULT_ALLOW; 247 result = KAUTH_RESULT_ALLOW;
248 break; 248 break;
249 249
250 case KAUTH_GENERIC_CANSEE:  250 case KAUTH_GENERIC_CANSEE:
251 if (!secmodel_bsd44_curtain) 251 if (!secmodel_bsd44_curtain)
252 result = KAUTH_RESULT_ALLOW; 252 result = KAUTH_RESULT_ALLOW;
253 else if (isroot || kauth_cred_uidmatch(cred, arg0)) 253 else if (isroot || kauth_cred_uidmatch(cred, arg0))
254 result = KAUTH_RESULT_ALLOW; 254 result = KAUTH_RESULT_ALLOW;
255 255
256 break; 256 break;
257 257
258 default: 258 default:
259 result = KAUTH_RESULT_DEFER; 259 result = KAUTH_RESULT_DEFER;
260 break; 260 break;
261 } 261 }
262 262
263 return (result); 263 return (result);
264} 264}
265 265
266/* 266/*
267 * kauth(9) listener 267 * kauth(9) listener
268 * 268 *
269 * Security model: Traditional NetBSD 269 * Security model: Traditional NetBSD
270 * Scope: System 270 * Scope: System
271 * Responsibility: Superuser access 271 * Responsibility: Superuser access
272 */ 272 */
273int 273int
274secmodel_suser_system_cb(kauth_cred_t cred, kauth_action_t action, 274secmodel_suser_system_cb(kauth_cred_t cred, kauth_action_t action,
275 void *cookie, void *arg0, void *arg1, 275 void *cookie, void *arg0, void *arg1,
276 void *arg2, void *arg3) 276 void *arg2, void *arg3)
277{ 277{
278 bool isroot; 278 bool isroot;
279 int result; 279 int result;
280 enum kauth_system_req req; 280 enum kauth_system_req req;
281 281
282 isroot = (kauth_cred_geteuid(cred) == 0); 282 isroot = (kauth_cred_geteuid(cred) == 0);
283 result = KAUTH_RESULT_DEFER; 283 result = KAUTH_RESULT_DEFER;
284 req = (enum kauth_system_req)arg0; 284 req = (enum kauth_system_req)arg0;
285 285
286 switch (action) { 286 switch (action) {
287 case KAUTH_SYSTEM_CPU: 287 case KAUTH_SYSTEM_CPU:
288 switch (req) { 288 switch (req) {
289 case KAUTH_REQ_SYSTEM_CPU_SETSTATE: 289 case KAUTH_REQ_SYSTEM_CPU_SETSTATE:
290 if (isroot) 290 if (isroot)
291 result = KAUTH_RESULT_ALLOW; 291 result = KAUTH_RESULT_ALLOW;
292 292
293 break; 293 break;
294 294
295 default: 295 default:
296 break; 296 break;
297 } 297 }
298 298
299 break; 299 break;
300 300
301 case KAUTH_SYSTEM_FS_QUOTA: 301 case KAUTH_SYSTEM_FS_QUOTA:
302 switch (req) { 302 switch (req) {
303 case KAUTH_REQ_SYSTEM_FS_QUOTA_GET: 303 case KAUTH_REQ_SYSTEM_FS_QUOTA_GET:
304 case KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF: 304 case KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF:
305 case KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE: 305 case KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE:
306 case KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT: 306 case KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT:
307 if (isroot) 307 if (isroot)
308 result = KAUTH_RESULT_ALLOW; 308 result = KAUTH_RESULT_ALLOW;
309 break; 309 break;
310 310
311 default: 311 default:
312 break; 312 break;
313 } 313 }
314 314
315 break; 315 break;
316 316
317 case KAUTH_SYSTEM_FS_RESERVEDSPACE: 317 case KAUTH_SYSTEM_FS_RESERVEDSPACE:
318 if (isroot) 318 if (isroot)
319 result = KAUTH_RESULT_ALLOW; 319 result = KAUTH_RESULT_ALLOW;
320 break; 320 break;
321 321
322 case KAUTH_SYSTEM_MOUNT: 322 case KAUTH_SYSTEM_MOUNT:
323 switch (req) { 323 switch (req) {
324 case KAUTH_REQ_SYSTEM_MOUNT_GET: 324 case KAUTH_REQ_SYSTEM_MOUNT_GET:
325 result = KAUTH_RESULT_ALLOW; 325 result = KAUTH_RESULT_ALLOW;
326 break; 326 break;
327 327
328 case KAUTH_REQ_SYSTEM_MOUNT_NEW: 328 case KAUTH_REQ_SYSTEM_MOUNT_NEW:
329 if (isroot) 329 if (isroot)
330 result = KAUTH_RESULT_ALLOW; 330 result = KAUTH_RESULT_ALLOW;
331 else if (dovfsusermount) { 331 else if (dovfsusermount) {
332 struct vnode *vp = arg1; 332 struct vnode *vp = arg1;
333 u_long flags = (u_long)arg2; 333 u_long flags = (u_long)arg2;
334 334
335 if (!(flags & MNT_NODEV) || 335 if (!(flags & MNT_NODEV) ||
336 !(flags & MNT_NOSUID)) 336 !(flags & MNT_NOSUID))
337 break; 337 break;
338 338
339 if ((vp->v_mount->mnt_flag & MNT_NOEXEC) && 339 if ((vp->v_mount->mnt_flag & MNT_NOEXEC) &&
340 !(flags & MNT_NOEXEC)) 340 !(flags & MNT_NOEXEC))
341 break; 341 break;
342 342
343 result = KAUTH_RESULT_ALLOW; 343 result = KAUTH_RESULT_ALLOW;
344 } 344 }
345 345
346 break; 346 break;
347 347
348 case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT: 348 case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT:
349 if (isroot) 349 if (isroot)
350 result = KAUTH_RESULT_ALLOW; 350 result = KAUTH_RESULT_ALLOW;
351 else { 351 else {
352 struct mount *mp = arg1; 352 struct mount *mp = arg1;
353 353
354 if (mp->mnt_stat.f_owner == 354 if (mp->mnt_stat.f_owner ==
355 kauth_cred_geteuid(cred)) 355 kauth_cred_geteuid(cred))
356 result = KAUTH_RESULT_ALLOW; 356 result = KAUTH_RESULT_ALLOW;
357 } 357 }
358 358
359 break; 359 break;
360 360
361 case KAUTH_REQ_SYSTEM_MOUNT_UPDATE: 361 case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
362 if (isroot) 362 if (isroot)
363 result = KAUTH_RESULT_ALLOW; 363 result = KAUTH_RESULT_ALLOW;
364 else if (dovfsusermount) { 364 else if (dovfsusermount) {
365 struct mount *mp = arg1; 365 struct mount *mp = arg1;
366 u_long flags = (u_long)arg2; 366 u_long flags = (u_long)arg2;
367 367
368 /* No exporting for non-root. */ 368 /* No exporting for non-root. */
369 if (flags & MNT_EXPORTED) 369 if (flags & MNT_EXPORTED)
370 break; 370 break;
371 371
372 if (!(flags & MNT_NODEV) || 372 if (!(flags & MNT_NODEV) ||
373 !(flags & MNT_NOSUID)) 373 !(flags & MNT_NOSUID))
374 break; 374 break;
375 375
376 /* 376 /*
377 * Only super-user, or user that did the mount, 377 * Only super-user, or user that did the mount,
378 * can update. 378 * can update.
379 */ 379 */
380 if (mp->mnt_stat.f_owner != 380 if (mp->mnt_stat.f_owner !=
381 kauth_cred_geteuid(cred)) 381 kauth_cred_geteuid(cred))
382 break; 382 break;
383 383
384 /* Retain 'noexec'. */ 384 /* Retain 'noexec'. */
385 if ((mp->mnt_flag & MNT_NOEXEC) && 385 if ((mp->mnt_flag & MNT_NOEXEC) &&
386 !(flags & MNT_NOEXEC)) 386 !(flags & MNT_NOEXEC))
387 break; 387 break;
388 388
389 result = KAUTH_RESULT_ALLOW; 389 result = KAUTH_RESULT_ALLOW;
390 } 390 }
391 391
392 break; 392 break;
393 393
394 default: 394 default:
395 result = KAUTH_RESULT_DEFER; 395 result = KAUTH_RESULT_DEFER;
396 break; 396 break;
397 } 397 }
398 398
399 break; 399 break;
400 400
401 case KAUTH_SYSTEM_PSET: { 401 case KAUTH_SYSTEM_PSET: {
402 psetid_t id; 402 psetid_t id;
403 403
404 id = (psetid_t)(unsigned long)arg1; 404 id = (psetid_t)(unsigned long)arg1;
405 405
406 switch (req) { 406 switch (req) {
407 case KAUTH_REQ_SYSTEM_PSET_ASSIGN: 407 case KAUTH_REQ_SYSTEM_PSET_ASSIGN:
408 case KAUTH_REQ_SYSTEM_PSET_BIND: 408 case KAUTH_REQ_SYSTEM_PSET_BIND:
409 if (isroot || id == PS_QUERY) 409 if (isroot || id == PS_QUERY)
410 result = KAUTH_RESULT_ALLOW; 410 result = KAUTH_RESULT_ALLOW;
411 411
412 break; 412 break;
413 413
414 case KAUTH_REQ_SYSTEM_PSET_CREATE: 414 case KAUTH_REQ_SYSTEM_PSET_CREATE:
415 case KAUTH_REQ_SYSTEM_PSET_DESTROY: 415 case KAUTH_REQ_SYSTEM_PSET_DESTROY:
416 if (isroot) 416 if (isroot)
417 result = KAUTH_RESULT_ALLOW; 417 result = KAUTH_RESULT_ALLOW;
418 418
419 break; 419 break;
420 420
421 default: 421 default:
422 break; 422 break;
423 } 423 }
424 424
425 break; 425 break;
426 } 426 }
427 427
428 case KAUTH_SYSTEM_TIME: 428 case KAUTH_SYSTEM_TIME:
429 switch (req) { 429 switch (req) {
430 case KAUTH_REQ_SYSTEM_TIME_ADJTIME: 430 case KAUTH_REQ_SYSTEM_TIME_ADJTIME:
431 case KAUTH_REQ_SYSTEM_TIME_NTPADJTIME: 431 case KAUTH_REQ_SYSTEM_TIME_NTPADJTIME:
432 case KAUTH_REQ_SYSTEM_TIME_TIMECOUNTERS: 432 case KAUTH_REQ_SYSTEM_TIME_TIMECOUNTERS:
433 if (isroot) 433 if (isroot)
434 result = KAUTH_RESULT_ALLOW; 434 result = KAUTH_RESULT_ALLOW;
435 break; 435 break;
436 436
437 case KAUTH_REQ_SYSTEM_TIME_SYSTEM: { 437 case KAUTH_REQ_SYSTEM_TIME_SYSTEM: {
438 bool device_context = (bool)arg3; 438 bool device_context = (bool)arg3;
439 439
440 if (device_context || isroot) 440 if (device_context || isroot)
441 result = KAUTH_RESULT_ALLOW; 441 result = KAUTH_RESULT_ALLOW;
442 442
443 break; 443 break;
444 } 444 }
445 445
446 case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET: 446 case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET:
447 if (isroot) 447 if (isroot)
448 result = KAUTH_RESULT_ALLOW; 448 result = KAUTH_RESULT_ALLOW;
449 break; 449 break;
450 450
451 default: 451 default:
452 result = KAUTH_RESULT_DEFER; 452 result = KAUTH_RESULT_DEFER;
453 break; 453 break;
454 } 454 }
455 break; 455 break;
456 456
457 case KAUTH_SYSTEM_SYSCTL: 457 case KAUTH_SYSTEM_SYSCTL:
458 switch (req) { 458 switch (req) {
459 case KAUTH_REQ_SYSTEM_SYSCTL_ADD: 459 case KAUTH_REQ_SYSTEM_SYSCTL_ADD:
460 case KAUTH_REQ_SYSTEM_SYSCTL_DELETE: 460 case KAUTH_REQ_SYSTEM_SYSCTL_DELETE:
461 case KAUTH_REQ_SYSTEM_SYSCTL_DESC: 461 case KAUTH_REQ_SYSTEM_SYSCTL_DESC:
462 case KAUTH_REQ_SYSTEM_SYSCTL_MODIFY: 462 case KAUTH_REQ_SYSTEM_SYSCTL_MODIFY:
463 case KAUTH_REQ_SYSTEM_SYSCTL_PRVT: 463 case KAUTH_REQ_SYSTEM_SYSCTL_PRVT:
464 if (isroot) 464 if (isroot)
465 result = KAUTH_RESULT_ALLOW; 465 result = KAUTH_RESULT_ALLOW;
466 break; 466 break;
467 467
468 default: 468 default:
469 break; 469 break;
470 } 470 }
471 471
472 break; 472 break;
473 473
474 case KAUTH_SYSTEM_SWAPCTL: 474 case KAUTH_SYSTEM_SWAPCTL:
475 case KAUTH_SYSTEM_ACCOUNTING: 475 case KAUTH_SYSTEM_ACCOUNTING:
476 case KAUTH_SYSTEM_REBOOT: 476 case KAUTH_SYSTEM_REBOOT:
477 case KAUTH_SYSTEM_CHROOT: 477 case KAUTH_SYSTEM_CHROOT:
478 case KAUTH_SYSTEM_FILEHANDLE: 478 case KAUTH_SYSTEM_FILEHANDLE:
479 case KAUTH_SYSTEM_MKNOD: 479 case KAUTH_SYSTEM_MKNOD:
480 if (isroot) 480 if (isroot)
481 result = KAUTH_RESULT_ALLOW; 481 result = KAUTH_RESULT_ALLOW;
482 break; 482 break;
483 483
484 case KAUTH_SYSTEM_DEBUG: 484 case KAUTH_SYSTEM_DEBUG:
485 switch (req) { 485 switch (req) {
486 case KAUTH_REQ_SYSTEM_DEBUG_IPKDB: 486 case KAUTH_REQ_SYSTEM_DEBUG_IPKDB:
487 default: 487 default:
488 /* Decisions are root-agnostic. */ 488 /* Decisions are root-agnostic. */
489 result = KAUTH_RESULT_ALLOW; 489 result = KAUTH_RESULT_ALLOW;
490 break; 490 break;
491 } 491 }
492 492
493 break; 493 break;
494 494
495 case KAUTH_SYSTEM_CHSYSFLAGS: 495 case KAUTH_SYSTEM_CHSYSFLAGS:
496 /* 496 /*
497 * Needs to be checked in conjunction with the immutable and 497 * Needs to be checked in conjunction with the immutable and
498 * append-only flags (usually). Should be handled differently. 498 * append-only flags (usually). Should be handled differently.
499 * Infects ufs, ext2fs, tmpfs, and rump. 499 * Infects ufs, ext2fs, tmpfs, and rump.
500 */ 500 */
501 if (isroot) 501 if (isroot)
502 result = KAUTH_RESULT_ALLOW; 502 result = KAUTH_RESULT_ALLOW;
503 503
504 break; 504 break;
505 505
506 case KAUTH_SYSTEM_SETIDCORE: 506 case KAUTH_SYSTEM_SETIDCORE:
507 if (isroot) 507 if (isroot)
508 result = KAUTH_RESULT_ALLOW; 508 result = KAUTH_RESULT_ALLOW;
509 509
510 break; 510 break;
511 511
512 case KAUTH_SYSTEM_MODULE: 512 case KAUTH_SYSTEM_MODULE:
513 if (isroot) 513 if (isroot)
514 result = KAUTH_RESULT_ALLOW; 514 result = KAUTH_RESULT_ALLOW;
515 if ((uintptr_t)arg2 != 0) /* autoload */ 515 if ((uintptr_t)arg2 != 0) /* autoload */
516 result = KAUTH_RESULT_ALLOW; 516 result = KAUTH_RESULT_ALLOW;
517 break; 517 break;
518 518
519 default: 519 default:
520 result = KAUTH_RESULT_DEFER; 520 result = KAUTH_RESULT_DEFER;
521 break; 521 break;
522 } 522 }
523 523
524 return (result); 524 return (result);
525} 525}
526 526
527/* 527/*
528 * common code for corename, rlimit, and stopflag. 528 * common code for corename, rlimit, and stopflag.
529 */ 529 */
530static int 530static int
531proc_uidmatch(kauth_cred_t cred, kauth_cred_t target) 531proc_uidmatch(kauth_cred_t cred, kauth_cred_t target)
532{ 532{
533 int r = 0; 533 int r = 0;
534 534
535 if (kauth_cred_getuid(cred) != kauth_cred_getuid(target) || 535 if (kauth_cred_getuid(cred) != kauth_cred_getuid(target) ||
536 kauth_cred_getuid(cred) != kauth_cred_getsvuid(target)) { 536 kauth_cred_getuid(cred) != kauth_cred_getsvuid(target)) {
537 /* 537 /*
538 * suid proc of ours or proc not ours 538 * suid proc of ours or proc not ours
539 */ 539 */
540 r = EPERM; 540 r = EPERM;
541 } else if (kauth_cred_getgid(target) != kauth_cred_getsvgid(target)) { 541 } else if (kauth_cred_getgid(target) != kauth_cred_getsvgid(target)) {
542 /* 542 /*
543 * sgid proc has sgid back to us temporarily 543 * sgid proc has sgid back to us temporarily
544 */ 544 */
545 r = EPERM; 545 r = EPERM;
546 } else { 546 } else {
547 /* 547 /*
548 * our rgid must be in target's group list (ie, 548 * our rgid must be in target's group list (ie,
549 * sub-processes started by a sgid process) 549 * sub-processes started by a sgid process)
550 */ 550 */
551 int ismember = 0; 551 int ismember = 0;
552 552
553 if (kauth_cred_ismember_gid(cred, 553 if (kauth_cred_ismember_gid(cred,
554 kauth_cred_getgid(target), &ismember) != 0 || 554 kauth_cred_getgid(target), &ismember) != 0 ||
555 !ismember) 555 !ismember)
556 r = EPERM; 556 r = EPERM;
557 } 557 }
558 558
559 return (r); 559 return (r);
560} 560}
561 561
562/* 562/*
563 * kauth(9) listener 563 * kauth(9) listener
564 * 564 *
565 * Security model: Traditional NetBSD 565 * Security model: Traditional NetBSD
566 * Scope: Process 566 * Scope: Process
567 * Responsibility: Superuser access 567 * Responsibility: Superuser access
568 */ 568 */
569int 569int
570secmodel_suser_process_cb(kauth_cred_t cred, kauth_action_t action, 570secmodel_suser_process_cb(kauth_cred_t cred, kauth_action_t action,
571 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 571 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
572{ 572{
573 struct proc *p; 573 struct proc *p;
574 bool isroot; 574 bool isroot;
575 int result; 575 int result;
576 576
577 isroot = (kauth_cred_geteuid(cred) == 0); 577 isroot = (kauth_cred_geteuid(cred) == 0);
578 result = KAUTH_RESULT_DEFER; 578 result = KAUTH_RESULT_DEFER;
579 p = arg0; 579 p = arg0;
580 580
581 switch (action) { 581 switch (action) {
582 case KAUTH_PROCESS_SIGNAL: { 582 case KAUTH_PROCESS_SIGNAL: {
583 int signum; 583 int signum;
584 584
585 signum = (int)(unsigned long)arg1; 585 signum = (int)(unsigned long)arg1;
586 586
587 if (isroot || kauth_cred_uidmatch(cred, p->p_cred) || 587 if (isroot || kauth_cred_uidmatch(cred, p->p_cred) ||
588 (signum == SIGCONT && (curproc->p_session == p->p_session))) 588 (signum == SIGCONT && (curproc->p_session == p->p_session)))
589 result = KAUTH_RESULT_ALLOW; 589 result = KAUTH_RESULT_ALLOW;
590 break; 590 break;
591 } 591 }
592 592
593 case KAUTH_PROCESS_CANSEE: { 593 case KAUTH_PROCESS_CANSEE: {
594 unsigned long req; 594 unsigned long req;
595 595
596 req = (unsigned long)arg1; 596 req = (unsigned long)arg1;
597 597
598 switch (req) { 598 switch (req) {
599 case KAUTH_REQ_PROCESS_CANSEE_ARGS: 599 case KAUTH_REQ_PROCESS_CANSEE_ARGS:
600 case KAUTH_REQ_PROCESS_CANSEE_ENTRY: 600 case KAUTH_REQ_PROCESS_CANSEE_ENTRY:
601 case KAUTH_REQ_PROCESS_CANSEE_OPENFILES: 601 case KAUTH_REQ_PROCESS_CANSEE_OPENFILES:
602 if (!secmodel_bsd44_curtain) 602 if (!secmodel_bsd44_curtain)
603 result = KAUTH_RESULT_ALLOW; 603 result = KAUTH_RESULT_ALLOW;
604 else if (isroot || kauth_cred_uidmatch(cred, p->p_cred)) 604 else if (isroot || kauth_cred_uidmatch(cred, p->p_cred))
605 result = KAUTH_RESULT_ALLOW; 605 result = KAUTH_RESULT_ALLOW;
606 break; 606 break;
607 607
608 case KAUTH_REQ_PROCESS_CANSEE_ENV: 608 case KAUTH_REQ_PROCESS_CANSEE_ENV:
609 if (!isroot && 609 if (!isroot &&
610 (kauth_cred_getuid(cred) != 610 (kauth_cred_getuid(cred) !=
611 kauth_cred_getuid(p->p_cred) || 611 kauth_cred_getuid(p->p_cred) ||
612 kauth_cred_getuid(cred) != 612 kauth_cred_getuid(cred) !=
613 kauth_cred_getsvuid(p->p_cred))) 613 kauth_cred_getsvuid(p->p_cred)))
614 break; 614 break;
615 else 615 else
616 result = KAUTH_RESULT_ALLOW; 616 result = KAUTH_RESULT_ALLOW;
617 617
618 break; 618 break;
619 619
620 default: 620 default:
621 break; 621 break;
622 } 622 }
623 623
624 break; 624 break;
625 } 625 }
626 626
627 case KAUTH_PROCESS_KTRACE: { 627 case KAUTH_PROCESS_KTRACE:
628 enum kauth_process_req req; 628 if (isroot)
629 
630 req = (enum kauth_process_req)(unsigned long)arg1; 
631 
632 if (isroot) { 
633 result = KAUTH_RESULT_ALLOW; 
634 break; 
635 } else if (req == KAUTH_REQ_PROCESS_KTRACE_PERSISTENT) { 
636 break; 
637 } 
638 
639 if ((p->p_traceflag & KTRFAC_PERSISTENT) || 
640 (p->p_flag & PK_SUGID)) { 
641 break; 
642 } 
643 
644 if (kauth_cred_geteuid(cred) == kauth_cred_getuid(p->p_cred) && 
645 kauth_cred_getuid(cred) == kauth_cred_getsvuid(p->p_cred) && 
646 kauth_cred_getgid(cred) == kauth_cred_getgid(p->p_cred) && 
647 kauth_cred_getgid(cred) == kauth_cred_getsvgid(p->p_cred)) { 
648 result = KAUTH_RESULT_ALLOW; 629 result = KAUTH_RESULT_ALLOW;
649 break; 
650 } 
651 630
652 break; 631 break;
653 } 
654 632
655 case KAUTH_PROCESS_PROCFS: { 633 case KAUTH_PROCESS_PROCFS: {
656 enum kauth_process_req req = (enum kauth_process_req)arg2; 634 enum kauth_process_req req = (enum kauth_process_req)arg2;
657 struct pfsnode *pfs = arg1; 635 struct pfsnode *pfs = arg1;
658 636
659 if (isroot) { 637 if (isroot) {
660 result = KAUTH_RESULT_ALLOW; 638 result = KAUTH_RESULT_ALLOW;
661 break; 639 break;
662 } 640 }
663 641
664 if (req == KAUTH_REQ_PROCESS_PROCFS_CTL) { 642 if (req == KAUTH_REQ_PROCESS_PROCFS_CTL) {
665 break; 643 break;
666 } 644 }
667 645
668 switch (pfs->pfs_type) { 646 switch (pfs->pfs_type) {
669 case PFSregs: 647 case PFSregs:
670 case PFSfpregs: 648 case PFSfpregs:
671 case PFSmem: 649 case PFSmem:
672 if (kauth_cred_getuid(cred) != 650 if (kauth_cred_getuid(cred) !=
673 kauth_cred_getuid(p->p_cred) || 651 kauth_cred_getuid(p->p_cred) ||
674 ISSET(p->p_flag, PK_SUGID)) { 652 ISSET(p->p_flag, PK_SUGID)) {
675 break; 653 break;
676 } 654 }
677 /*FALLTHROUGH*/ 655 /*FALLTHROUGH*/
678 default: 656 default:
679 result = KAUTH_RESULT_ALLOW; 657 result = KAUTH_RESULT_ALLOW;
680 break; 658 break;
681 } 659 }
682 660
683 break; 661 break;
684 } 662 }
685 663
686 case KAUTH_PROCESS_PTRACE: { 664 case KAUTH_PROCESS_PTRACE: {
687 switch ((u_long)arg1) { 665 switch ((u_long)arg1) {
688 case PT_TRACE_ME: 666 case PT_TRACE_ME:
689 case PT_ATTACH: 667 case PT_ATTACH:
690 case PT_WRITE_I: 668 case PT_WRITE_I:
691 case PT_WRITE_D: 669 case PT_WRITE_D:
692 case PT_READ_I: 670 case PT_READ_I:
693 case PT_READ_D: 671 case PT_READ_D:
694 case PT_IO: 672 case PT_IO:
695#ifdef PT_GETREGS 673#ifdef PT_GETREGS
696 case PT_GETREGS: 674 case PT_GETREGS:
697#endif 675#endif
698#ifdef PT_SETREGS 676#ifdef PT_SETREGS
699 case PT_SETREGS: 677 case PT_SETREGS:
700#endif 678#endif
701#ifdef PT_GETFPREGS 679#ifdef PT_GETFPREGS
702 case PT_GETFPREGS: 680 case PT_GETFPREGS:
703#endif 681#endif
704#ifdef PT_SETFPREGS 682#ifdef PT_SETFPREGS
705 case PT_SETFPREGS: 683 case PT_SETFPREGS:
706#endif 684#endif
707#ifdef __HAVE_PTRACE_MACHDEP 685#ifdef __HAVE_PTRACE_MACHDEP
708 PTRACE_MACHDEP_REQUEST_CASES 686 PTRACE_MACHDEP_REQUEST_CASES
709#endif 687#endif
710 if (isroot) { 688 if (isroot) {
711 result = KAUTH_RESULT_ALLOW; 689 result = KAUTH_RESULT_ALLOW;
712 break; 690 break;
713 } 691 }
714 692
715 if (kauth_cred_getuid(cred) != 693 if (kauth_cred_getuid(cred) !=
716 kauth_cred_getuid(p->p_cred) || 694 kauth_cred_getuid(p->p_cred) ||
717 ISSET(p->p_flag, PK_SUGID)) { 695 ISSET(p->p_flag, PK_SUGID)) {
718 break; 696 break;
719 } 697 }
720 698
721 result = KAUTH_RESULT_ALLOW; 699 result = KAUTH_RESULT_ALLOW;
722 break; 700 break;
723 701
724#ifdef PT_STEP 702#ifdef PT_STEP
725 case PT_STEP: 703 case PT_STEP:
726#endif 704#endif
727 case PT_CONTINUE: 705 case PT_CONTINUE:
728 case PT_KILL: 706 case PT_KILL:
729 case PT_DETACH: 707 case PT_DETACH:
730 case PT_LWPINFO: 708 case PT_LWPINFO:
731 case PT_SYSCALL: 709 case PT_SYSCALL:
732 case PT_DUMPCORE: 710 case PT_DUMPCORE:
733 result = KAUTH_RESULT_ALLOW; 711 result = KAUTH_RESULT_ALLOW;
734 break; 712 break;
735 713
736 default: 714 default:
737 result = KAUTH_RESULT_DEFER; 715 result = KAUTH_RESULT_DEFER;
738 break; 716 break;
739 } 717 }
740 718
741 break; 719 break;
742 } 720 }
743 721
744 case KAUTH_PROCESS_CORENAME: 722 case KAUTH_PROCESS_CORENAME:
745 if (isroot || proc_uidmatch(cred, p->p_cred) == 0) 723 if (isroot || proc_uidmatch(cred, p->p_cred) == 0)
746 result = KAUTH_RESULT_ALLOW; 724 result = KAUTH_RESULT_ALLOW;
747 725
748 break; 726 break;
749 727
750 case KAUTH_PROCESS_FORK: { 728 case KAUTH_PROCESS_FORK: {
751 int lnprocs = (int)(unsigned long)arg2; 729 int lnprocs = (int)(unsigned long)arg2;
752 730
753 /* 731 /*
754 * Don't allow a nonprivileged user to use the last few 732 * Don't allow a nonprivileged user to use the last few
755 * processes. The variable lnprocs is the current number of 733 * processes. The variable lnprocs is the current number of
756 * processes, maxproc is the limit. 734 * processes, maxproc is the limit.
757 */ 735 */
758 if (__predict_false((lnprocs >= maxproc - 5) && !isroot)) 736 if (__predict_false((lnprocs >= maxproc - 5) && !isroot))
759 break; 737 break;
760 else 738 else
761 result = KAUTH_RESULT_ALLOW; 739 result = KAUTH_RESULT_ALLOW;
762 740
763 break; 741 break;
764 } 742 }
765 743
766 case KAUTH_PROCESS_KEVENT_FILTER: 744 case KAUTH_PROCESS_KEVENT_FILTER:
767 if ((kauth_cred_getuid(p->p_cred) != 745 if ((kauth_cred_getuid(p->p_cred) !=
768 kauth_cred_getuid(cred) || 746 kauth_cred_getuid(cred) ||
769 ISSET(p->p_flag, PK_SUGID)) && 747 ISSET(p->p_flag, PK_SUGID)) &&
770 !isroot) 748 !isroot)
771 break; 749 break;
772 else 750 else
773 result = KAUTH_RESULT_ALLOW; 751 result = KAUTH_RESULT_ALLOW;
774 752
775 break; 753 break;
776 754
777 case KAUTH_PROCESS_NICE: 755 case KAUTH_PROCESS_NICE:
778 if (isroot) { 756 if (isroot) {
779 result = KAUTH_RESULT_ALLOW; 757 result = KAUTH_RESULT_ALLOW;
780 break; 758 break;
781 } 759 }
782 760
783 if (kauth_cred_geteuid(cred) != 761 if (kauth_cred_geteuid(cred) !=
784 kauth_cred_geteuid(p->p_cred) && 762 kauth_cred_geteuid(p->p_cred) &&
785 kauth_cred_getuid(cred) != 763 kauth_cred_getuid(cred) !=
786 kauth_cred_geteuid(p->p_cred)) { 764 kauth_cred_geteuid(p->p_cred)) {
787 break; 765 break;
788 } 766 }
789 767
790 if ((u_long)arg1 >= p->p_nice) 768 if ((u_long)arg1 >= p->p_nice)
791 result = KAUTH_RESULT_ALLOW; 769 result = KAUTH_RESULT_ALLOW;
792 770
793 break; 771 break;
794 772
795 case KAUTH_PROCESS_RLIMIT: { 773 case KAUTH_PROCESS_RLIMIT: {
796 unsigned long req; 774 unsigned long req;
797 775
798 req = (unsigned long)arg1; 776 req = (unsigned long)arg1;
799 777
800 switch (req) { 778 switch (req) {
801 case KAUTH_REQ_PROCESS_RLIMIT_SET: { 779 case KAUTH_REQ_PROCESS_RLIMIT_SET: {
802 struct rlimit *new_rlimit; 780 struct rlimit *new_rlimit;
803 u_long which; 781 u_long which;
804 782
805 if (isroot) { 783 if (isroot) {
806 result = KAUTH_RESULT_ALLOW; 784 result = KAUTH_RESULT_ALLOW;
807 break; 785 break;
808 } 786 }
809 787
810 if ((p != curlwp->l_proc) && 788 if ((p != curlwp->l_proc) &&
811 (proc_uidmatch(cred, p->p_cred) != 0)) { 789 (proc_uidmatch(cred, p->p_cred) != 0)) {
812 break; 790 break;
813 } 791 }
814 792
815 new_rlimit = arg2; 793 new_rlimit = arg2;
816 which = (u_long)arg3; 794 which = (u_long)arg3;
817 795
818 if (new_rlimit->rlim_max <= 796 if (new_rlimit->rlim_max <=
819 p->p_rlimit[which].rlim_max) 797 p->p_rlimit[which].rlim_max)
820 result = KAUTH_RESULT_ALLOW; 798 result = KAUTH_RESULT_ALLOW;
821 799
822 break; 800 break;
823 } 801 }
824 802
825 case KAUTH_REQ_PROCESS_RLIMIT_GET: 803 case KAUTH_REQ_PROCESS_RLIMIT_GET:
826 result = KAUTH_RESULT_ALLOW; 804 result = KAUTH_RESULT_ALLOW;
827 break; 805 break;
828 806
829 default: 807 default:
830 break; 808 break;
831 } 809 }
832 810
833 break; 811 break;
834 } 812 }
835 813
836 case KAUTH_PROCESS_SCHEDULER_GETPARAM: 814 case KAUTH_PROCESS_SCHEDULER_GETPARAM:
837 if (isroot || kauth_cred_uidmatch(cred, p->p_cred)) 815 if (isroot || kauth_cred_uidmatch(cred, p->p_cred))
838 result = KAUTH_RESULT_ALLOW; 816 result = KAUTH_RESULT_ALLOW;
839 817
840 break; 818 break;
841 819
842 case KAUTH_PROCESS_SCHEDULER_SETPARAM: 820 case KAUTH_PROCESS_SCHEDULER_SETPARAM:
843 if (isroot) 821 if (isroot)
844 result = KAUTH_RESULT_ALLOW; 822 result = KAUTH_RESULT_ALLOW;
845 else if (kauth_cred_uidmatch(cred, p->p_cred)) { 823 else if (kauth_cred_uidmatch(cred, p->p_cred)) {
846 struct lwp *l; 824 struct lwp *l;
847 int policy; 825 int policy;
848 pri_t priority; 826 pri_t priority;
849 827
850 l = arg1; 828 l = arg1;
851 policy = (int)(unsigned long)arg2; 829 policy = (int)(unsigned long)arg2;
852 priority = (pri_t)(unsigned long)arg3; 830 priority = (pri_t)(unsigned long)arg3;
853 831
854 if ((policy == l->l_class || 832 if ((policy == l->l_class ||
855 (policy != SCHED_FIFO && policy != SCHED_RR)) && 833 (policy != SCHED_FIFO && policy != SCHED_RR)) &&
856 priority <= l->l_priority) 834 priority <= l->l_priority)
857 result = KAUTH_RESULT_ALLOW; 835 result = KAUTH_RESULT_ALLOW;
858 } 836 }
859 837
860 break; 838 break;
861 839
862 case KAUTH_PROCESS_SCHEDULER_GETAFFINITY: 840 case KAUTH_PROCESS_SCHEDULER_GETAFFINITY:
863 result = KAUTH_RESULT_ALLOW; 841 result = KAUTH_RESULT_ALLOW;
864 842
865 break; 843 break;
866 844
867 case KAUTH_PROCESS_SCHEDULER_SETAFFINITY: 845 case KAUTH_PROCESS_SCHEDULER_SETAFFINITY:
868 if (isroot) 846 if (isroot)
869 result = KAUTH_RESULT_ALLOW; 847 result = KAUTH_RESULT_ALLOW;
870 848
871 break; 849 break;
872 850
873 case KAUTH_PROCESS_SETID: 851 case KAUTH_PROCESS_SETID:
874 if (isroot) 852 if (isroot)
875 result = KAUTH_RESULT_ALLOW; 853 result = KAUTH_RESULT_ALLOW;
876 break; 854 break;
877 855
878 case KAUTH_PROCESS_STOPFLAG: 856 case KAUTH_PROCESS_STOPFLAG:
879 if (isroot || proc_uidmatch(cred, p->p_cred) == 0) { 857 if (isroot || proc_uidmatch(cred, p->p_cred) == 0) {
880 result = KAUTH_RESULT_ALLOW; 858 result = KAUTH_RESULT_ALLOW;
881 break; 859 break;
882 } 860 }
883 break; 861 break;
884 862
885 default: 863 default:
886 result = KAUTH_RESULT_DEFER; 864 result = KAUTH_RESULT_DEFER;
887 break; 865 break;
888 } 866 }
889 867
890 return (result); 868 return (result);
891} 869}
892 870
893/* 871/*
894 * kauth(9) listener 872 * kauth(9) listener
895 * 873 *
896 * Security model: Traditional NetBSD 874 * Security model: Traditional NetBSD
897 * Scope: Network 875 * Scope: Network
898 * Responsibility: Superuser access 876 * Responsibility: Superuser access
899 */ 877 */
900int 878int
901secmodel_suser_network_cb(kauth_cred_t cred, kauth_action_t action, 879secmodel_suser_network_cb(kauth_cred_t cred, kauth_action_t action,
902 void *cookie, void *arg0, void *arg1, void *arg2, 880 void *cookie, void *arg0, void *arg1, void *arg2,
903 void *arg3) 881 void *arg3)
904{ 882{
905 bool isroot; 883 bool isroot;
906 int result; 884 int result;
907 enum kauth_network_req req; 885 enum kauth_network_req req;
908 886
909 isroot = (kauth_cred_geteuid(cred) == 0); 887 isroot = (kauth_cred_geteuid(cred) == 0);
910 result = KAUTH_RESULT_DEFER; 888 result = KAUTH_RESULT_DEFER;
911 req = (enum kauth_network_req)arg0; 889 req = (enum kauth_network_req)arg0;
912 890
913 switch (action) { 891 switch (action) {
914 case KAUTH_NETWORK_ALTQ: 892 case KAUTH_NETWORK_ALTQ:
915 switch (req) { 893 switch (req) {
916 case KAUTH_REQ_NETWORK_ALTQ_AFMAP: 894 case KAUTH_REQ_NETWORK_ALTQ_AFMAP:
917 case KAUTH_REQ_NETWORK_ALTQ_BLUE: 895 case KAUTH_REQ_NETWORK_ALTQ_BLUE:
918 case KAUTH_REQ_NETWORK_ALTQ_CBQ: 896 case KAUTH_REQ_NETWORK_ALTQ_CBQ:
919 case KAUTH_REQ_NETWORK_ALTQ_CDNR: 897 case KAUTH_REQ_NETWORK_ALTQ_CDNR:
920 case KAUTH_REQ_NETWORK_ALTQ_CONF: 898 case KAUTH_REQ_NETWORK_ALTQ_CONF:
921 case KAUTH_REQ_NETWORK_ALTQ_FIFOQ: 899 case KAUTH_REQ_NETWORK_ALTQ_FIFOQ:
922 case KAUTH_REQ_NETWORK_ALTQ_HFSC: 900 case KAUTH_REQ_NETWORK_ALTQ_HFSC:
923 case KAUTH_REQ_NETWORK_ALTQ_JOBS: 901 case KAUTH_REQ_NETWORK_ALTQ_JOBS:
924 case KAUTH_REQ_NETWORK_ALTQ_PRIQ: 902 case KAUTH_REQ_NETWORK_ALTQ_PRIQ:
925 case KAUTH_REQ_NETWORK_ALTQ_RED: 903 case KAUTH_REQ_NETWORK_ALTQ_RED:
926 case KAUTH_REQ_NETWORK_ALTQ_RIO: 904 case KAUTH_REQ_NETWORK_ALTQ_RIO:
927 case KAUTH_REQ_NETWORK_ALTQ_WFQ: 905 case KAUTH_REQ_NETWORK_ALTQ_WFQ:
928 if (isroot) 906 if (isroot)
929 result = KAUTH_RESULT_ALLOW; 907 result = KAUTH_RESULT_ALLOW;
930 break; 908 break;
931 909
932 default: 910 default:
933 result = KAUTH_RESULT_DEFER; 911 result = KAUTH_RESULT_DEFER;
934 break; 912 break;
935 } 913 }
936 914
937 break; 915 break;
938 916
939 case KAUTH_NETWORK_BIND: 917 case KAUTH_NETWORK_BIND:
940 switch (req) { 918 switch (req) {
941 case KAUTH_REQ_NETWORK_BIND_PORT: 919 case KAUTH_REQ_NETWORK_BIND_PORT:
942 result = KAUTH_RESULT_ALLOW; 920 result = KAUTH_RESULT_ALLOW;
943 break; 921 break;
944 922
945 case KAUTH_REQ_NETWORK_BIND_PRIVPORT: 923 case KAUTH_REQ_NETWORK_BIND_PRIVPORT:
946 if (isroot) 924 if (isroot)
947 result = KAUTH_RESULT_ALLOW; 925 result = KAUTH_RESULT_ALLOW;
948 break; 926 break;
949 927
950 default: 928 default:
951 break; 929 break;
952 } 930 }
953 break; 931 break;
954 932
955 case KAUTH_NETWORK_FIREWALL: 933 case KAUTH_NETWORK_FIREWALL:
956 switch (req) { 934 switch (req) {
957 case KAUTH_REQ_NETWORK_FIREWALL_FW: 935 case KAUTH_REQ_NETWORK_FIREWALL_FW:
958 case KAUTH_REQ_NETWORK_FIREWALL_NAT: 936 case KAUTH_REQ_NETWORK_FIREWALL_NAT:
959 /* 937 /*
960 * Decisions are root-agnostic. 938 * Decisions are root-agnostic.
961 * 939 *
962 * Both requests are issued from the context of a 940 * Both requests are issued from the context of a
963 * device with permission bits acting as access 941 * device with permission bits acting as access
964 * control. 942 * control.
965 */ 943 */
966 result = KAUTH_RESULT_ALLOW; 944 result = KAUTH_RESULT_ALLOW;
967 break; 945 break;
968 946
969 default: 947 default:
970 break; 948 break;
971 } 949 }
972 break; 950 break;
973 951
974 case KAUTH_NETWORK_FORWSRCRT: 952 case KAUTH_NETWORK_FORWSRCRT:
975 if (isroot) 953 if (isroot)
976 result = KAUTH_RESULT_ALLOW; 954 result = KAUTH_RESULT_ALLOW;
977 955
978 break; 956 break;
979 957
980 case KAUTH_NETWORK_INTERFACE: 958 case KAUTH_NETWORK_INTERFACE:
981 switch (req) { 959 switch (req) {
982 case KAUTH_REQ_NETWORK_INTERFACE_GET: 960 case KAUTH_REQ_NETWORK_INTERFACE_GET:
983 case KAUTH_REQ_NETWORK_INTERFACE_SET: 961 case KAUTH_REQ_NETWORK_INTERFACE_SET:
984 result = KAUTH_RESULT_ALLOW; 962 result = KAUTH_RESULT_ALLOW;
985 break; 963 break;
986 964
987 case KAUTH_REQ_NETWORK_INTERFACE_GETPRIV: 965 case KAUTH_REQ_NETWORK_INTERFACE_GETPRIV:
988 case KAUTH_REQ_NETWORK_INTERFACE_SETPRIV: 966 case KAUTH_REQ_NETWORK_INTERFACE_SETPRIV:
989 if (isroot) 967 if (isroot)
990 result = KAUTH_RESULT_ALLOW; 968 result = KAUTH_RESULT_ALLOW;
991 break; 969 break;
992 970
993 default: 971 default:
994 result = KAUTH_RESULT_DEFER; 972 result = KAUTH_RESULT_DEFER;
995 break; 973 break;
996 } 974 }
997 break; 975 break;
998 976
999 case KAUTH_NETWORK_INTERFACE_PPP: 977 case KAUTH_NETWORK_INTERFACE_PPP:
1000 switch (req) { 978 switch (req) {
1001 case KAUTH_REQ_NETWORK_INTERFACE_PPP_ADD: 979 case KAUTH_REQ_NETWORK_INTERFACE_PPP_ADD:
1002 if (isroot) 980 if (isroot)
1003 result = KAUTH_RESULT_ALLOW; 981 result = KAUTH_RESULT_ALLOW;
1004 break; 982 break;
1005 983
1006 default: 984 default:
1007 break; 985 break;
1008 } 986 }
1009 987
1010 break; 988 break;
1011 989
1012 case KAUTH_NETWORK_INTERFACE_SLIP: 990 case KAUTH_NETWORK_INTERFACE_SLIP:
1013 switch (req) { 991 switch (req) {
1014 case KAUTH_REQ_NETWORK_INTERFACE_SLIP_ADD: 992 case KAUTH_REQ_NETWORK_INTERFACE_SLIP_ADD:
1015 if (isroot) 993 if (isroot)
1016 result = KAUTH_RESULT_ALLOW; 994 result = KAUTH_RESULT_ALLOW;
1017 break; 995 break;
1018 996
1019 default: 997 default:
1020 break; 998 break;
1021 } 999 }
1022 1000
1023 break; 1001 break;
1024 1002
1025 case KAUTH_NETWORK_INTERFACE_STRIP: 1003 case KAUTH_NETWORK_INTERFACE_STRIP:
1026 switch (req) { 1004 switch (req) {
1027 case KAUTH_REQ_NETWORK_INTERFACE_STRIP_ADD: 1005 case KAUTH_REQ_NETWORK_INTERFACE_STRIP_ADD:
1028 if (isroot) 1006 if (isroot)
1029 result = KAUTH_RESULT_ALLOW; 1007 result = KAUTH_RESULT_ALLOW;
1030 break; 1008 break;
1031 1009
1032 default: 1010 default:
1033 break; 1011 break;
1034 } 1012 }
1035 1013
1036 break; 1014 break;
1037 1015
1038 case KAUTH_NETWORK_INTERFACE_TUN: 1016 case KAUTH_NETWORK_INTERFACE_TUN:
1039 switch (req) { 1017 switch (req) {
1040 case KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD: 1018 case KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD:
1041 if (isroot) 1019 if (isroot)
1042 result = KAUTH_RESULT_ALLOW; 1020 result = KAUTH_RESULT_ALLOW;
1043 break; 1021 break;
1044 1022
1045 default: 1023 default:
1046 break; 1024 break;
1047 } 1025 }
1048 1026
1049 break; 1027 break;
1050 1028
1051 case KAUTH_NETWORK_NFS: 1029 case KAUTH_NETWORK_NFS:
1052 switch (req) { 1030 switch (req) {
1053 case KAUTH_REQ_NETWORK_NFS_EXPORT: 1031 case KAUTH_REQ_NETWORK_NFS_EXPORT:
1054 case KAUTH_REQ_NETWORK_NFS_SVC: 1032 case KAUTH_REQ_NETWORK_NFS_SVC:
1055 if (isroot) 1033 if (isroot)
1056 result = KAUTH_RESULT_ALLOW; 1034 result = KAUTH_RESULT_ALLOW;
1057 1035
1058 break; 1036 break;
1059 1037
1060 default: 1038 default:
1061 result = KAUTH_RESULT_DEFER; 1039 result = KAUTH_RESULT_DEFER;
1062 break; 1040 break;
1063 } 1041 }
1064 break; 1042 break;
1065 1043
1066 case KAUTH_NETWORK_ROUTE: 1044 case KAUTH_NETWORK_ROUTE:
1067 switch (((struct rt_msghdr *)arg1)->rtm_type) { 1045 switch (((struct rt_msghdr *)arg1)->rtm_type) {
1068 case RTM_GET: 1046 case RTM_GET:
1069 result = KAUTH_RESULT_ALLOW; 1047 result = KAUTH_RESULT_ALLOW;
1070 break; 1048 break;
1071 1049
1072 default: 1050 default:
1073 if (isroot) 1051 if (isroot)
1074 result = KAUTH_RESULT_ALLOW; 1052 result = KAUTH_RESULT_ALLOW;
1075 break; 1053 break;
1076 } 1054 }
1077 break; 1055 break;
1078 1056
1079 case KAUTH_NETWORK_SOCKET: 1057 case KAUTH_NETWORK_SOCKET:
1080 switch (req) { 1058 switch (req) {
1081 case KAUTH_REQ_NETWORK_SOCKET_DROP: 1059 case KAUTH_REQ_NETWORK_SOCKET_DROP:
1082 /* 1060 /*
1083 * The superuser can drop any connection. Normal users 1061 * The superuser can drop any connection. Normal users
1084 * can only drop their own connections. 1062 * can only drop their own connections.
1085 */ 1063 */
1086 if (isroot) 1064 if (isroot)
1087 result = KAUTH_RESULT_ALLOW; 1065 result = KAUTH_RESULT_ALLOW;
1088 else { 1066 else {
1089 struct socket *so = (struct socket *)arg1; 1067 struct socket *so = (struct socket *)arg1;
1090 uid_t sockuid = so->so_uidinfo->ui_uid; 1068 uid_t sockuid = so->so_uidinfo->ui_uid;
1091 1069
1092 if (sockuid == kauth_cred_getuid(cred) || 1070 if (sockuid == kauth_cred_getuid(cred) ||
1093 sockuid == kauth_cred_geteuid(cred)) 1071 sockuid == kauth_cred_geteuid(cred))
1094 result = KAUTH_RESULT_ALLOW; 1072 result = KAUTH_RESULT_ALLOW;
1095 } 1073 }
1096 1074
1097  1075
1098 break; 1076 break;
1099 1077
1100 case KAUTH_REQ_NETWORK_SOCKET_OPEN: 1078 case KAUTH_REQ_NETWORK_SOCKET_OPEN:
1101 if ((u_long)arg1 == PF_ROUTE || (u_long)arg1 == PF_BLUETOOTH) 1079 if ((u_long)arg1 == PF_ROUTE || (u_long)arg1 == PF_BLUETOOTH)
1102 result = KAUTH_RESULT_ALLOW; 1080 result = KAUTH_RESULT_ALLOW;
1103 else if ((u_long)arg2 == SOCK_RAW) { 1081 else if ((u_long)arg2 == SOCK_RAW) {
1104 if (isroot) 1082 if (isroot)
1105 result = KAUTH_RESULT_ALLOW; 1083 result = KAUTH_RESULT_ALLOW;
1106 } else 1084 } else
1107 result = KAUTH_RESULT_ALLOW; 1085 result = KAUTH_RESULT_ALLOW;
1108 break; 1086 break;
1109 1087
1110 case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK: 1088 case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK:
1111 if (isroot) 1089 if (isroot)
1112 result = KAUTH_RESULT_ALLOW; 1090 result = KAUTH_RESULT_ALLOW;
1113 break; 1091 break;
1114 1092
1115 case KAUTH_REQ_NETWORK_SOCKET_CANSEE: 1093 case KAUTH_REQ_NETWORK_SOCKET_CANSEE:
1116 if (secmodel_bsd44_curtain) { 1094 if (secmodel_bsd44_curtain) {
1117 uid_t so_uid; 1095 uid_t so_uid;
1118 1096
1119 so_uid = 1097 so_uid =
1120 ((struct socket *)arg1)->so_uidinfo->ui_uid; 1098 ((struct socket *)arg1)->so_uidinfo->ui_uid;
1121 if (isroot || 1099 if (isroot ||
1122 kauth_cred_geteuid(cred) == so_uid) 1100 kauth_cred_geteuid(cred) == so_uid)
1123 result = KAUTH_RESULT_ALLOW; 1101 result = KAUTH_RESULT_ALLOW;
1124 } else 1102 } else
1125 result = KAUTH_RESULT_ALLOW; 1103 result = KAUTH_RESULT_ALLOW;
1126 break; 1104 break;
1127 1105
1128 case KAUTH_REQ_NETWORK_SOCKET_SETPRIV: 1106 case KAUTH_REQ_NETWORK_SOCKET_SETPRIV:
1129 if (isroot) 1107 if (isroot)
1130 result = KAUTH_RESULT_ALLOW; 1108 result = KAUTH_RESULT_ALLOW;
1131 break; 1109 break;
1132 1110
1133 default: 1111 default:
1134 break; 1112 break;
1135 } 1113 }
1136 1114
1137 break; 1115 break;
1138 1116
1139 1117
1140 default: 1118 default:
1141 result = KAUTH_RESULT_DEFER; 1119 result = KAUTH_RESULT_DEFER;
1142 break; 1120 break;
1143 } 1121 }
1144 1122
1145 return (result); 1123 return (result);
1146} 1124}
1147 1125
1148/* 1126/*
1149 * kauth(9) listener 1127 * kauth(9) listener
1150 * 1128 *
1151 * Security model: Traditional NetBSD 1129 * Security model: Traditional NetBSD
1152 * Scope: Machdep 1130 * Scope: Machdep
1153 * Responsibility: Superuser access 1131 * Responsibility: Superuser access
1154 */ 1132 */
1155int 1133int
1156secmodel_suser_machdep_cb(kauth_cred_t cred, kauth_action_t action, 1134secmodel_suser_machdep_cb(kauth_cred_t cred, kauth_action_t action,
1157 void *cookie, void *arg0, void *arg1, void *arg2, 1135 void *cookie, void *arg0, void *arg1, void *arg2,
1158 void *arg3) 1136 void *arg3)
1159{ 1137{
1160 bool isroot; 1138 bool isroot;
1161 int result; 1139 int result;
1162 1140
1163 isroot = (kauth_cred_geteuid(cred) == 0); 1141 isroot = (kauth_cred_geteuid(cred) == 0);
1164 result = KAUTH_RESULT_DEFER; 1142 result = KAUTH_RESULT_DEFER;
1165 1143
1166 switch (action) { 1144 switch (action) {
1167 case KAUTH_MACHDEP_IOPERM_GET: 1145 case KAUTH_MACHDEP_IOPERM_GET:
1168 case KAUTH_MACHDEP_LDT_GET: 1146 case KAUTH_MACHDEP_LDT_GET:
1169 case KAUTH_MACHDEP_LDT_SET: 1147 case KAUTH_MACHDEP_LDT_SET:
1170 case KAUTH_MACHDEP_MTRR_GET: 1148 case KAUTH_MACHDEP_MTRR_GET:
1171 result = KAUTH_RESULT_ALLOW; 1149 result = KAUTH_RESULT_ALLOW;
1172 break; 1150 break;
1173 1151
1174 case KAUTH_MACHDEP_CACHEFLUSH: 1152 case KAUTH_MACHDEP_CACHEFLUSH:
1175 case KAUTH_MACHDEP_IOPERM_SET: 1153 case KAUTH_MACHDEP_IOPERM_SET:
1176 case KAUTH_MACHDEP_IOPL: 1154 case KAUTH_MACHDEP_IOPL:
1177 case KAUTH_MACHDEP_MTRR_SET: 1155 case KAUTH_MACHDEP_MTRR_SET:
1178 case KAUTH_MACHDEP_NVRAM: 1156 case KAUTH_MACHDEP_NVRAM:
1179 case KAUTH_MACHDEP_UNMANAGEDMEM: 1157 case KAUTH_MACHDEP_UNMANAGEDMEM:
1180 if (isroot) 1158 if (isroot)
1181 result = KAUTH_RESULT_ALLOW; 1159 result = KAUTH_RESULT_ALLOW;
1182 break; 1160 break;
1183 1161
1184 default: 1162 default:
1185 result = KAUTH_RESULT_DEFER; 1163 result = KAUTH_RESULT_DEFER;
1186 break; 1164 break;
1187 } 1165 }
1188 1166
1189 return (result); 1167 return (result);
1190} 1168}
1191 1169
1192/* 1170/*
1193 * kauth(9) listener 1171 * kauth(9) listener
1194 * 1172 *
1195 * Security model: Traditional NetBSD 1173 * Security model: Traditional NetBSD
1196 * Scope: Device 1174 * Scope: Device
1197 * Responsibility: Superuser access 1175 * Responsibility: Superuser access
1198 */ 1176 */
1199int 1177int
1200secmodel_suser_device_cb(kauth_cred_t cred, kauth_action_t action, 1178secmodel_suser_device_cb(kauth_cred_t cred, kauth_action_t action,
1201 void *cookie, void *arg0, void *arg1, void *arg2, 1179 void *cookie, void *arg0, void *arg1, void *arg2,
1202 void *arg3) 1180 void *arg3)
1203{ 1181{
1204 struct tty *tty; 1182 struct tty *tty;
1205 bool isroot; 1183 bool isroot;
1206 int result; 1184 int result;
1207 1185
1208 isroot = (kauth_cred_geteuid(cred) == 0); 1186 isroot = (kauth_cred_geteuid(cred) == 0);
1209 result = KAUTH_RESULT_DEFER; 1187 result = KAUTH_RESULT_DEFER;
1210 1188
1211 switch (action) { 1189 switch (action) {
1212 case KAUTH_DEVICE_BLUETOOTH_SETPRIV: 1190 case KAUTH_DEVICE_BLUETOOTH_SETPRIV:
1213 case KAUTH_DEVICE_BLUETOOTH_SEND: 1191 case KAUTH_DEVICE_BLUETOOTH_SEND:
1214 case KAUTH_DEVICE_BLUETOOTH_RECV: 1192 case KAUTH_DEVICE_BLUETOOTH_RECV:
1215 if (isroot) 1193 if (isroot)
1216 result = KAUTH_RESULT_ALLOW; 1194 result = KAUTH_RESULT_ALLOW;
1217 break; 1195 break;
1218 1196
1219 case KAUTH_DEVICE_BLUETOOTH_BCSP: 1197 case KAUTH_DEVICE_BLUETOOTH_BCSP:
1220 case KAUTH_DEVICE_BLUETOOTH_BTUART: { 1198 case KAUTH_DEVICE_BLUETOOTH_BTUART: {
1221 enum kauth_device_req req; 1199 enum kauth_device_req req;
1222 1200
1223 req = (enum kauth_device_req)arg0; 1201 req = (enum kauth_device_req)arg0;
1224 switch (req) { 1202 switch (req) {
1225 case KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD: 1203 case KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD:
1226 case KAUTH_REQ_DEVICE_BLUETOOTH_BTUART_ADD: 1204 case KAUTH_REQ_DEVICE_BLUETOOTH_BTUART_ADD:
1227 if (isroot) 1205 if (isroot)
1228 result = KAUTH_RESULT_ALLOW; 1206 result = KAUTH_RESULT_ALLOW;
1229 break; 1207 break;
1230 1208
1231 default: 1209 default:
1232 break; 1210 break;
1233 } 1211 }
1234 1212
1235 break; 1213 break;
1236 } 1214 }
1237 1215
1238 case KAUTH_DEVICE_RAWIO_SPEC: 1216 case KAUTH_DEVICE_RAWIO_SPEC:
1239 case KAUTH_DEVICE_RAWIO_PASSTHRU: 1217 case KAUTH_DEVICE_RAWIO_PASSTHRU:
1240 /* 1218 /*
1241 * Decision is root-agnostic. 1219 * Decision is root-agnostic.
1242 * 1220 *
1243 * Both requests can be issued on devices subject to their 1221 * Both requests can be issued on devices subject to their
1244 * permission bits. 1222 * permission bits.
1245 */ 1223 */
1246 result = KAUTH_RESULT_ALLOW; 1224 result = KAUTH_RESULT_ALLOW;
1247 break; 1225 break;
1248 1226
1249 case KAUTH_DEVICE_TTY_OPEN: 1227 case KAUTH_DEVICE_TTY_OPEN:
1250 tty = arg0; 1228 tty = arg0;
1251 1229
1252 if (!(tty->t_state & TS_ISOPEN)) 1230 if (!(tty->t_state & TS_ISOPEN))
1253 result = KAUTH_RESULT_ALLOW; 1231 result = KAUTH_RESULT_ALLOW;
1254 else if (tty->t_state & TS_XCLUDE) { 1232 else if (tty->t_state & TS_XCLUDE) {
1255 if (isroot) 1233 if (isroot)
1256 result = KAUTH_RESULT_ALLOW; 1234 result = KAUTH_RESULT_ALLOW;
1257 } else 1235 } else
1258 result = KAUTH_RESULT_ALLOW; 1236 result = KAUTH_RESULT_ALLOW;
1259 1237
1260 break; 1238 break;
1261 1239
1262 case KAUTH_DEVICE_TTY_PRIVSET: 1240 case KAUTH_DEVICE_TTY_PRIVSET:
1263 if (isroot) 1241 if (isroot)
1264 result = KAUTH_RESULT_ALLOW; 1242 result = KAUTH_RESULT_ALLOW;
1265 1243
1266 break; 1244 break;
1267 1245
1268 case KAUTH_DEVICE_TTY_STI: 1246 case KAUTH_DEVICE_TTY_STI:
1269 if (isroot) 1247 if (isroot)
1270 result = KAUTH_RESULT_ALLOW; 1248 result = KAUTH_RESULT_ALLOW;
1271 1249
1272 break; 1250 break;
1273 1251
1274 case KAUTH_DEVICE_RND_ADDDATA: 1252 case KAUTH_DEVICE_RND_ADDDATA:
1275 case KAUTH_DEVICE_RND_GETPRIV: 1253 case KAUTH_DEVICE_RND_GETPRIV:
1276 case KAUTH_DEVICE_RND_SETPRIV: 1254 case KAUTH_DEVICE_RND_SETPRIV:
1277 if (isroot) 1255 if (isroot)
1278 result = KAUTH_RESULT_ALLOW; 1256 result = KAUTH_RESULT_ALLOW;
1279 break; 1257 break;
1280 1258
1281 case KAUTH_DEVICE_GPIO_PINSET: 1259 case KAUTH_DEVICE_GPIO_PINSET:
1282 /* 1260 /*
1283 * root can access gpio pins, secmodel_securlevel can veto 1261 * root can access gpio pins, secmodel_securlevel can veto
1284 * this decision. 1262 * this decision.
1285 */ 1263 */
1286 if (isroot) 1264 if (isroot)
1287 result = KAUTH_RESULT_ALLOW; 1265 result = KAUTH_RESULT_ALLOW;
1288 break; 1266 break;
1289 1267
1290 default: 1268 default:
1291 result = KAUTH_RESULT_DEFER; 1269 result = KAUTH_RESULT_DEFER;
1292 break; 1270 break;
1293 } 1271 }
1294 1272
1295 return (result); 1273 return (result);
1296} 1274}
1297 1275
1298int 1276int
1299secmodel_suser_vnode_cb(kauth_cred_t cred, kauth_action_t action, 1277secmodel_suser_vnode_cb(kauth_cred_t cred, kauth_action_t action,
1300 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3) 1278 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
1301{ 1279{
1302 bool isroot; 1280 bool isroot;
1303 int result; 1281 int result;
1304 1282
1305 isroot = (kauth_cred_geteuid(cred) == 0); 1283 isroot = (kauth_cred_geteuid(cred) == 0);
1306 result = KAUTH_RESULT_DEFER; 1284 result = KAUTH_RESULT_DEFER;
1307 1285
1308 if (isroot) 1286 if (isroot)
1309 result = KAUTH_RESULT_ALLOW; 1287 result = KAUTH_RESULT_ALLOW;
1310 1288
1311 return (result); 1289 return (result);
1312} 1290}
1313 1291