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