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