xref: /netbsd-src/sys/secmodel/suser/secmodel_suser.c (revision 19aecbc6b0cd8e6512872ee8688d34d15845bb81)
1 /* $NetBSD: secmodel_suser.c,v 1.58 2024/03/01 22:01:03 andvar 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.58 2024/03/01 22:01:03 andvar 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/secmodel.h>
56 #include <secmodel/suser/suser.h>
57 
58 MODULE(MODULE_CLASS_SECMODEL, suser, NULL);
59 
60 static kauth_listener_t l_generic, l_system, l_process, l_network, l_machdep,
61     l_device, l_vnode;
62 
63 static secmodel_t suser_sm;
64 
65 SYSCTL_SETUP(sysctl_security_suser_setup, "secmodel_user sysctl")
66 {
67 	const struct sysctlnode *rnode;
68 
69 	sysctl_createv(clog, 0, NULL, &rnode,
70 		       CTLFLAG_PERMANENT,
71 		       CTLTYPE_NODE, "models", NULL,
72 		       NULL, 0, NULL, 0,
73 		       CTL_SECURITY, CTL_CREATE, CTL_EOL);
74 
75 	sysctl_createv(clog, 0, &rnode, &rnode,
76 		       CTLFLAG_PERMANENT,
77 		       CTLTYPE_NODE, "suser", NULL,
78 		       NULL, 0, NULL, 0,
79 		       CTL_CREATE, CTL_EOL);
80 
81 	sysctl_createv(clog, 0, &rnode, NULL,
82 		       CTLFLAG_PERMANENT,
83 		       CTLTYPE_STRING, "name", NULL,
84 		       NULL, 0, __UNCONST(SECMODEL_SUSER_NAME), 0,
85 		       CTL_CREATE, CTL_EOL);
86 }
87 
88 void
secmodel_suser_init(void)89 secmodel_suser_init(void)
90 {
91 
92 }
93 
94 void
secmodel_suser_start(void)95 secmodel_suser_start(void)
96 {
97 	l_generic = kauth_listen_scope(KAUTH_SCOPE_GENERIC,
98 	    secmodel_suser_generic_cb, NULL);
99 	l_system = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
100 	    secmodel_suser_system_cb, NULL);
101 	l_process = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
102 	    secmodel_suser_process_cb, NULL);
103 	l_network = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
104 	    secmodel_suser_network_cb, NULL);
105 	l_machdep = kauth_listen_scope(KAUTH_SCOPE_MACHDEP,
106 	    secmodel_suser_machdep_cb, NULL);
107 	l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
108 	    secmodel_suser_device_cb, NULL);
109 	l_vnode = kauth_listen_scope(KAUTH_SCOPE_VNODE,
110 	    secmodel_suser_vnode_cb, NULL);
111 }
112 
113 void
secmodel_suser_stop(void)114 secmodel_suser_stop(void)
115 {
116 	kauth_unlisten_scope(l_generic);
117 	kauth_unlisten_scope(l_system);
118 	kauth_unlisten_scope(l_process);
119 	kauth_unlisten_scope(l_network);
120 	kauth_unlisten_scope(l_machdep);
121 	kauth_unlisten_scope(l_device);
122 	kauth_unlisten_scope(l_vnode);
123 }
124 
125 static bool
suser_isroot(kauth_cred_t cred)126 suser_isroot(kauth_cred_t cred)
127 {
128 	return kauth_cred_geteuid(cred) == 0;
129 }
130 
131 static int
suser_eval(const char * what,void * arg,void * ret)132 suser_eval(const char *what, void *arg, void *ret)
133 {
134 	int error = 0;
135 
136 	if (strcasecmp(what, "is-root") == 0) {
137 		kauth_cred_t cred = arg;
138 		bool *bp = ret;
139 
140 		*bp = suser_isroot(cred);
141 	} else {
142 		error = ENOENT;
143 	}
144 
145 	return error;
146 }
147 
148 static int
suser_modcmd(modcmd_t cmd,void * arg)149 suser_modcmd(modcmd_t cmd, void *arg)
150 {
151 	int error = 0;
152 
153 	switch (cmd) {
154 	case MODULE_CMD_INIT:
155 		error = secmodel_register(&suser_sm,
156 		    SECMODEL_SUSER_ID, SECMODEL_SUSER_NAME,
157 		    NULL, suser_eval, NULL);
158 		if (error != 0)
159 			printf("suser_modcmd::init: secmodel_register "
160 			    "returned %d\n", error);
161 
162 		secmodel_suser_init();
163 		secmodel_suser_start();
164 		break;
165 
166 	case MODULE_CMD_FINI:
167 		secmodel_suser_stop();
168 
169 		error = secmodel_deregister(suser_sm);
170 		if (error != 0)
171 			printf("suser_modcmd::fini: secmodel_deregister "
172 			    "returned %d\n", error);
173 
174 		break;
175 
176 	case MODULE_CMD_AUTOUNLOAD:
177 		error = EPERM;
178 		break;
179 
180 	default:
181 		error = ENOTTY;
182 		break;
183 	}
184 
185 	return (error);
186 }
187 
188 /*
189  * kauth(9) listener
190  *
191  * Security model: Traditional NetBSD
192  * Scope: Generic
193  * Responsibility: Superuser access
194  */
195 int
secmodel_suser_generic_cb(kauth_cred_t cred,kauth_action_t action,void * cookie,void * arg0,void * arg1,void * arg2,void * arg3)196 secmodel_suser_generic_cb(kauth_cred_t cred, kauth_action_t action,
197     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
198 {
199 	bool isroot;
200 	int result;
201 
202 	isroot = suser_isroot(cred);
203 	result = KAUTH_RESULT_DEFER;
204 
205 	switch (action) {
206 	case KAUTH_GENERIC_ISSUSER:
207 		if (isroot)
208 			result = KAUTH_RESULT_ALLOW;
209 		break;
210 
211 	default:
212 		break;
213 	}
214 
215 	return (result);
216 }
217 
218 /*
219  * kauth(9) listener
220  *
221  * Security model: Traditional NetBSD
222  * Scope: System
223  * Responsibility: Superuser access
224  */
225 int
secmodel_suser_system_cb(kauth_cred_t cred,kauth_action_t action,void * cookie,void * arg0,void * arg1,void * arg2,void * arg3)226 secmodel_suser_system_cb(kauth_cred_t cred, kauth_action_t action,
227     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
228 {
229 	bool isroot;
230 	int result;
231 	enum kauth_system_req req;
232 
233 	isroot = suser_isroot(cred);
234 	result = KAUTH_RESULT_DEFER;
235 	req = (enum kauth_system_req)(uintptr_t)arg0;
236 
237 	switch (action) {
238 	case KAUTH_SYSTEM_CPU:
239 		switch (req) {
240 		case KAUTH_REQ_SYSTEM_CPU_SETSTATE:
241 			if (isroot)
242 				result = KAUTH_RESULT_ALLOW;
243 
244 			break;
245 
246 		default:
247 			break;
248 		}
249 
250 		break;
251 
252 	case KAUTH_SYSTEM_DEVMAPPER:
253 		if (isroot)
254 			result = KAUTH_RESULT_ALLOW;
255 
256 		break;
257 
258 	case KAUTH_SYSTEM_FS_QUOTA:
259 		switch (req) {
260 		case KAUTH_REQ_SYSTEM_FS_QUOTA_GET:
261 		case KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF:
262 		case KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE:
263 		case KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT:
264 			if (isroot)
265 				result = KAUTH_RESULT_ALLOW;
266 			break;
267 
268 		default:
269 			break;
270 		}
271 
272 		break;
273 
274 	case KAUTH_SYSTEM_SYSVIPC:
275 		switch (req) {
276 		case KAUTH_REQ_SYSTEM_SYSVIPC_BYPASS:
277 		case KAUTH_REQ_SYSTEM_SYSVIPC_SHM_LOCK:
278 		case KAUTH_REQ_SYSTEM_SYSVIPC_SHM_UNLOCK:
279 		case KAUTH_REQ_SYSTEM_SYSVIPC_MSGQ_OVERSIZE:
280 			if (isroot)
281 				result = KAUTH_RESULT_ALLOW;
282 
283 			break;
284 
285 		default:
286 			break;
287 		}
288 
289 		break;
290 
291 	case KAUTH_SYSTEM_MOUNT:
292 		switch (req) {
293 		case KAUTH_REQ_SYSTEM_MOUNT_DEVICE:
294 		case KAUTH_REQ_SYSTEM_MOUNT_GET:
295 		case KAUTH_REQ_SYSTEM_MOUNT_NEW:
296 		case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT:
297 		case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
298 		case KAUTH_REQ_SYSTEM_MOUNT_UMAP:
299 			if (isroot) {
300 				result = KAUTH_RESULT_ALLOW;
301 				break;
302 			}
303 
304 			break;
305 
306 		default:
307 			break;
308 		}
309 
310 		break;
311 
312 	case KAUTH_SYSTEM_MQUEUE:
313 		if (isroot)
314 			result = KAUTH_RESULT_ALLOW;
315 
316 		break;
317 
318 	case KAUTH_SYSTEM_PSET:
319 		switch (req) {
320 		case KAUTH_REQ_SYSTEM_PSET_ASSIGN:
321 		case KAUTH_REQ_SYSTEM_PSET_BIND:
322 		case KAUTH_REQ_SYSTEM_PSET_CREATE:
323 		case KAUTH_REQ_SYSTEM_PSET_DESTROY:
324 			if (isroot)
325 				result = KAUTH_RESULT_ALLOW;
326 
327 			break;
328 
329 		default:
330 			break;
331 		}
332 
333 		break;
334 
335 	case KAUTH_SYSTEM_TIME:
336 		switch (req) {
337 		case KAUTH_REQ_SYSTEM_TIME_ADJTIME:
338 		case KAUTH_REQ_SYSTEM_TIME_NTPADJTIME:
339 		case KAUTH_REQ_SYSTEM_TIME_TIMECOUNTERS:
340 		case KAUTH_REQ_SYSTEM_TIME_SYSTEM:
341 		case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET:
342 			if (isroot)
343 				result = KAUTH_RESULT_ALLOW;
344 			break;
345 
346 		default:
347 			break;
348 		}
349 		break;
350 
351 	case KAUTH_SYSTEM_SEMAPHORE:
352 		if (isroot)
353 			result = KAUTH_RESULT_ALLOW;
354 
355 		break;
356 
357 	case KAUTH_SYSTEM_SYSCTL:
358 		switch (req) {
359 		case KAUTH_REQ_SYSTEM_SYSCTL_ADD:
360 		case KAUTH_REQ_SYSTEM_SYSCTL_DELETE:
361 		case KAUTH_REQ_SYSTEM_SYSCTL_DESC:
362 		case KAUTH_REQ_SYSTEM_SYSCTL_MODIFY:
363 		case KAUTH_REQ_SYSTEM_SYSCTL_PRVT:
364 			if (isroot)
365 				result = KAUTH_RESULT_ALLOW;
366 			break;
367 
368 		default:
369 			break;
370 		}
371 
372 		break;
373 
374 	case KAUTH_SYSTEM_SWAPCTL:
375 	case KAUTH_SYSTEM_ACCOUNTING:
376 	case KAUTH_SYSTEM_REBOOT:
377 	case KAUTH_SYSTEM_CHROOT:
378 	case KAUTH_SYSTEM_FILEHANDLE:
379 	case KAUTH_SYSTEM_MKNOD:
380 	case KAUTH_SYSTEM_SETIDCORE:
381 	case KAUTH_SYSTEM_MODULE:
382 	case KAUTH_SYSTEM_FS_RESERVEDSPACE:
383 	case KAUTH_SYSTEM_MAP_VA_ZERO:
384 	case KAUTH_SYSTEM_FS_EXTATTR:
385 	case KAUTH_SYSTEM_FS_SNAPSHOT:
386 		if (isroot)
387 			result = KAUTH_RESULT_ALLOW;
388 		break;
389 
390 	case KAUTH_SYSTEM_DEBUG:
391 		break;
392 
393 	case KAUTH_SYSTEM_CHSYSFLAGS:
394 		/* Deprecated. */
395 		if (isroot)
396 			result = KAUTH_RESULT_ALLOW;
397 
398 		break;
399 
400 	case KAUTH_SYSTEM_VERIEXEC:
401 		switch (req) {
402 		case KAUTH_REQ_SYSTEM_VERIEXEC_ACCESS:
403 		case KAUTH_REQ_SYSTEM_VERIEXEC_MODIFY:
404 			if (isroot)
405 				result = KAUTH_RESULT_ALLOW;
406 
407 			break;
408 
409 		default:
410 			break;
411 		}
412 
413 		break;
414 
415 	case KAUTH_SYSTEM_LFS:
416 		switch (req) {
417 		case KAUTH_REQ_SYSTEM_LFS_MARKV:
418 		case KAUTH_REQ_SYSTEM_LFS_BMAPV:
419 		case KAUTH_REQ_SYSTEM_LFS_SEGCLEAN:
420 		case KAUTH_REQ_SYSTEM_LFS_SEGWAIT:
421 		case KAUTH_REQ_SYSTEM_LFS_FCNTL:
422 			if (isroot)
423 				result = KAUTH_RESULT_ALLOW;
424 
425 		default:
426 			break;
427 		}
428 
429 		break;
430 
431 	case KAUTH_SYSTEM_INTR:
432 		switch (req) {
433 		case KAUTH_REQ_SYSTEM_INTR_AFFINITY:
434 			if (isroot)
435 				result = KAUTH_RESULT_ALLOW;
436 
437 			break;
438 
439 		default:
440 			break;
441 		}
442 
443 		break;
444 
445 	case KAUTH_SYSTEM_KERNADDR:
446 		if (isroot)
447 			result = KAUTH_RESULT_ALLOW;
448 
449 		break;
450 
451 	default:
452 		break;
453 	}
454 
455 	return (result);
456 }
457 
458 /*
459  * kauth(9) listener
460  *
461  * Security model: Traditional NetBSD
462  * Scope: Process
463  * Responsibility: Superuser access
464  */
465 int
secmodel_suser_process_cb(kauth_cred_t cred,kauth_action_t action,void * cookie,void * arg0,void * arg1,void * arg2,void * arg3)466 secmodel_suser_process_cb(kauth_cred_t cred, kauth_action_t action,
467     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
468 {
469 	bool isroot;
470 	int result;
471 
472 	isroot = suser_isroot(cred);
473 	result = KAUTH_RESULT_DEFER;
474 
475 	switch (action) {
476 	case KAUTH_PROCESS_SIGNAL:
477 	case KAUTH_PROCESS_KTRACE:
478 	case KAUTH_PROCESS_PROCFS:
479 	case KAUTH_PROCESS_PTRACE:
480 	case KAUTH_PROCESS_SCHEDULER_GETPARAM:
481 	case KAUTH_PROCESS_SCHEDULER_SETPARAM:
482 	case KAUTH_PROCESS_SCHEDULER_GETAFFINITY:
483 	case KAUTH_PROCESS_SCHEDULER_SETAFFINITY:
484 	case KAUTH_PROCESS_SETID:
485 	case KAUTH_PROCESS_KEVENT_FILTER:
486 	case KAUTH_PROCESS_NICE:
487 	case KAUTH_PROCESS_FORK:
488 	case KAUTH_PROCESS_CORENAME:
489 	case KAUTH_PROCESS_STOPFLAG:
490 		if (isroot)
491 			result = KAUTH_RESULT_ALLOW;
492 
493 		break;
494 
495 	case KAUTH_PROCESS_CANSEE: {
496 		unsigned long req;
497 
498 		req = (unsigned long)arg1;
499 
500 		switch (req) {
501 		case KAUTH_REQ_PROCESS_CANSEE_ARGS:
502 		case KAUTH_REQ_PROCESS_CANSEE_ENTRY:
503 		case KAUTH_REQ_PROCESS_CANSEE_OPENFILES:
504 		case KAUTH_REQ_PROCESS_CANSEE_EPROC:
505 		case KAUTH_REQ_PROCESS_CANSEE_KPTR:
506 			if (isroot) {
507 				result = KAUTH_RESULT_ALLOW;
508 				break;
509 			}
510 
511 			break;
512 
513 		case KAUTH_REQ_PROCESS_CANSEE_ENV:
514 			if (isroot)
515 				result = KAUTH_RESULT_ALLOW;
516 
517 			break;
518 
519 		default:
520 			break;
521 		}
522 
523 		break;
524 		}
525 
526 	case KAUTH_PROCESS_RLIMIT: {
527 		enum kauth_process_req req;
528 
529 		req = (enum kauth_process_req)(uintptr_t)arg1;
530 
531 		switch (req) {
532 		case KAUTH_REQ_PROCESS_RLIMIT_SET:
533 		case KAUTH_REQ_PROCESS_RLIMIT_GET:
534 		case KAUTH_REQ_PROCESS_RLIMIT_BYPASS:
535 			if (isroot)
536 				result = KAUTH_RESULT_ALLOW;
537 
538 			break;
539 
540 		default:
541 			break;
542 		}
543 
544 		break;
545 		}
546 
547 	default:
548 		break;
549 	}
550 
551 	return (result);
552 }
553 
554 /*
555  * kauth(9) listener
556  *
557  * Security model: Traditional NetBSD
558  * Scope: Network
559  * Responsibility: Superuser access
560  */
561 int
secmodel_suser_network_cb(kauth_cred_t cred,kauth_action_t action,void * cookie,void * arg0,void * arg1,void * arg2,void * arg3)562 secmodel_suser_network_cb(kauth_cred_t cred, kauth_action_t action,
563     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
564 {
565 	bool isroot;
566 	int result;
567 	enum kauth_network_req req;
568 
569 	isroot = suser_isroot(cred);
570 	result = KAUTH_RESULT_DEFER;
571 	req = (enum kauth_network_req)(uintptr_t)arg0;
572 
573 	switch (action) {
574 	case KAUTH_NETWORK_ALTQ:
575 		switch (req) {
576 		case KAUTH_REQ_NETWORK_ALTQ_AFMAP:
577 		case KAUTH_REQ_NETWORK_ALTQ_BLUE:
578 		case KAUTH_REQ_NETWORK_ALTQ_CBQ:
579 		case KAUTH_REQ_NETWORK_ALTQ_CDNR:
580 		case KAUTH_REQ_NETWORK_ALTQ_CONF:
581 		case KAUTH_REQ_NETWORK_ALTQ_FIFOQ:
582 		case KAUTH_REQ_NETWORK_ALTQ_HFSC:
583 		case KAUTH_REQ_NETWORK_ALTQ_JOBS:
584 		case KAUTH_REQ_NETWORK_ALTQ_PRIQ:
585 		case KAUTH_REQ_NETWORK_ALTQ_RED:
586 		case KAUTH_REQ_NETWORK_ALTQ_RIO:
587 		case KAUTH_REQ_NETWORK_ALTQ_WFQ:
588 			if (isroot)
589 				result = KAUTH_RESULT_ALLOW;
590 			break;
591 
592 		default:
593 			break;
594 		}
595 
596 		break;
597 
598 	case KAUTH_NETWORK_BIND:
599 		switch (req) {
600 		case KAUTH_REQ_NETWORK_BIND_PORT:
601 		case KAUTH_REQ_NETWORK_BIND_PRIVPORT:
602 		case KAUTH_REQ_NETWORK_BIND_ANYADDR:
603 			if (isroot)
604 				result = KAUTH_RESULT_ALLOW;
605 			break;
606 
607 		default:
608 			break;
609 		}
610 		break;
611 
612 	case KAUTH_NETWORK_FIREWALL:
613 		switch (req) {
614 		case KAUTH_REQ_NETWORK_FIREWALL_FW:
615 		case KAUTH_REQ_NETWORK_FIREWALL_NAT:
616 			if (isroot)
617 				result = KAUTH_RESULT_ALLOW;
618 
619 			break;
620 
621 		default:
622 			break;
623 		}
624 		break;
625 
626 	case KAUTH_NETWORK_FORWSRCRT:
627 	case KAUTH_NETWORK_ROUTE:
628 		if (isroot)
629 			result = KAUTH_RESULT_ALLOW;
630 
631 		break;
632 
633 	case KAUTH_NETWORK_INTERFACE:
634 		switch (req) {
635 		case KAUTH_REQ_NETWORK_INTERFACE_GET:
636 		case KAUTH_REQ_NETWORK_INTERFACE_SET:
637 		case KAUTH_REQ_NETWORK_INTERFACE_GETPRIV:
638 		case KAUTH_REQ_NETWORK_INTERFACE_SETPRIV:
639 		case KAUTH_REQ_NETWORK_INTERFACE_FIRMWARE:
640 			if (isroot)
641 				result = KAUTH_RESULT_ALLOW;
642 			break;
643 
644 		default:
645 			break;
646 		}
647 		break;
648 
649 	case KAUTH_NETWORK_INTERFACE_BRIDGE:
650 		switch (req) {
651 		case KAUTH_REQ_NETWORK_INTERFACE_BRIDGE_GETPRIV:
652 		case KAUTH_REQ_NETWORK_INTERFACE_BRIDGE_SETPRIV:
653 			if (isroot)
654 				result = KAUTH_RESULT_ALLOW;
655 			break;
656 
657 		default:
658 			break;
659 		}
660 
661 		break;
662 
663 	case KAUTH_NETWORK_INTERFACE_PPP:
664 		switch (req) {
665 		case KAUTH_REQ_NETWORK_INTERFACE_PPP_ADD:
666 			if (isroot)
667 				result = KAUTH_RESULT_ALLOW;
668 			break;
669 
670 		default:
671 			break;
672 		}
673 
674 		break;
675 
676 	case KAUTH_NETWORK_INTERFACE_PVC:
677 		switch (req) {
678 		case KAUTH_REQ_NETWORK_INTERFACE_PVC_ADD:
679 			if (isroot)
680 				result = KAUTH_RESULT_ALLOW;
681 
682 			break;
683 
684 		default:
685 			break;
686 		}
687 
688 		break;
689 
690 	case KAUTH_NETWORK_INTERFACE_SLIP:
691 		switch (req) {
692 		case KAUTH_REQ_NETWORK_INTERFACE_SLIP_ADD:
693 			if (isroot)
694 				result = KAUTH_RESULT_ALLOW;
695 			break;
696 
697 		default:
698 			break;
699 		}
700 
701 		break;
702 
703 	case KAUTH_NETWORK_INTERFACE_TUN:
704 		switch (req) {
705 		case KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD:
706 			if (isroot)
707 				result = KAUTH_RESULT_ALLOW;
708 			break;
709 
710 		default:
711 			break;
712 		}
713 
714 		break;
715 
716 	case KAUTH_NETWORK_IPV6:
717 		switch (req) {
718 		case KAUTH_REQ_NETWORK_IPV6_HOPBYHOP:
719 		case KAUTH_REQ_NETWORK_IPV6_JOIN_MULTICAST:
720 			if (isroot)
721 				result = KAUTH_RESULT_ALLOW;
722 
723 			break;
724 
725 		default:
726 			break;
727 		}
728 
729 		break;
730 
731 	case KAUTH_NETWORK_NFS:
732 		switch (req) {
733 		case KAUTH_REQ_NETWORK_NFS_EXPORT:
734 		case KAUTH_REQ_NETWORK_NFS_SVC:
735 			if (isroot)
736 				result = KAUTH_RESULT_ALLOW;
737 
738 			break;
739 
740 		default:
741 			break;
742 		}
743 		break;
744 
745 	case KAUTH_NETWORK_SMB:
746 		switch (req) {
747 		case KAUTH_REQ_NETWORK_SMB_SHARE_ACCESS:
748 		case KAUTH_REQ_NETWORK_SMB_SHARE_CREATE:
749 		case KAUTH_REQ_NETWORK_SMB_VC_ACCESS:
750 		case KAUTH_REQ_NETWORK_SMB_VC_CREATE:
751 			if (isroot)
752 				result = KAUTH_RESULT_ALLOW;
753 
754 			break;
755 
756 		default:
757 			break;
758 		}
759 
760 		break;
761 
762 	case KAUTH_NETWORK_INTERFACE_WG:
763 		switch (req) {
764 		case KAUTH_REQ_NETWORK_INTERFACE_WG_GETPRIV:
765 		case KAUTH_REQ_NETWORK_INTERFACE_WG_SETPRIV:
766 			if (isroot)
767 				result = KAUTH_RESULT_ALLOW;
768 			break;
769 
770 		default:
771 			break;
772 		}
773 
774 		break;
775 
776 	case KAUTH_NETWORK_SOCKET:
777 		switch (req) {
778 		case KAUTH_REQ_NETWORK_SOCKET_DROP:
779 		case KAUTH_REQ_NETWORK_SOCKET_OPEN:
780 		case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK:
781 		case KAUTH_REQ_NETWORK_SOCKET_SETPRIV:
782 			if (isroot)
783 				result = KAUTH_RESULT_ALLOW;
784 			break;
785 
786 		case KAUTH_REQ_NETWORK_SOCKET_CANSEE:
787 			if (isroot) {
788 				result = KAUTH_RESULT_ALLOW;
789 				break;
790 			}
791 
792 			break;
793 
794 		default:
795 			break;
796 		}
797 
798 		break;
799 
800 	case KAUTH_NETWORK_IPSEC:
801 		switch (req) {
802 		case KAUTH_REQ_NETWORK_IPSEC_BYPASS:
803 			if (isroot)
804 				result = KAUTH_RESULT_ALLOW;
805 
806 			break;
807 
808 		default:
809 			break;
810 		}
811 
812 		break;
813 
814 	default:
815 		break;
816 	}
817 
818 	return (result);
819 }
820 
821 /*
822  * kauth(9) listener
823  *
824  * Security model: Traditional NetBSD
825  * Scope: Machdep
826  * Responsibility: Superuser access
827  */
828 int
secmodel_suser_machdep_cb(kauth_cred_t cred,kauth_action_t action,void * cookie,void * arg0,void * arg1,void * arg2,void * arg3)829 secmodel_suser_machdep_cb(kauth_cred_t cred, kauth_action_t action,
830     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
831 {
832 	bool isroot;
833 	int result;
834 
835 	isroot = suser_isroot(cred);
836 	result = KAUTH_RESULT_DEFER;
837 
838 	switch (action) {
839 	case KAUTH_MACHDEP_CPU_UCODE_APPLY:
840 	case KAUTH_MACHDEP_IOPERM_GET:
841 	case KAUTH_MACHDEP_LDT_GET:
842 	case KAUTH_MACHDEP_LDT_SET:
843 	case KAUTH_MACHDEP_MTRR_GET:
844 	case KAUTH_MACHDEP_CACHEFLUSH:
845 	case KAUTH_MACHDEP_IOPERM_SET:
846 	case KAUTH_MACHDEP_IOPL:
847 	case KAUTH_MACHDEP_MTRR_SET:
848 	case KAUTH_MACHDEP_NVRAM:
849 	case KAUTH_MACHDEP_UNMANAGEDMEM:
850 	case KAUTH_MACHDEP_PXG:
851 		if (isroot)
852 			result = KAUTH_RESULT_ALLOW;
853 		break;
854 
855 	case KAUTH_MACHDEP_SVS_DISABLE:
856 		/* Deprecated. */
857 		if (isroot)
858 			result = KAUTH_RESULT_ALLOW;
859 		break;
860 
861 	default:
862 		break;
863 	}
864 
865 	return (result);
866 }
867 
868 /*
869  * kauth(9) listener
870  *
871  * Security model: Traditional NetBSD
872  * Scope: Device
873  * Responsibility: Superuser access
874  */
875 int
secmodel_suser_device_cb(kauth_cred_t cred,kauth_action_t action,void * cookie,void * arg0,void * arg1,void * arg2,void * arg3)876 secmodel_suser_device_cb(kauth_cred_t cred, kauth_action_t action,
877     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
878 {
879 	bool isroot;
880 	int result;
881 
882 	isroot = suser_isroot(cred);
883 	result = KAUTH_RESULT_DEFER;
884 
885 	switch (action) {
886 	case KAUTH_DEVICE_BLUETOOTH_SETPRIV:
887 	case KAUTH_DEVICE_BLUETOOTH_SEND:
888 	case KAUTH_DEVICE_BLUETOOTH_RECV:
889 	case KAUTH_DEVICE_TTY_OPEN:
890 	case KAUTH_DEVICE_TTY_PRIVSET:
891 	case KAUTH_DEVICE_TTY_STI:
892 	case KAUTH_DEVICE_TTY_VIRTUAL:
893 	case KAUTH_DEVICE_RND_ADDDATA:
894 	case KAUTH_DEVICE_RND_ADDDATA_ESTIMATE:
895 	case KAUTH_DEVICE_RND_GETPRIV:
896 	case KAUTH_DEVICE_RND_SETPRIV:
897 	case KAUTH_DEVICE_WSCONS_KEYBOARD_BELL:
898 	case KAUTH_DEVICE_WSCONS_KEYBOARD_KEYREPEAT:
899 	case KAUTH_DEVICE_NVMM_CTL:
900 		if (isroot)
901 			result = KAUTH_RESULT_ALLOW;
902 		break;
903 
904 	case KAUTH_DEVICE_BLUETOOTH_BCSP:
905 	case KAUTH_DEVICE_BLUETOOTH_BTUART: {
906 		enum kauth_device_req req;
907 
908 		req = (enum kauth_device_req)(uintptr_t)arg0;
909 		switch (req) {
910 		case KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD:
911 		case KAUTH_REQ_DEVICE_BLUETOOTH_BTUART_ADD:
912 			if (isroot)
913 				result = KAUTH_RESULT_ALLOW;
914 			break;
915 
916 		default:
917 			break;
918 		}
919 
920 		break;
921 		}
922 
923 	case KAUTH_DEVICE_GPIO_PINSET:
924 		/*
925 		 * root can access gpio pins, secmodel_securelevel can veto
926 		 * this decision.
927 		 */
928 		if (isroot)
929 			result = KAUTH_RESULT_ALLOW;
930 		break;
931 
932 	default:
933 		break;
934 	}
935 
936 	return (result);
937 }
938 
939 int
secmodel_suser_vnode_cb(kauth_cred_t cred,kauth_action_t action,void * cookie,void * arg0,void * arg1,void * arg2,void * arg3)940 secmodel_suser_vnode_cb(kauth_cred_t cred, kauth_action_t action,
941     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
942 {
943 	bool isroot;
944 	int result;
945 
946 	isroot = suser_isroot(cred);
947 	result = KAUTH_RESULT_DEFER;
948 
949 	if (isroot) {
950 		/* Superuser can execute only if the file's executable. */
951 		if ((action & KAUTH_VNODE_EXECUTE) == 0 ||
952 		    (action & KAUTH_VNODE_IS_EXEC))
953 			result = KAUTH_RESULT_ALLOW;
954 	}
955 
956 	return (result);
957 }
958 
959