Home | History | Annotate | Line # | Download | only in suser
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