xref: /netbsd-src/sys/secmodel/suser/secmodel_suser.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
1 /* $NetBSD: secmodel_suser.c,v 1.34 2009/12/29 04:25:30 elad Exp $ */
2 /*-
3  * Copyright (c) 2006 Elad Efrat <elad@NetBSD.org>
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
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
15  *    derived from this software without specific prior written permission.
16  *
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
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
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
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
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28 
29 /*
30  * This file contains kauth(9) listeners needed to implement the traditional
31  * NetBSD superuser access restrictions.
32  *
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
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
37  * as normal users are not allowed to access system resources.
38  */
39 
40 #include <sys/cdefs.h>
41 __KERNEL_RCSID(0, "$NetBSD: secmodel_suser.c,v 1.34 2009/12/29 04:25:30 elad Exp $");
42 
43 #include <sys/types.h>
44 #include <sys/param.h>
45 #include <sys/kauth.h>
46 
47 #include <sys/mutex.h>
48 #include <sys/mount.h>
49 #include <sys/socketvar.h>
50 #include <sys/sysctl.h>
51 #include <sys/vnode.h>
52 #include <sys/proc.h>
53 #include <sys/module.h>
54 
55 #include <secmodel/suser/suser.h>
56 
57 MODULE(MODULE_CLASS_SECMODEL, suser, NULL);
58 
59 static int secmodel_suser_curtain;
60 /* static */ int dovfsusermount;
61 
62 static kauth_listener_t l_generic, l_system, l_process, l_network, l_machdep,
63     l_device, l_vnode;
64 
65 static struct sysctllog *suser_sysctl_log;
66 
67 void
68 sysctl_security_suser_setup(struct sysctllog **clog)
69 {
70 	const struct sysctlnode *rnode;
71 
72 	sysctl_createv(clog, 0, NULL, &rnode,
73 		       CTLFLAG_PERMANENT,
74 		       CTLTYPE_NODE, "security", NULL,
75 		       NULL, 0, NULL, 0,
76 		       CTL_SECURITY, CTL_EOL);
77 
78 	sysctl_createv(clog, 0, &rnode, &rnode,
79 		       CTLFLAG_PERMANENT,
80 		       CTLTYPE_NODE, "models", NULL,
81 		       NULL, 0, NULL, 0,
82 		       CTL_CREATE, CTL_EOL);
83 
84 	sysctl_createv(clog, 0, &rnode, &rnode,
85 		       CTLFLAG_PERMANENT,
86 		       CTLTYPE_NODE, "suser", NULL,
87 		       NULL, 0, NULL, 0,
88 		       CTL_CREATE, CTL_EOL);
89 
90 	sysctl_createv(clog, 0, &rnode, NULL,
91 		       CTLFLAG_PERMANENT,
92 		       CTLTYPE_STRING, "name", NULL,
93 		       NULL, 0, __UNCONST("Traditional NetBSD: Superuser"), 0,
94 		       CTL_CREATE, CTL_EOL);
95 
96 	sysctl_createv(clog, 0, &rnode, NULL,
97 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
98 		       CTLTYPE_INT, "curtain",
99 		       SYSCTL_DESCR("Curtain information about objects to "\
100 		       		    "users not owning them."),
101 		       NULL, 0, &secmodel_suser_curtain, 0,
102 		       CTL_CREATE, CTL_EOL);
103 
104 	sysctl_createv(clog, 0, &rnode, NULL,
105 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
106 		       CTLTYPE_INT, "usermount",
107 		       SYSCTL_DESCR("Whether unprivileged users may mount "
108 				    "filesystems"),
109 		       NULL, 0, &dovfsusermount, 0,
110 		       CTL_CREATE, CTL_EOL);
111 
112 	/* Compatibility: security.curtain */
113 	sysctl_createv(clog, 0, NULL, &rnode,
114 		       CTLFLAG_PERMANENT,
115 		       CTLTYPE_NODE, "security", NULL,
116 		       NULL, 0, NULL, 0,
117 		       CTL_SECURITY, CTL_EOL);
118 
119 	sysctl_createv(clog, 0, &rnode, NULL,
120 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
121 		       CTLTYPE_INT, "curtain",
122 		       SYSCTL_DESCR("Curtain information about objects to "\
123 		       		    "users not owning them."),
124 		       NULL, 0, &secmodel_suser_curtain, 0,
125 		       CTL_CREATE, CTL_EOL);
126 
127 	/* Compatibility: vfs.generic.usermount */
128 	sysctl_createv(clog, 0, NULL, NULL,
129 		       CTLFLAG_PERMANENT,
130 		       CTLTYPE_NODE, "vfs", NULL,
131 		       NULL, 0, NULL, 0,
132 		       CTL_VFS, CTL_EOL);
133 
134 	sysctl_createv(clog, 0, NULL, NULL,
135 		       CTLFLAG_PERMANENT,
136 		       CTLTYPE_NODE, "generic",
137 		       SYSCTL_DESCR("Non-specific vfs related information"),
138 		       NULL, 0, NULL, 0,
139 		       CTL_VFS, VFS_GENERIC, CTL_EOL);
140 
141 	sysctl_createv(clog, 0, NULL, NULL,
142 		       CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
143 		       CTLTYPE_INT, "usermount",
144 		       SYSCTL_DESCR("Whether unprivileged users may mount "
145 				    "filesystems"),
146 		       NULL, 0, &dovfsusermount, 0,
147 		       CTL_VFS, VFS_GENERIC, VFS_USERMOUNT, CTL_EOL);
148 }
149 
150 void
151 secmodel_suser_init(void)
152 {
153 	secmodel_suser_curtain = 0;
154 }
155 
156 void
157 secmodel_suser_start(void)
158 {
159 	l_generic = kauth_listen_scope(KAUTH_SCOPE_GENERIC,
160 	    secmodel_suser_generic_cb, NULL);
161 	l_system = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
162 	    secmodel_suser_system_cb, NULL);
163 	l_process = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
164 	    secmodel_suser_process_cb, NULL);
165 	l_network = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
166 	    secmodel_suser_network_cb, NULL);
167 	l_machdep = kauth_listen_scope(KAUTH_SCOPE_MACHDEP,
168 	    secmodel_suser_machdep_cb, NULL);
169 	l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
170 	    secmodel_suser_device_cb, NULL);
171 	l_vnode = kauth_listen_scope(KAUTH_SCOPE_VNODE,
172 	    secmodel_suser_vnode_cb, NULL);
173 }
174 
175 void
176 secmodel_suser_stop(void)
177 {
178 	kauth_unlisten_scope(l_generic);
179 	kauth_unlisten_scope(l_system);
180 	kauth_unlisten_scope(l_process);
181 	kauth_unlisten_scope(l_network);
182 	kauth_unlisten_scope(l_machdep);
183 	kauth_unlisten_scope(l_device);
184 	kauth_unlisten_scope(l_vnode);
185 }
186 
187 static int
188 suser_modcmd(modcmd_t cmd, void *arg)
189 {
190 	int error = 0;
191 
192 	switch (cmd) {
193 	case MODULE_CMD_INIT:
194 		secmodel_suser_init();
195 		secmodel_suser_start();
196 		sysctl_security_suser_setup(&suser_sysctl_log);
197 		break;
198 
199 	case MODULE_CMD_FINI:
200 		sysctl_teardown(&suser_sysctl_log);
201 		secmodel_suser_stop();
202 		break;
203 
204 	case MODULE_CMD_AUTOUNLOAD:
205 		error = EPERM;
206 		break;
207 
208 	default:
209 		error = ENOTTY;
210 		break;
211 	}
212 
213 	return (error);
214 }
215 
216 /*
217  * kauth(9) listener
218  *
219  * Security model: Traditional NetBSD
220  * Scope: Generic
221  * Responsibility: Superuser access
222  */
223 int
224 secmodel_suser_generic_cb(kauth_cred_t cred, kauth_action_t action,
225     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
226 {
227 	bool isroot;
228 	int result;
229 
230 	isroot = (kauth_cred_geteuid(cred) == 0);
231 	result = KAUTH_RESULT_DEFER;
232 
233 	switch (action) {
234 	case KAUTH_GENERIC_ISSUSER:
235 		if (isroot)
236 			result = KAUTH_RESULT_ALLOW;
237 		break;
238 
239 	default:
240 		break;
241 	}
242 
243 	return (result);
244 }
245 
246 static int
247 suser_usermount_policy(kauth_cred_t cred, enum kauth_system_req req, void *arg1,
248     void *arg2)
249 {
250 	struct mount *mp;
251 	u_long flags;
252 	int result;
253 
254 	result = KAUTH_RESULT_DEFER;
255 
256 	if (!dovfsusermount)
257 		return result;
258 
259 	switch (req) {
260 	case KAUTH_REQ_SYSTEM_MOUNT_NEW:
261 		mp = ((struct vnode *)arg1)->v_mount;
262 		flags= (u_long)arg2;
263 
264 		if (usermount_common_policy(mp, flags) != 0)
265 			break;
266 
267 		result = KAUTH_RESULT_ALLOW;
268 
269 		break;
270 
271 	case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT:
272 		mp = arg1;
273 
274 		/* Must own the mount. */
275 		if (mp->mnt_stat.f_owner != kauth_cred_geteuid(cred))
276 			break;
277 
278 		result = KAUTH_RESULT_ALLOW;
279 
280 		break;
281 
282 	case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
283 		mp = arg1;
284 		flags = (u_long)arg2;
285 
286 		/* Must own the mount. */
287 		if (mp->mnt_stat.f_owner != kauth_cred_geteuid(cred))
288 			break;
289 
290 		if (usermount_common_policy(mp, flags) != 0)
291 			break;
292 
293 		result = KAUTH_RESULT_ALLOW;
294 
295 		break;
296 
297 	default:
298 		break;
299 	}
300 
301 	return result;
302 }
303 
304 /*
305  * kauth(9) listener
306  *
307  * Security model: Traditional NetBSD
308  * Scope: System
309  * Responsibility: Superuser access
310  */
311 int
312 secmodel_suser_system_cb(kauth_cred_t cred, kauth_action_t action,
313     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
314 {
315 	bool isroot;
316 	int result;
317 	enum kauth_system_req req;
318 
319 	isroot = (kauth_cred_geteuid(cred) == 0);
320 	result = KAUTH_RESULT_DEFER;
321 	req = (enum kauth_system_req)arg0;
322 
323 	switch (action) {
324 	case KAUTH_SYSTEM_CPU:
325 		switch (req) {
326 		case KAUTH_REQ_SYSTEM_CPU_SETSTATE:
327 			if (isroot)
328 				result = KAUTH_RESULT_ALLOW;
329 
330 			break;
331 
332 		default:
333 			break;
334 		}
335 
336 		break;
337 
338 	case KAUTH_SYSTEM_FS_QUOTA:
339 		switch (req) {
340 		case KAUTH_REQ_SYSTEM_FS_QUOTA_GET:
341 		case KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF:
342 		case KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE:
343 		case KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT:
344 			if (isroot)
345 				result = KAUTH_RESULT_ALLOW;
346 			break;
347 
348 		default:
349 			break;
350 		}
351 
352 		break;
353 
354 	case KAUTH_SYSTEM_MOUNT:
355 		switch (req) {
356 		case KAUTH_REQ_SYSTEM_MOUNT_GET:
357 			if (isroot) {
358 				result = KAUTH_RESULT_ALLOW;
359 				break;
360 			}
361 
362 			break;
363 
364 		case KAUTH_REQ_SYSTEM_MOUNT_NEW:
365 		case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT:
366 		case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
367 			if (isroot) {
368 				result = KAUTH_RESULT_ALLOW;
369 				break;
370 			}
371 
372 			result = suser_usermount_policy(cred, req, arg1, arg2);
373 
374 			break;
375 
376 		default:
377 			break;
378 		}
379 
380 		break;
381 
382 	case KAUTH_SYSTEM_PSET:
383 		switch (req) {
384 		case KAUTH_REQ_SYSTEM_PSET_ASSIGN:
385 		case KAUTH_REQ_SYSTEM_PSET_BIND:
386 		case KAUTH_REQ_SYSTEM_PSET_CREATE:
387 		case KAUTH_REQ_SYSTEM_PSET_DESTROY:
388 			if (isroot)
389 				result = KAUTH_RESULT_ALLOW;
390 
391 			break;
392 
393 		default:
394 			break;
395 		}
396 
397 		break;
398 
399 	case KAUTH_SYSTEM_TIME:
400 		switch (req) {
401 		case KAUTH_REQ_SYSTEM_TIME_ADJTIME:
402 		case KAUTH_REQ_SYSTEM_TIME_NTPADJTIME:
403 		case KAUTH_REQ_SYSTEM_TIME_TIMECOUNTERS:
404 		case KAUTH_REQ_SYSTEM_TIME_SYSTEM:
405 		case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET:
406 			if (isroot)
407 				result = KAUTH_RESULT_ALLOW;
408 			break;
409 
410 		default:
411 			break;
412 		}
413 		break;
414 
415 	case KAUTH_SYSTEM_SYSCTL:
416 		switch (req) {
417 		case KAUTH_REQ_SYSTEM_SYSCTL_ADD:
418 		case KAUTH_REQ_SYSTEM_SYSCTL_DELETE:
419 		case KAUTH_REQ_SYSTEM_SYSCTL_DESC:
420 		case KAUTH_REQ_SYSTEM_SYSCTL_MODIFY:
421 		case KAUTH_REQ_SYSTEM_SYSCTL_PRVT:
422 			if (isroot)
423 				result = KAUTH_RESULT_ALLOW;
424 			break;
425 
426 		default:
427 			break;
428 		}
429 
430 		break;
431 
432 	case KAUTH_SYSTEM_SWAPCTL:
433 	case KAUTH_SYSTEM_ACCOUNTING:
434 	case KAUTH_SYSTEM_REBOOT:
435 	case KAUTH_SYSTEM_CHROOT:
436 	case KAUTH_SYSTEM_FILEHANDLE:
437 	case KAUTH_SYSTEM_MKNOD:
438 	case KAUTH_SYSTEM_SETIDCORE:
439 	case KAUTH_SYSTEM_MODULE:
440 	case KAUTH_SYSTEM_FS_RESERVEDSPACE:
441 		if (isroot)
442 			result = KAUTH_RESULT_ALLOW;
443 		break;
444 
445 	case KAUTH_SYSTEM_DEBUG:
446 		switch (req) {
447 		case KAUTH_REQ_SYSTEM_DEBUG_IPKDB:
448 			if (isroot)
449 				result = KAUTH_RESULT_ALLOW;
450 
451 			break;
452 
453 		default:
454 			break;
455 		}
456 
457 		break;
458 
459 	case KAUTH_SYSTEM_CHSYSFLAGS:
460 		/*
461 		 * Needs to be checked in conjunction with the immutable and
462 		 * append-only flags (usually). Should be handled differently.
463 		 * Infects ufs, ext2fs, tmpfs, and rump.
464 		 */
465 		if (isroot)
466 			result = KAUTH_RESULT_ALLOW;
467 
468 		break;
469 
470 	default:
471 		break;
472 	}
473 
474 	return (result);
475 }
476 
477 /*
478  * kauth(9) listener
479  *
480  * Security model: Traditional NetBSD
481  * Scope: Process
482  * Responsibility: Superuser access
483  */
484 int
485 secmodel_suser_process_cb(kauth_cred_t cred, kauth_action_t action,
486     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
487 {
488 	struct proc *p;
489 	bool isroot;
490 	int result;
491 
492 	isroot = (kauth_cred_geteuid(cred) == 0);
493 	result = KAUTH_RESULT_DEFER;
494 	p = arg0;
495 
496 	switch (action) {
497 	case KAUTH_PROCESS_SIGNAL:
498 	case KAUTH_PROCESS_KTRACE:
499 	case KAUTH_PROCESS_PROCFS:
500 	case KAUTH_PROCESS_PTRACE:
501 	case KAUTH_PROCESS_SCHEDULER_GETPARAM:
502 	case KAUTH_PROCESS_SCHEDULER_SETPARAM:
503 	case KAUTH_PROCESS_SCHEDULER_GETAFFINITY:
504 	case KAUTH_PROCESS_SCHEDULER_SETAFFINITY:
505 	case KAUTH_PROCESS_SETID:
506 	case KAUTH_PROCESS_KEVENT_FILTER:
507 	case KAUTH_PROCESS_NICE:
508 	case KAUTH_PROCESS_FORK:
509 	case KAUTH_PROCESS_CORENAME:
510 	case KAUTH_PROCESS_STOPFLAG:
511 		if (isroot)
512 			result = KAUTH_RESULT_ALLOW;
513 
514 		break;
515 
516 	case KAUTH_PROCESS_CANSEE: {
517 		unsigned long req;
518 
519 		req = (unsigned long)arg1;
520 
521 		switch (req) {
522 		case KAUTH_REQ_PROCESS_CANSEE_ARGS:
523 		case KAUTH_REQ_PROCESS_CANSEE_ENTRY:
524 		case KAUTH_REQ_PROCESS_CANSEE_OPENFILES:
525 			if (isroot) {
526 				result = KAUTH_RESULT_ALLOW;
527 				break;
528 			}
529 
530 			if (secmodel_suser_curtain) {
531 				if (!kauth_cred_uidmatch(cred, p->p_cred))
532 					result = KAUTH_RESULT_DENY;
533 			}
534 
535 			break;
536 
537 		case KAUTH_REQ_PROCESS_CANSEE_ENV:
538 			if (isroot)
539 				result = KAUTH_RESULT_ALLOW;
540 
541 			break;
542 
543 		default:
544 			break;
545 		}
546 
547 		break;
548 		}
549 
550 	case KAUTH_PROCESS_RLIMIT: {
551 		enum kauth_process_req req;
552 
553 		req = (enum kauth_process_req)(unsigned long)arg1;
554 
555 		switch (req) {
556 		case KAUTH_REQ_PROCESS_RLIMIT_SET:
557 		case KAUTH_REQ_PROCESS_RLIMIT_GET:
558 			if (isroot)
559 				result = KAUTH_RESULT_ALLOW;
560 
561 			break;
562 
563 		default:
564 			break;
565 		}
566 
567 		break;
568 		}
569 
570 	default:
571 		break;
572 	}
573 
574 	return (result);
575 }
576 
577 /*
578  * kauth(9) listener
579  *
580  * Security model: Traditional NetBSD
581  * Scope: Network
582  * Responsibility: Superuser access
583  */
584 int
585 secmodel_suser_network_cb(kauth_cred_t cred, kauth_action_t action,
586     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
587 {
588 	bool isroot;
589 	int result;
590 	enum kauth_network_req req;
591 
592 	isroot = (kauth_cred_geteuid(cred) == 0);
593 	result = KAUTH_RESULT_DEFER;
594 	req = (enum kauth_network_req)arg0;
595 
596 	switch (action) {
597 	case KAUTH_NETWORK_ALTQ:
598 		switch (req) {
599 		case KAUTH_REQ_NETWORK_ALTQ_AFMAP:
600 		case KAUTH_REQ_NETWORK_ALTQ_BLUE:
601 		case KAUTH_REQ_NETWORK_ALTQ_CBQ:
602 		case KAUTH_REQ_NETWORK_ALTQ_CDNR:
603 		case KAUTH_REQ_NETWORK_ALTQ_CONF:
604 		case KAUTH_REQ_NETWORK_ALTQ_FIFOQ:
605 		case KAUTH_REQ_NETWORK_ALTQ_HFSC:
606 		case KAUTH_REQ_NETWORK_ALTQ_JOBS:
607 		case KAUTH_REQ_NETWORK_ALTQ_PRIQ:
608 		case KAUTH_REQ_NETWORK_ALTQ_RED:
609 		case KAUTH_REQ_NETWORK_ALTQ_RIO:
610 		case KAUTH_REQ_NETWORK_ALTQ_WFQ:
611 			if (isroot)
612 				result = KAUTH_RESULT_ALLOW;
613 			break;
614 
615 		default:
616 			break;
617 		}
618 
619 		break;
620 
621 	case KAUTH_NETWORK_BIND:
622 		switch (req) {
623 		case KAUTH_REQ_NETWORK_BIND_PORT:
624 		case KAUTH_REQ_NETWORK_BIND_PRIVPORT:
625 			if (isroot)
626 				result = KAUTH_RESULT_ALLOW;
627 			break;
628 
629 		default:
630 			break;
631 		}
632 		break;
633 
634 	case KAUTH_NETWORK_FIREWALL:
635 		switch (req) {
636 		case KAUTH_REQ_NETWORK_FIREWALL_FW:
637 		case KAUTH_REQ_NETWORK_FIREWALL_NAT:
638 			if (isroot)
639 				result = KAUTH_RESULT_ALLOW;
640 
641 			break;
642 
643 		default:
644 			break;
645 		}
646 		break;
647 
648 	case KAUTH_NETWORK_FORWSRCRT:
649 	case KAUTH_NETWORK_ROUTE:
650 		if (isroot)
651 			result = KAUTH_RESULT_ALLOW;
652 
653 		break;
654 
655 	case KAUTH_NETWORK_INTERFACE:
656 		switch (req) {
657 		case KAUTH_REQ_NETWORK_INTERFACE_GET:
658 		case KAUTH_REQ_NETWORK_INTERFACE_SET:
659 		case KAUTH_REQ_NETWORK_INTERFACE_GETPRIV:
660 		case KAUTH_REQ_NETWORK_INTERFACE_SETPRIV:
661 			if (isroot)
662 				result = KAUTH_RESULT_ALLOW;
663 			break;
664 
665 		default:
666 			break;
667 		}
668 		break;
669 
670 	case KAUTH_NETWORK_INTERFACE_PPP:
671 		switch (req) {
672 		case KAUTH_REQ_NETWORK_INTERFACE_PPP_ADD:
673 			if (isroot)
674 				result = KAUTH_RESULT_ALLOW;
675 			break;
676 
677 		default:
678 			break;
679 		}
680 
681 		break;
682 
683 	case KAUTH_NETWORK_INTERFACE_SLIP:
684 		switch (req) {
685 		case KAUTH_REQ_NETWORK_INTERFACE_SLIP_ADD:
686 			if (isroot)
687 				result = KAUTH_RESULT_ALLOW;
688 			break;
689 
690 		default:
691 			break;
692 		}
693 
694 		break;
695 
696 	case KAUTH_NETWORK_INTERFACE_STRIP:
697 		switch (req) {
698 		case KAUTH_REQ_NETWORK_INTERFACE_STRIP_ADD:
699 			if (isroot)
700 				result = KAUTH_RESULT_ALLOW;
701 			break;
702 
703 		default:
704 			break;
705 		}
706 
707 		break;
708 
709 	case KAUTH_NETWORK_INTERFACE_TUN:
710 		switch (req) {
711 		case KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD:
712 			if (isroot)
713 				result = KAUTH_RESULT_ALLOW;
714 			break;
715 
716 		default:
717 			break;
718 		}
719 
720 		break;
721 
722 	case KAUTH_NETWORK_NFS:
723 		switch (req) {
724 		case KAUTH_REQ_NETWORK_NFS_EXPORT:
725 		case KAUTH_REQ_NETWORK_NFS_SVC:
726 			if (isroot)
727 				result = KAUTH_RESULT_ALLOW;
728 
729 			break;
730 
731 		default:
732 			break;
733 		}
734 		break;
735 
736 	case KAUTH_NETWORK_SOCKET:
737 		switch (req) {
738 		case KAUTH_REQ_NETWORK_SOCKET_DROP:
739 		case KAUTH_REQ_NETWORK_SOCKET_OPEN:
740 		case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK:
741 		case KAUTH_REQ_NETWORK_SOCKET_SETPRIV:
742 			if (isroot)
743 				result = KAUTH_RESULT_ALLOW;
744 			break;
745 
746 		case KAUTH_REQ_NETWORK_SOCKET_CANSEE:
747 			if (isroot) {
748 				result = KAUTH_RESULT_ALLOW;
749 				break;
750 			}
751 
752 			if (secmodel_suser_curtain) {
753 				struct socket *so;
754 
755 				so = (struct socket *)arg1;
756 
757 				if (!proc_uidmatch(cred, so->so_cred))
758 					result = KAUTH_RESULT_DENY;
759 			}
760 
761 			break;
762 
763 		default:
764 			break;
765 		}
766 
767 		break;
768 
769 
770 	default:
771 		break;
772 	}
773 
774 	return (result);
775 }
776 
777 /*
778  * kauth(9) listener
779  *
780  * Security model: Traditional NetBSD
781  * Scope: Machdep
782  * Responsibility: Superuser access
783  */
784 int
785 secmodel_suser_machdep_cb(kauth_cred_t cred, kauth_action_t action,
786     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
787 {
788         bool isroot;
789         int result;
790 
791         isroot = (kauth_cred_geteuid(cred) == 0);
792         result = KAUTH_RESULT_DEFER;
793 
794         switch (action) {
795 	case KAUTH_MACHDEP_IOPERM_GET:
796 	case KAUTH_MACHDEP_LDT_GET:
797 	case KAUTH_MACHDEP_LDT_SET:
798 	case KAUTH_MACHDEP_MTRR_GET:
799 	case KAUTH_MACHDEP_CACHEFLUSH:
800 	case KAUTH_MACHDEP_IOPERM_SET:
801 	case KAUTH_MACHDEP_IOPL:
802 	case KAUTH_MACHDEP_MTRR_SET:
803 	case KAUTH_MACHDEP_NVRAM:
804 	case KAUTH_MACHDEP_UNMANAGEDMEM:
805 		if (isroot)
806 			result = KAUTH_RESULT_ALLOW;
807 		break;
808 
809 	default:
810 		break;
811 	}
812 
813 	return (result);
814 }
815 
816 /*
817  * kauth(9) listener
818  *
819  * Security model: Traditional NetBSD
820  * Scope: Device
821  * Responsibility: Superuser access
822  */
823 int
824 secmodel_suser_device_cb(kauth_cred_t cred, kauth_action_t action,
825     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
826 {
827         bool isroot;
828         int result;
829 
830         isroot = (kauth_cred_geteuid(cred) == 0);
831         result = KAUTH_RESULT_DEFER;
832 
833 	switch (action) {
834 	case KAUTH_DEVICE_BLUETOOTH_SETPRIV:
835 	case KAUTH_DEVICE_BLUETOOTH_SEND:
836 	case KAUTH_DEVICE_BLUETOOTH_RECV:
837 	case KAUTH_DEVICE_TTY_OPEN:
838 	case KAUTH_DEVICE_TTY_PRIVSET:
839 	case KAUTH_DEVICE_TTY_STI:
840 	case KAUTH_DEVICE_RND_ADDDATA:
841 	case KAUTH_DEVICE_RND_GETPRIV:
842 	case KAUTH_DEVICE_RND_SETPRIV:
843 		if (isroot)
844 			result = KAUTH_RESULT_ALLOW;
845 		break;
846 
847 	case KAUTH_DEVICE_BLUETOOTH_BCSP:
848 	case KAUTH_DEVICE_BLUETOOTH_BTUART: {
849 		enum kauth_device_req req;
850 
851 		req = (enum kauth_device_req)arg0;
852 		switch (req) {
853 		case KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD:
854 		case KAUTH_REQ_DEVICE_BLUETOOTH_BTUART_ADD:
855 			if (isroot)
856 				result = KAUTH_RESULT_ALLOW;
857 			break;
858 
859 		default:
860 			break;
861 		}
862 
863 		break;
864 		}
865 
866 	case KAUTH_DEVICE_GPIO_PINSET:
867 		/*
868 		 * root can access gpio pins, secmodel_securlevel can veto
869 		 * this decision.
870 		 */
871 		if (isroot)
872 			result = KAUTH_RESULT_ALLOW;
873 		break;
874 
875 	default:
876 		break;
877 	}
878 
879 	return (result);
880 }
881 
882 int
883 secmodel_suser_vnode_cb(kauth_cred_t cred, kauth_action_t action,
884     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
885 {
886 	bool isroot;
887 	int result;
888 
889 	isroot = (kauth_cred_geteuid(cred) == 0);
890 	result = KAUTH_RESULT_DEFER;
891 
892 	if (isroot)
893 		result = KAUTH_RESULT_ALLOW;
894 
895 	return (result);
896 }
897 
898