secmodel_suser.c revision 1.11 1 /* $NetBSD: secmodel_suser.c,v 1.11 2009/10/02 23:18:12 elad Exp $ */
2 /*-
3 * Copyright (c) 2006 Elad Efrat <elad (at) 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.11 2009/10/02 23:18:12 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/tty.h>
52 #include <net/route.h>
53 #include <sys/vnode.h>
54 #include <sys/proc.h>
55 #include <sys/uidinfo.h>
56 #include <sys/module.h>
57
58 #include <miscfs/procfs/procfs.h>
59
60 #include <secmodel/suser/suser.h>
61
62 MODULE(MODULE_CLASS_SECMODEL, suser, NULL);
63
64 static int secmodel_bsd44_curtain;
65 /* static */ int dovfsusermount;
66
67 static kauth_listener_t l_generic, l_system, l_process, l_network, l_machdep,
68 l_device, l_vnode;
69
70 static struct sysctllog *suser_sysctl_log;
71
72 void
73 sysctl_security_suser_setup(struct sysctllog **clog)
74 {
75 const struct sysctlnode *rnode;
76
77 sysctl_createv(clog, 0, NULL, &rnode,
78 CTLFLAG_PERMANENT,
79 CTLTYPE_NODE, "security", NULL,
80 NULL, 0, NULL, 0,
81 CTL_SECURITY, CTL_EOL);
82
83 sysctl_createv(clog, 0, &rnode, &rnode,
84 CTLFLAG_PERMANENT,
85 CTLTYPE_NODE, "models", NULL,
86 NULL, 0, NULL, 0,
87 CTL_CREATE, CTL_EOL);
88
89 sysctl_createv(clog, 0, &rnode, &rnode,
90 CTLFLAG_PERMANENT,
91 CTLTYPE_NODE, "suser", NULL,
92 NULL, 0, NULL, 0,
93 CTL_CREATE, CTL_EOL);
94
95 sysctl_createv(clog, 0, &rnode, NULL,
96 CTLFLAG_PERMANENT,
97 CTLTYPE_STRING, "name", NULL,
98 NULL, 0, __UNCONST("Traditional NetBSD: Superuser"), 0,
99 CTL_CREATE, CTL_EOL);
100
101 sysctl_createv(clog, 0, &rnode, NULL,
102 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
103 CTLTYPE_INT, "curtain",
104 SYSCTL_DESCR("Curtain information about objects to "\
105 "users not owning them."),
106 NULL, 0, &secmodel_bsd44_curtain, 0,
107 CTL_CREATE, CTL_EOL);
108
109 sysctl_createv(clog, 0, &rnode, NULL,
110 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
111 CTLTYPE_INT, "usermount",
112 SYSCTL_DESCR("Whether unprivileged users may mount "
113 "filesystems"),
114 NULL, 0, &dovfsusermount, 0,
115 CTL_CREATE, CTL_EOL);
116
117 /* Compatibility: security.curtain */
118 sysctl_createv(clog, 0, NULL, &rnode,
119 CTLFLAG_PERMANENT,
120 CTLTYPE_NODE, "security", NULL,
121 NULL, 0, NULL, 0,
122 CTL_SECURITY, CTL_EOL);
123
124 sysctl_createv(clog, 0, &rnode, NULL,
125 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
126 CTLTYPE_INT, "curtain",
127 SYSCTL_DESCR("Curtain information about objects to "\
128 "users not owning them."),
129 NULL, 0, &secmodel_bsd44_curtain, 0,
130 CTL_CREATE, CTL_EOL);
131
132 /* Compatibility: vfs.generic.usermount */
133 sysctl_createv(clog, 0, NULL, NULL,
134 CTLFLAG_PERMANENT,
135 CTLTYPE_NODE, "vfs", NULL,
136 NULL, 0, NULL, 0,
137 CTL_VFS, CTL_EOL);
138
139 sysctl_createv(clog, 0, NULL, NULL,
140 CTLFLAG_PERMANENT,
141 CTLTYPE_NODE, "generic",
142 SYSCTL_DESCR("Non-specific vfs related information"),
143 NULL, 0, NULL, 0,
144 CTL_VFS, VFS_GENERIC, CTL_EOL);
145
146 sysctl_createv(clog, 0, NULL, NULL,
147 CTLFLAG_PERMANENT|CTLFLAG_READWRITE,
148 CTLTYPE_INT, "usermount",
149 SYSCTL_DESCR("Whether unprivileged users may mount "
150 "filesystems"),
151 NULL, 0, &dovfsusermount, 0,
152 CTL_VFS, VFS_GENERIC, VFS_USERMOUNT, CTL_EOL);
153 }
154
155 void
156 secmodel_suser_init(void)
157 {
158 secmodel_bsd44_curtain = 0;
159 dovfsusermount = 0;
160 }
161
162 void
163 secmodel_suser_start(void)
164 {
165 l_generic = kauth_listen_scope(KAUTH_SCOPE_GENERIC,
166 secmodel_suser_generic_cb, NULL);
167 l_system = kauth_listen_scope(KAUTH_SCOPE_SYSTEM,
168 secmodel_suser_system_cb, NULL);
169 l_process = kauth_listen_scope(KAUTH_SCOPE_PROCESS,
170 secmodel_suser_process_cb, NULL);
171 l_network = kauth_listen_scope(KAUTH_SCOPE_NETWORK,
172 secmodel_suser_network_cb, NULL);
173 l_machdep = kauth_listen_scope(KAUTH_SCOPE_MACHDEP,
174 secmodel_suser_machdep_cb, NULL);
175 l_device = kauth_listen_scope(KAUTH_SCOPE_DEVICE,
176 secmodel_suser_device_cb, NULL);
177 l_vnode = kauth_listen_scope(KAUTH_SCOPE_VNODE,
178 secmodel_suser_vnode_cb, NULL);
179 }
180
181 void
182 secmodel_suser_stop(void)
183 {
184 kauth_unlisten_scope(l_generic);
185 kauth_unlisten_scope(l_system);
186 kauth_unlisten_scope(l_process);
187 kauth_unlisten_scope(l_network);
188 kauth_unlisten_scope(l_machdep);
189 kauth_unlisten_scope(l_device);
190 kauth_unlisten_scope(l_vnode);
191 }
192
193 static int
194 suser_modcmd(modcmd_t cmd, void *arg)
195 {
196 int error = 0;
197
198 switch (cmd) {
199 case MODULE_CMD_INIT:
200 secmodel_suser_init();
201 secmodel_suser_start();
202 sysctl_security_suser_setup(&suser_sysctl_log);
203 break;
204
205 case MODULE_CMD_FINI:
206 sysctl_teardown(&suser_sysctl_log);
207 secmodel_suser_stop();
208 break;
209
210 case MODULE_CMD_AUTOUNLOAD:
211 error = EPERM;
212 break;
213
214 default:
215 error = ENOTTY;
216 break;
217 }
218
219 return (error);
220 }
221
222 /*
223 * kauth(9) listener
224 *
225 * Security model: Traditional NetBSD
226 * Scope: Generic
227 * Responsibility: Superuser access
228 */
229 int
230 secmodel_suser_generic_cb(kauth_cred_t cred, kauth_action_t action,
231 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
232 {
233 bool isroot;
234 int result;
235
236 isroot = (kauth_cred_geteuid(cred) == 0);
237 result = KAUTH_RESULT_DEFER;
238
239 switch (action) {
240 case KAUTH_GENERIC_ISSUSER:
241 if (isroot)
242 result = KAUTH_RESULT_ALLOW;
243 break;
244
245 case KAUTH_GENERIC_CANSEE:
246 if (!secmodel_bsd44_curtain)
247 result = KAUTH_RESULT_ALLOW;
248 else if (isroot || kauth_cred_uidmatch(cred, arg0))
249 result = KAUTH_RESULT_ALLOW;
250
251 break;
252
253 default:
254 break;
255 }
256
257 return (result);
258 }
259
260 /*
261 * kauth(9) listener
262 *
263 * Security model: Traditional NetBSD
264 * Scope: System
265 * Responsibility: Superuser access
266 */
267 int
268 secmodel_suser_system_cb(kauth_cred_t cred, kauth_action_t action,
269 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
270 {
271 bool isroot;
272 int result;
273 enum kauth_system_req req;
274
275 isroot = (kauth_cred_geteuid(cred) == 0);
276 result = KAUTH_RESULT_DEFER;
277 req = (enum kauth_system_req)arg0;
278
279 switch (action) {
280 case KAUTH_SYSTEM_CPU:
281 switch (req) {
282 case KAUTH_REQ_SYSTEM_CPU_SETSTATE:
283 if (isroot)
284 result = KAUTH_RESULT_ALLOW;
285
286 break;
287
288 default:
289 break;
290 }
291
292 break;
293
294 case KAUTH_SYSTEM_FS_QUOTA:
295 switch (req) {
296 case KAUTH_REQ_SYSTEM_FS_QUOTA_GET:
297 case KAUTH_REQ_SYSTEM_FS_QUOTA_ONOFF:
298 case KAUTH_REQ_SYSTEM_FS_QUOTA_MANAGE:
299 case KAUTH_REQ_SYSTEM_FS_QUOTA_NOLIMIT:
300 if (isroot)
301 result = KAUTH_RESULT_ALLOW;
302 break;
303
304 default:
305 break;
306 }
307
308 break;
309
310 case KAUTH_SYSTEM_FS_RESERVEDSPACE:
311 if (isroot)
312 result = KAUTH_RESULT_ALLOW;
313 break;
314
315 case KAUTH_SYSTEM_MOUNT:
316 switch (req) {
317 case KAUTH_REQ_SYSTEM_MOUNT_GET:
318 result = KAUTH_RESULT_ALLOW;
319 break;
320
321 case KAUTH_REQ_SYSTEM_MOUNT_NEW:
322 if (isroot)
323 result = KAUTH_RESULT_ALLOW;
324 else if (dovfsusermount) {
325 struct vnode *vp = arg1;
326 u_long flags = (u_long)arg2;
327
328 if (!(flags & MNT_NODEV) ||
329 !(flags & MNT_NOSUID))
330 break;
331
332 if ((vp->v_mount->mnt_flag & MNT_NOEXEC) &&
333 !(flags & MNT_NOEXEC))
334 break;
335
336 result = KAUTH_RESULT_ALLOW;
337 }
338
339 break;
340
341 case KAUTH_REQ_SYSTEM_MOUNT_UNMOUNT:
342 if (isroot)
343 result = KAUTH_RESULT_ALLOW;
344 else {
345 struct mount *mp = arg1;
346
347 if (mp->mnt_stat.f_owner ==
348 kauth_cred_geteuid(cred))
349 result = KAUTH_RESULT_ALLOW;
350 }
351
352 break;
353
354 case KAUTH_REQ_SYSTEM_MOUNT_UPDATE:
355 if (isroot)
356 result = KAUTH_RESULT_ALLOW;
357 else if (dovfsusermount) {
358 struct mount *mp = arg1;
359 u_long flags = (u_long)arg2;
360
361 /* No exporting for non-root. */
362 if (flags & MNT_EXPORTED)
363 break;
364
365 if (!(flags & MNT_NODEV) ||
366 !(flags & MNT_NOSUID))
367 break;
368
369 /*
370 * Only super-user, or user that did the mount,
371 * can update.
372 */
373 if (mp->mnt_stat.f_owner !=
374 kauth_cred_geteuid(cred))
375 break;
376
377 /* Retain 'noexec'. */
378 if ((mp->mnt_flag & MNT_NOEXEC) &&
379 !(flags & MNT_NOEXEC))
380 break;
381
382 result = KAUTH_RESULT_ALLOW;
383 }
384
385 break;
386
387 default:
388 break;
389 }
390
391 break;
392
393 case KAUTH_SYSTEM_PSET:
394 switch (req) {
395 case KAUTH_REQ_SYSTEM_PSET_ASSIGN:
396 case KAUTH_REQ_SYSTEM_PSET_BIND:
397 case KAUTH_REQ_SYSTEM_PSET_CREATE:
398 case KAUTH_REQ_SYSTEM_PSET_DESTROY:
399 if (isroot)
400 result = KAUTH_RESULT_ALLOW;
401
402 break;
403
404 default:
405 break;
406 }
407
408 break;
409
410 case KAUTH_SYSTEM_TIME:
411 switch (req) {
412 case KAUTH_REQ_SYSTEM_TIME_ADJTIME:
413 case KAUTH_REQ_SYSTEM_TIME_NTPADJTIME:
414 case KAUTH_REQ_SYSTEM_TIME_TIMECOUNTERS:
415 if (isroot)
416 result = KAUTH_RESULT_ALLOW;
417 break;
418
419 case KAUTH_REQ_SYSTEM_TIME_SYSTEM: {
420 bool device_context = (bool)arg3;
421
422 if (device_context || isroot)
423 result = KAUTH_RESULT_ALLOW;
424
425 break;
426 }
427
428 case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET:
429 if (isroot)
430 result = KAUTH_RESULT_ALLOW;
431 break;
432
433 default:
434 break;
435 }
436 break;
437
438 case KAUTH_SYSTEM_SYSCTL:
439 switch (req) {
440 case KAUTH_REQ_SYSTEM_SYSCTL_ADD:
441 case KAUTH_REQ_SYSTEM_SYSCTL_DELETE:
442 case KAUTH_REQ_SYSTEM_SYSCTL_DESC:
443 case KAUTH_REQ_SYSTEM_SYSCTL_MODIFY:
444 case KAUTH_REQ_SYSTEM_SYSCTL_PRVT:
445 if (isroot)
446 result = KAUTH_RESULT_ALLOW;
447 break;
448
449 default:
450 break;
451 }
452
453 break;
454
455 case KAUTH_SYSTEM_SWAPCTL:
456 case KAUTH_SYSTEM_ACCOUNTING:
457 case KAUTH_SYSTEM_REBOOT:
458 case KAUTH_SYSTEM_CHROOT:
459 case KAUTH_SYSTEM_FILEHANDLE:
460 case KAUTH_SYSTEM_MKNOD:
461 if (isroot)
462 result = KAUTH_RESULT_ALLOW;
463 break;
464
465 case KAUTH_SYSTEM_CHSYSFLAGS:
466 /*
467 * Needs to be checked in conjunction with the immutable and
468 * append-only flags (usually). Should be handled differently.
469 * Infects ufs, ext2fs, tmpfs, and rump.
470 */
471 if (isroot)
472 result = KAUTH_RESULT_ALLOW;
473
474 break;
475
476 case KAUTH_SYSTEM_SETIDCORE:
477 if (isroot)
478 result = KAUTH_RESULT_ALLOW;
479
480 break;
481
482 case KAUTH_SYSTEM_MODULE:
483 if (isroot)
484 result = KAUTH_RESULT_ALLOW;
485 if ((uintptr_t)arg2 != 0) /* autoload */
486 result = KAUTH_RESULT_ALLOW;
487 break;
488
489 default:
490 break;
491 }
492
493 return (result);
494 }
495
496 /*
497 * kauth(9) listener
498 *
499 * Security model: Traditional NetBSD
500 * Scope: Process
501 * Responsibility: Superuser access
502 */
503 int
504 secmodel_suser_process_cb(kauth_cred_t cred, kauth_action_t action,
505 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
506 {
507 struct proc *p;
508 bool isroot;
509 int result;
510
511 isroot = (kauth_cred_geteuid(cred) == 0);
512 result = KAUTH_RESULT_DEFER;
513 p = arg0;
514
515 switch (action) {
516 case KAUTH_PROCESS_SIGNAL: {
517 int signum;
518
519 signum = (int)(unsigned long)arg1;
520
521 if (isroot || kauth_cred_uidmatch(cred, p->p_cred) ||
522 (signum == SIGCONT && (curproc->p_session == p->p_session)))
523 result = KAUTH_RESULT_ALLOW;
524 break;
525 }
526
527 case KAUTH_PROCESS_CANSEE: {
528 unsigned long req;
529
530 req = (unsigned long)arg1;
531
532 switch (req) {
533 case KAUTH_REQ_PROCESS_CANSEE_ARGS:
534 case KAUTH_REQ_PROCESS_CANSEE_ENTRY:
535 case KAUTH_REQ_PROCESS_CANSEE_OPENFILES:
536 if (!secmodel_bsd44_curtain)
537 result = KAUTH_RESULT_ALLOW;
538 else if (isroot || kauth_cred_uidmatch(cred, p->p_cred))
539 result = KAUTH_RESULT_ALLOW;
540 break;
541
542 case KAUTH_REQ_PROCESS_CANSEE_ENV:
543 if (!isroot &&
544 (kauth_cred_getuid(cred) !=
545 kauth_cred_getuid(p->p_cred) ||
546 kauth_cred_getuid(cred) !=
547 kauth_cred_getsvuid(p->p_cred)))
548 break;
549 else
550 result = KAUTH_RESULT_ALLOW;
551
552 break;
553
554 default:
555 break;
556 }
557
558 break;
559 }
560
561 case KAUTH_PROCESS_KTRACE:
562 if (isroot)
563 result = KAUTH_RESULT_ALLOW;
564
565 break;
566
567 case KAUTH_PROCESS_PROCFS:
568 if (isroot)
569 result = KAUTH_RESULT_ALLOW;
570
571 break;
572
573 case KAUTH_PROCESS_PTRACE:
574 if (isroot)
575 result = KAUTH_RESULT_ALLOW;
576
577 break;
578
579 case KAUTH_PROCESS_CORENAME:
580 if (isroot || proc_uidmatch(cred, p->p_cred) == 0)
581 result = KAUTH_RESULT_ALLOW;
582
583 break;
584
585 case KAUTH_PROCESS_FORK: {
586 int lnprocs = (int)(unsigned long)arg2;
587
588 /*
589 * Don't allow a nonprivileged user to use the last few
590 * processes. The variable lnprocs is the current number of
591 * processes, maxproc is the limit.
592 */
593 if (__predict_false((lnprocs >= maxproc - 5) && !isroot))
594 break;
595 else
596 result = KAUTH_RESULT_ALLOW;
597
598 break;
599 }
600
601 case KAUTH_PROCESS_KEVENT_FILTER:
602 if ((kauth_cred_getuid(p->p_cred) !=
603 kauth_cred_getuid(cred) ||
604 ISSET(p->p_flag, PK_SUGID)) &&
605 !isroot)
606 break;
607 else
608 result = KAUTH_RESULT_ALLOW;
609
610 break;
611
612 case KAUTH_PROCESS_NICE:
613 if (isroot)
614 result = KAUTH_RESULT_ALLOW;
615
616 break;
617
618 case KAUTH_PROCESS_RLIMIT: {
619 enum kauth_process_req req;
620
621 req = (enum kauth_process_req)(unsigned long)arg1;
622
623 switch (req) {
624 case KAUTH_REQ_PROCESS_RLIMIT_SET:
625 case KAUTH_REQ_PROCESS_RLIMIT_GET:
626 if (isroot)
627 result = KAUTH_RESULT_ALLOW;
628
629 break;
630
631 default:
632 break;
633 }
634
635 break;
636 }
637
638 case KAUTH_PROCESS_SCHEDULER_GETPARAM:
639 if (isroot || kauth_cred_uidmatch(cred, p->p_cred))
640 result = KAUTH_RESULT_ALLOW;
641
642 break;
643
644 case KAUTH_PROCESS_SCHEDULER_SETPARAM:
645 if (isroot)
646 result = KAUTH_RESULT_ALLOW;
647 else if (kauth_cred_uidmatch(cred, p->p_cred)) {
648 struct lwp *l;
649 int policy;
650 pri_t priority;
651
652 l = arg1;
653 policy = (int)(unsigned long)arg2;
654 priority = (pri_t)(unsigned long)arg3;
655
656 if ((policy == l->l_class ||
657 (policy != SCHED_FIFO && policy != SCHED_RR)) &&
658 priority <= l->l_priority)
659 result = KAUTH_RESULT_ALLOW;
660 }
661
662 break;
663
664 case KAUTH_PROCESS_SCHEDULER_GETAFFINITY:
665 result = KAUTH_RESULT_ALLOW;
666
667 break;
668
669 case KAUTH_PROCESS_SCHEDULER_SETAFFINITY:
670 if (isroot)
671 result = KAUTH_RESULT_ALLOW;
672
673 break;
674
675 case KAUTH_PROCESS_SETID:
676 if (isroot)
677 result = KAUTH_RESULT_ALLOW;
678 break;
679
680 case KAUTH_PROCESS_STOPFLAG:
681 if (isroot || proc_uidmatch(cred, p->p_cred) == 0) {
682 result = KAUTH_RESULT_ALLOW;
683 break;
684 }
685 break;
686
687 default:
688 break;
689 }
690
691 return (result);
692 }
693
694 /*
695 * kauth(9) listener
696 *
697 * Security model: Traditional NetBSD
698 * Scope: Network
699 * Responsibility: Superuser access
700 */
701 int
702 secmodel_suser_network_cb(kauth_cred_t cred, kauth_action_t action,
703 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
704 {
705 bool isroot;
706 int result;
707 enum kauth_network_req req;
708
709 isroot = (kauth_cred_geteuid(cred) == 0);
710 result = KAUTH_RESULT_DEFER;
711 req = (enum kauth_network_req)arg0;
712
713 switch (action) {
714 case KAUTH_NETWORK_ALTQ:
715 switch (req) {
716 case KAUTH_REQ_NETWORK_ALTQ_AFMAP:
717 case KAUTH_REQ_NETWORK_ALTQ_BLUE:
718 case KAUTH_REQ_NETWORK_ALTQ_CBQ:
719 case KAUTH_REQ_NETWORK_ALTQ_CDNR:
720 case KAUTH_REQ_NETWORK_ALTQ_CONF:
721 case KAUTH_REQ_NETWORK_ALTQ_FIFOQ:
722 case KAUTH_REQ_NETWORK_ALTQ_HFSC:
723 case KAUTH_REQ_NETWORK_ALTQ_JOBS:
724 case KAUTH_REQ_NETWORK_ALTQ_PRIQ:
725 case KAUTH_REQ_NETWORK_ALTQ_RED:
726 case KAUTH_REQ_NETWORK_ALTQ_RIO:
727 case KAUTH_REQ_NETWORK_ALTQ_WFQ:
728 if (isroot)
729 result = KAUTH_RESULT_ALLOW;
730 break;
731
732 default:
733 break;
734 }
735
736 break;
737
738 case KAUTH_NETWORK_BIND:
739 switch (req) {
740 case KAUTH_REQ_NETWORK_BIND_PORT:
741 result = KAUTH_RESULT_ALLOW;
742 break;
743
744 case KAUTH_REQ_NETWORK_BIND_PRIVPORT:
745 if (isroot)
746 result = KAUTH_RESULT_ALLOW;
747 break;
748
749 default:
750 break;
751 }
752 break;
753
754 case KAUTH_NETWORK_FIREWALL:
755 switch (req) {
756 case KAUTH_REQ_NETWORK_FIREWALL_FW:
757 case KAUTH_REQ_NETWORK_FIREWALL_NAT:
758 /*
759 * Decisions are root-agnostic.
760 *
761 * Both requests are issued from the context of a
762 * device with permission bits acting as access
763 * control.
764 */
765 result = KAUTH_RESULT_ALLOW;
766 break;
767
768 default:
769 break;
770 }
771 break;
772
773 case KAUTH_NETWORK_FORWSRCRT:
774 if (isroot)
775 result = KAUTH_RESULT_ALLOW;
776
777 break;
778
779 case KAUTH_NETWORK_INTERFACE:
780 switch (req) {
781 case KAUTH_REQ_NETWORK_INTERFACE_GET:
782 case KAUTH_REQ_NETWORK_INTERFACE_SET:
783 result = KAUTH_RESULT_ALLOW;
784 break;
785
786 case KAUTH_REQ_NETWORK_INTERFACE_GETPRIV:
787 case KAUTH_REQ_NETWORK_INTERFACE_SETPRIV:
788 if (isroot)
789 result = KAUTH_RESULT_ALLOW;
790 break;
791
792 default:
793 break;
794 }
795 break;
796
797 case KAUTH_NETWORK_INTERFACE_PPP:
798 switch (req) {
799 case KAUTH_REQ_NETWORK_INTERFACE_PPP_ADD:
800 if (isroot)
801 result = KAUTH_RESULT_ALLOW;
802 break;
803
804 default:
805 break;
806 }
807
808 break;
809
810 case KAUTH_NETWORK_INTERFACE_SLIP:
811 switch (req) {
812 case KAUTH_REQ_NETWORK_INTERFACE_SLIP_ADD:
813 if (isroot)
814 result = KAUTH_RESULT_ALLOW;
815 break;
816
817 default:
818 break;
819 }
820
821 break;
822
823 case KAUTH_NETWORK_INTERFACE_STRIP:
824 switch (req) {
825 case KAUTH_REQ_NETWORK_INTERFACE_STRIP_ADD:
826 if (isroot)
827 result = KAUTH_RESULT_ALLOW;
828 break;
829
830 default:
831 break;
832 }
833
834 break;
835
836 case KAUTH_NETWORK_INTERFACE_TUN:
837 switch (req) {
838 case KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD:
839 if (isroot)
840 result = KAUTH_RESULT_ALLOW;
841 break;
842
843 default:
844 break;
845 }
846
847 break;
848
849 case KAUTH_NETWORK_NFS:
850 switch (req) {
851 case KAUTH_REQ_NETWORK_NFS_EXPORT:
852 case KAUTH_REQ_NETWORK_NFS_SVC:
853 if (isroot)
854 result = KAUTH_RESULT_ALLOW;
855
856 break;
857
858 default:
859 break;
860 }
861 break;
862
863 case KAUTH_NETWORK_ROUTE:
864 if (isroot)
865 result = KAUTH_RESULT_ALLOW;
866
867 break;
868
869 case KAUTH_NETWORK_SOCKET:
870 switch (req) {
871 case KAUTH_REQ_NETWORK_SOCKET_DROP:
872 /*
873 * The superuser can drop any connection. Normal users
874 * can only drop their own connections.
875 */
876 if (isroot)
877 result = KAUTH_RESULT_ALLOW;
878 else {
879 struct socket *so = (struct socket *)arg1;
880 uid_t sockuid = so->so_uidinfo->ui_uid;
881
882 if (sockuid == kauth_cred_getuid(cred) ||
883 sockuid == kauth_cred_geteuid(cred))
884 result = KAUTH_RESULT_ALLOW;
885 }
886
887
888 break;
889
890 case KAUTH_REQ_NETWORK_SOCKET_OPEN:
891 if ((u_long)arg1 == PF_ROUTE || (u_long)arg1 == PF_BLUETOOTH)
892 result = KAUTH_RESULT_ALLOW;
893 else if ((u_long)arg2 == SOCK_RAW) {
894 if (isroot)
895 result = KAUTH_RESULT_ALLOW;
896 } else
897 result = KAUTH_RESULT_ALLOW;
898 break;
899
900 case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK:
901 if (isroot)
902 result = KAUTH_RESULT_ALLOW;
903 break;
904
905 case KAUTH_REQ_NETWORK_SOCKET_CANSEE:
906 if (secmodel_bsd44_curtain) {
907 uid_t so_uid;
908
909 so_uid =
910 ((struct socket *)arg1)->so_uidinfo->ui_uid;
911 if (isroot ||
912 kauth_cred_geteuid(cred) == so_uid)
913 result = KAUTH_RESULT_ALLOW;
914 } else
915 result = KAUTH_RESULT_ALLOW;
916 break;
917
918 case KAUTH_REQ_NETWORK_SOCKET_SETPRIV:
919 if (isroot)
920 result = KAUTH_RESULT_ALLOW;
921 break;
922
923 default:
924 break;
925 }
926
927 break;
928
929
930 default:
931 break;
932 }
933
934 return (result);
935 }
936
937 /*
938 * kauth(9) listener
939 *
940 * Security model: Traditional NetBSD
941 * Scope: Machdep
942 * Responsibility: Superuser access
943 */
944 int
945 secmodel_suser_machdep_cb(kauth_cred_t cred, kauth_action_t action,
946 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
947 {
948 bool isroot;
949 int result;
950
951 isroot = (kauth_cred_geteuid(cred) == 0);
952 result = KAUTH_RESULT_DEFER;
953
954 switch (action) {
955 case KAUTH_MACHDEP_IOPERM_GET:
956 case KAUTH_MACHDEP_LDT_GET:
957 case KAUTH_MACHDEP_LDT_SET:
958 case KAUTH_MACHDEP_MTRR_GET:
959 result = KAUTH_RESULT_ALLOW;
960 break;
961
962 case KAUTH_MACHDEP_CACHEFLUSH:
963 case KAUTH_MACHDEP_IOPERM_SET:
964 case KAUTH_MACHDEP_IOPL:
965 case KAUTH_MACHDEP_MTRR_SET:
966 case KAUTH_MACHDEP_NVRAM:
967 case KAUTH_MACHDEP_UNMANAGEDMEM:
968 if (isroot)
969 result = KAUTH_RESULT_ALLOW;
970 break;
971
972 default:
973 break;
974 }
975
976 return (result);
977 }
978
979 /*
980 * kauth(9) listener
981 *
982 * Security model: Traditional NetBSD
983 * Scope: Device
984 * Responsibility: Superuser access
985 */
986 int
987 secmodel_suser_device_cb(kauth_cred_t cred, kauth_action_t action,
988 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
989 {
990 struct tty *tty;
991 bool isroot;
992 int result;
993
994 isroot = (kauth_cred_geteuid(cred) == 0);
995 result = KAUTH_RESULT_DEFER;
996
997 switch (action) {
998 case KAUTH_DEVICE_BLUETOOTH_SETPRIV:
999 case KAUTH_DEVICE_BLUETOOTH_SEND:
1000 case KAUTH_DEVICE_BLUETOOTH_RECV:
1001 if (isroot)
1002 result = KAUTH_RESULT_ALLOW;
1003 break;
1004
1005 case KAUTH_DEVICE_BLUETOOTH_BCSP:
1006 case KAUTH_DEVICE_BLUETOOTH_BTUART: {
1007 enum kauth_device_req req;
1008
1009 req = (enum kauth_device_req)arg0;
1010 switch (req) {
1011 case KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD:
1012 case KAUTH_REQ_DEVICE_BLUETOOTH_BTUART_ADD:
1013 if (isroot)
1014 result = KAUTH_RESULT_ALLOW;
1015 break;
1016
1017 default:
1018 break;
1019 }
1020
1021 break;
1022 }
1023
1024 case KAUTH_DEVICE_RAWIO_SPEC:
1025 case KAUTH_DEVICE_RAWIO_PASSTHRU:
1026 /*
1027 * Decision is root-agnostic.
1028 *
1029 * Both requests can be issued on devices subject to their
1030 * permission bits.
1031 */
1032 result = KAUTH_RESULT_ALLOW;
1033 break;
1034
1035 case KAUTH_DEVICE_TTY_OPEN:
1036 tty = arg0;
1037
1038 if (!(tty->t_state & TS_ISOPEN))
1039 result = KAUTH_RESULT_ALLOW;
1040 else if (tty->t_state & TS_XCLUDE) {
1041 if (isroot)
1042 result = KAUTH_RESULT_ALLOW;
1043 } else
1044 result = KAUTH_RESULT_ALLOW;
1045
1046 break;
1047
1048 case KAUTH_DEVICE_TTY_PRIVSET:
1049 if (isroot)
1050 result = KAUTH_RESULT_ALLOW;
1051
1052 break;
1053
1054 case KAUTH_DEVICE_TTY_STI:
1055 if (isroot)
1056 result = KAUTH_RESULT_ALLOW;
1057
1058 break;
1059
1060 case KAUTH_DEVICE_RND_ADDDATA:
1061 case KAUTH_DEVICE_RND_GETPRIV:
1062 case KAUTH_DEVICE_RND_SETPRIV:
1063 if (isroot)
1064 result = KAUTH_RESULT_ALLOW;
1065 break;
1066
1067 case KAUTH_DEVICE_GPIO_PINSET:
1068 /*
1069 * root can access gpio pins, secmodel_securlevel can veto
1070 * this decision.
1071 */
1072 if (isroot)
1073 result = KAUTH_RESULT_ALLOW;
1074 break;
1075
1076 default:
1077 break;
1078 }
1079
1080 return (result);
1081 }
1082
1083 int
1084 secmodel_suser_vnode_cb(kauth_cred_t cred, kauth_action_t action,
1085 void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
1086 {
1087 bool isroot;
1088 int result;
1089
1090 isroot = (kauth_cred_geteuid(cred) == 0);
1091 result = KAUTH_RESULT_DEFER;
1092
1093 if (isroot)
1094 result = KAUTH_RESULT_ALLOW;
1095
1096 return (result);
1097 }
1098
1099