Home | History | Annotate | Line # | Download | only in suser
secmodel_suser.c revision 1.19
      1 /* $NetBSD: secmodel_suser.c,v 1.19 2009/10/03 01:41:39 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.19 2009/10/03 01:41:39 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_bsd44_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_bsd44_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_bsd44_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_bsd44_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_bsd44_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 			if (isroot)
    414 				result = KAUTH_RESULT_ALLOW;
    415 			break;
    416 
    417 		case KAUTH_REQ_SYSTEM_TIME_SYSTEM: {
    418 			bool device_context = (bool)arg3;
    419 
    420 			if (device_context || isroot)
    421 				result = KAUTH_RESULT_ALLOW;
    422 
    423 			break;
    424 		}
    425 
    426 		case KAUTH_REQ_SYSTEM_TIME_RTCOFFSET:
    427 			if (isroot)
    428 				result = KAUTH_RESULT_ALLOW;
    429 			break;
    430 
    431 		default:
    432 			break;
    433 		}
    434 		break;
    435 
    436 	case KAUTH_SYSTEM_SYSCTL:
    437 		switch (req) {
    438 		case KAUTH_REQ_SYSTEM_SYSCTL_ADD:
    439 		case KAUTH_REQ_SYSTEM_SYSCTL_DELETE:
    440 		case KAUTH_REQ_SYSTEM_SYSCTL_DESC:
    441 		case KAUTH_REQ_SYSTEM_SYSCTL_MODIFY:
    442 		case KAUTH_REQ_SYSTEM_SYSCTL_PRVT:
    443 			if (isroot)
    444 				result = KAUTH_RESULT_ALLOW;
    445 			break;
    446 
    447 		default:
    448 			break;
    449 		}
    450 
    451 		break;
    452 
    453 	case KAUTH_SYSTEM_SWAPCTL:
    454 	case KAUTH_SYSTEM_ACCOUNTING:
    455 	case KAUTH_SYSTEM_REBOOT:
    456 	case KAUTH_SYSTEM_CHROOT:
    457 	case KAUTH_SYSTEM_FILEHANDLE:
    458 	case KAUTH_SYSTEM_MKNOD:
    459 		if (isroot)
    460 			result = KAUTH_RESULT_ALLOW;
    461 		break;
    462 
    463 	case KAUTH_SYSTEM_CHSYSFLAGS:
    464 		/*
    465 		 * Needs to be checked in conjunction with the immutable and
    466 		 * append-only flags (usually). Should be handled differently.
    467 		 * Infects ufs, ext2fs, tmpfs, and rump.
    468 		 */
    469 		if (isroot)
    470 			result = KAUTH_RESULT_ALLOW;
    471 
    472 		break;
    473 
    474 	case KAUTH_SYSTEM_SETIDCORE:
    475 		if (isroot)
    476 			result = KAUTH_RESULT_ALLOW;
    477 
    478 		break;
    479 
    480 	case KAUTH_SYSTEM_MODULE:
    481 		if (isroot)
    482 			result = KAUTH_RESULT_ALLOW;
    483 
    484 		break;
    485 
    486 	default:
    487 		break;
    488 	}
    489 
    490 	return (result);
    491 }
    492 
    493 /*
    494  * kauth(9) listener
    495  *
    496  * Security model: Traditional NetBSD
    497  * Scope: Process
    498  * Responsibility: Superuser access
    499  */
    500 int
    501 secmodel_suser_process_cb(kauth_cred_t cred, kauth_action_t action,
    502     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    503 {
    504 	struct proc *p;
    505 	bool isroot;
    506 	int result;
    507 
    508 	isroot = (kauth_cred_geteuid(cred) == 0);
    509 	result = KAUTH_RESULT_DEFER;
    510 	p = arg0;
    511 
    512 	switch (action) {
    513 	case KAUTH_PROCESS_SIGNAL:
    514 		if (isroot)
    515 			result = KAUTH_RESULT_ALLOW;
    516 
    517 		break;
    518 
    519 	case KAUTH_PROCESS_CANSEE: {
    520 		unsigned long req;
    521 
    522 		req = (unsigned long)arg1;
    523 
    524 		switch (req) {
    525 		case KAUTH_REQ_PROCESS_CANSEE_ARGS:
    526 		case KAUTH_REQ_PROCESS_CANSEE_ENTRY:
    527 		case KAUTH_REQ_PROCESS_CANSEE_OPENFILES:
    528 			if (!secmodel_bsd44_curtain)
    529 				result = KAUTH_RESULT_ALLOW;
    530 			else if (isroot || kauth_cred_uidmatch(cred, p->p_cred))
    531 				result = KAUTH_RESULT_ALLOW;
    532 			break;
    533 
    534 		case KAUTH_REQ_PROCESS_CANSEE_ENV:
    535 			if (!isroot &&
    536 			    (kauth_cred_getuid(cred) !=
    537 			     kauth_cred_getuid(p->p_cred) ||
    538 			    kauth_cred_getuid(cred) !=
    539 			     kauth_cred_getsvuid(p->p_cred)))
    540 				break;
    541 			else
    542 				result = KAUTH_RESULT_ALLOW;
    543 
    544 			break;
    545 
    546 		default:
    547 			break;
    548 		}
    549 
    550 		break;
    551 		}
    552 
    553 	case KAUTH_PROCESS_KTRACE:
    554 		if (isroot)
    555 			result = KAUTH_RESULT_ALLOW;
    556 
    557 		break;
    558 
    559 	case KAUTH_PROCESS_PROCFS:
    560 		if (isroot)
    561 			result = KAUTH_RESULT_ALLOW;
    562 
    563 		break;
    564 
    565 	case KAUTH_PROCESS_PTRACE:
    566 		if (isroot)
    567 			result = KAUTH_RESULT_ALLOW;
    568 
    569 		break;
    570 
    571 	case KAUTH_PROCESS_CORENAME:
    572 		if (isroot || proc_uidmatch(cred, p->p_cred) == 0)
    573 			result = KAUTH_RESULT_ALLOW;
    574 
    575 		break;
    576 
    577 	case KAUTH_PROCESS_FORK: {
    578 		int lnprocs = (int)(unsigned long)arg2;
    579 
    580 		/*
    581 		 * Don't allow a nonprivileged user to use the last few
    582 		 * processes. The variable lnprocs is the current number of
    583 		 * processes, maxproc is the limit.
    584 		 */
    585 		if (__predict_false((lnprocs >= maxproc - 5) && !isroot))
    586 			break;
    587 		else
    588 			result = KAUTH_RESULT_ALLOW;
    589 
    590 		break;
    591 		}
    592 
    593 	case KAUTH_PROCESS_KEVENT_FILTER:
    594 		if (isroot)
    595 			result = KAUTH_RESULT_ALLOW;
    596 
    597 		break;
    598 
    599 	case KAUTH_PROCESS_NICE:
    600 		if (isroot)
    601 			result = KAUTH_RESULT_ALLOW;
    602 
    603 		break;
    604 
    605 	case KAUTH_PROCESS_RLIMIT: {
    606 		enum kauth_process_req req;
    607 
    608 		req = (enum kauth_process_req)(unsigned long)arg1;
    609 
    610 		switch (req) {
    611 		case KAUTH_REQ_PROCESS_RLIMIT_SET:
    612 		case KAUTH_REQ_PROCESS_RLIMIT_GET:
    613 			if (isroot)
    614 				result = KAUTH_RESULT_ALLOW;
    615 
    616 			break;
    617 
    618 		default:
    619 			break;
    620 		}
    621 
    622 		break;
    623 		}
    624 
    625 	case KAUTH_PROCESS_SCHEDULER_GETPARAM:
    626 	case KAUTH_PROCESS_SCHEDULER_SETPARAM:
    627 	case KAUTH_PROCESS_SCHEDULER_SETAFFINITY:
    628 		if (isroot)
    629 			result = KAUTH_RESULT_ALLOW;
    630 
    631 		break;
    632 
    633 	case KAUTH_PROCESS_SETID:
    634 		if (isroot)
    635 			result = KAUTH_RESULT_ALLOW;
    636 		break;
    637 
    638 	case KAUTH_PROCESS_STOPFLAG:
    639 		if (isroot || proc_uidmatch(cred, p->p_cred) == 0) {
    640 			result = KAUTH_RESULT_ALLOW;
    641 			break;
    642 		}
    643 		break;
    644 
    645 	default:
    646 		break;
    647 	}
    648 
    649 	return (result);
    650 }
    651 
    652 /*
    653  * kauth(9) listener
    654  *
    655  * Security model: Traditional NetBSD
    656  * Scope: Network
    657  * Responsibility: Superuser access
    658  */
    659 int
    660 secmodel_suser_network_cb(kauth_cred_t cred, kauth_action_t action,
    661     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    662 {
    663 	bool isroot;
    664 	int result;
    665 	enum kauth_network_req req;
    666 
    667 	isroot = (kauth_cred_geteuid(cred) == 0);
    668 	result = KAUTH_RESULT_DEFER;
    669 	req = (enum kauth_network_req)arg0;
    670 
    671 	switch (action) {
    672 	case KAUTH_NETWORK_ALTQ:
    673 		switch (req) {
    674 		case KAUTH_REQ_NETWORK_ALTQ_AFMAP:
    675 		case KAUTH_REQ_NETWORK_ALTQ_BLUE:
    676 		case KAUTH_REQ_NETWORK_ALTQ_CBQ:
    677 		case KAUTH_REQ_NETWORK_ALTQ_CDNR:
    678 		case KAUTH_REQ_NETWORK_ALTQ_CONF:
    679 		case KAUTH_REQ_NETWORK_ALTQ_FIFOQ:
    680 		case KAUTH_REQ_NETWORK_ALTQ_HFSC:
    681 		case KAUTH_REQ_NETWORK_ALTQ_JOBS:
    682 		case KAUTH_REQ_NETWORK_ALTQ_PRIQ:
    683 		case KAUTH_REQ_NETWORK_ALTQ_RED:
    684 		case KAUTH_REQ_NETWORK_ALTQ_RIO:
    685 		case KAUTH_REQ_NETWORK_ALTQ_WFQ:
    686 			if (isroot)
    687 				result = KAUTH_RESULT_ALLOW;
    688 			break;
    689 
    690 		default:
    691 			break;
    692 		}
    693 
    694 		break;
    695 
    696 	case KAUTH_NETWORK_BIND:
    697 		switch (req) {
    698 		case KAUTH_REQ_NETWORK_BIND_PORT:
    699 			result = KAUTH_RESULT_ALLOW;
    700 			break;
    701 
    702 		case KAUTH_REQ_NETWORK_BIND_PRIVPORT:
    703 			if (isroot)
    704 				result = KAUTH_RESULT_ALLOW;
    705 			break;
    706 
    707 		default:
    708 			break;
    709 		}
    710 		break;
    711 
    712 	case KAUTH_NETWORK_FORWSRCRT:
    713 		if (isroot)
    714 			result = KAUTH_RESULT_ALLOW;
    715 
    716 		break;
    717 
    718 	case KAUTH_NETWORK_INTERFACE:
    719 		switch (req) {
    720 		case KAUTH_REQ_NETWORK_INTERFACE_GET:
    721 		case KAUTH_REQ_NETWORK_INTERFACE_SET:
    722 			result = KAUTH_RESULT_ALLOW;
    723 			break;
    724 
    725 		case KAUTH_REQ_NETWORK_INTERFACE_GETPRIV:
    726 		case KAUTH_REQ_NETWORK_INTERFACE_SETPRIV:
    727 			if (isroot)
    728 				result = KAUTH_RESULT_ALLOW;
    729 			break;
    730 
    731 		default:
    732 			break;
    733 		}
    734 		break;
    735 
    736 	case KAUTH_NETWORK_INTERFACE_PPP:
    737 		switch (req) {
    738 		case KAUTH_REQ_NETWORK_INTERFACE_PPP_ADD:
    739 			if (isroot)
    740 				result = KAUTH_RESULT_ALLOW;
    741 			break;
    742 
    743 		default:
    744 			break;
    745 		}
    746 
    747 		break;
    748 
    749 	case KAUTH_NETWORK_INTERFACE_SLIP:
    750 		switch (req) {
    751 		case KAUTH_REQ_NETWORK_INTERFACE_SLIP_ADD:
    752 			if (isroot)
    753 				result = KAUTH_RESULT_ALLOW;
    754 			break;
    755 
    756 		default:
    757 			break;
    758 		}
    759 
    760 		break;
    761 
    762 	case KAUTH_NETWORK_INTERFACE_STRIP:
    763 		switch (req) {
    764 		case KAUTH_REQ_NETWORK_INTERFACE_STRIP_ADD:
    765 			if (isroot)
    766 				result = KAUTH_RESULT_ALLOW;
    767 			break;
    768 
    769 		default:
    770 			break;
    771 		}
    772 
    773 		break;
    774 
    775 	case KAUTH_NETWORK_INTERFACE_TUN:
    776 		switch (req) {
    777 		case KAUTH_REQ_NETWORK_INTERFACE_TUN_ADD:
    778 			if (isroot)
    779 				result = KAUTH_RESULT_ALLOW;
    780 			break;
    781 
    782 		default:
    783 			break;
    784 		}
    785 
    786 		break;
    787 
    788 	case KAUTH_NETWORK_NFS:
    789 		switch (req) {
    790 		case KAUTH_REQ_NETWORK_NFS_EXPORT:
    791 		case KAUTH_REQ_NETWORK_NFS_SVC:
    792 			if (isroot)
    793 				result = KAUTH_RESULT_ALLOW;
    794 
    795 			break;
    796 
    797 		default:
    798 			break;
    799 		}
    800 		break;
    801 
    802 	case KAUTH_NETWORK_ROUTE:
    803 		if (isroot)
    804 			result = KAUTH_RESULT_ALLOW;
    805 
    806 		break;
    807 
    808 	case KAUTH_NETWORK_SOCKET:
    809 		switch (req) {
    810 		case KAUTH_REQ_NETWORK_SOCKET_DROP:
    811 		case KAUTH_REQ_NETWORK_SOCKET_OPEN:
    812 		case KAUTH_REQ_NETWORK_SOCKET_RAWSOCK:
    813 		case KAUTH_REQ_NETWORK_SOCKET_SETPRIV:
    814 			if (isroot)
    815 				result = KAUTH_RESULT_ALLOW;
    816 			break;
    817 
    818 		case KAUTH_REQ_NETWORK_SOCKET_CANSEE:
    819 			if (isroot) {
    820 				result = KAUTH_RESULT_ALLOW;
    821 				break;
    822 			}
    823 
    824 			if (secmodel_bsd44_curtain) {
    825 				struct socket *so;
    826 				uid_t so_uid;
    827 
    828 				so = (struct socket *)arg1;
    829 				so_uid = so->so_uidinfo->ui_uid;
    830 				if (kauth_cred_geteuid(cred) != so_uid)
    831 					result = KAUTH_RESULT_DENY;
    832 			}
    833 
    834 			break;
    835 
    836 		default:
    837 			break;
    838 		}
    839 
    840 		break;
    841 
    842 
    843 	default:
    844 		break;
    845 	}
    846 
    847 	return (result);
    848 }
    849 
    850 /*
    851  * kauth(9) listener
    852  *
    853  * Security model: Traditional NetBSD
    854  * Scope: Machdep
    855  * Responsibility: Superuser access
    856  */
    857 int
    858 secmodel_suser_machdep_cb(kauth_cred_t cred, kauth_action_t action,
    859     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    860 {
    861         bool isroot;
    862         int result;
    863 
    864         isroot = (kauth_cred_geteuid(cred) == 0);
    865         result = KAUTH_RESULT_DEFER;
    866 
    867         switch (action) {
    868 	case KAUTH_MACHDEP_IOPERM_GET:
    869 	case KAUTH_MACHDEP_LDT_GET:
    870 	case KAUTH_MACHDEP_LDT_SET:
    871 	case KAUTH_MACHDEP_MTRR_GET:
    872 		result = KAUTH_RESULT_ALLOW;
    873 		break;
    874 
    875 	case KAUTH_MACHDEP_CACHEFLUSH:
    876 	case KAUTH_MACHDEP_IOPERM_SET:
    877 	case KAUTH_MACHDEP_IOPL:
    878 	case KAUTH_MACHDEP_MTRR_SET:
    879 	case KAUTH_MACHDEP_NVRAM:
    880 	case KAUTH_MACHDEP_UNMANAGEDMEM:
    881 		if (isroot)
    882 			result = KAUTH_RESULT_ALLOW;
    883 		break;
    884 
    885 	default:
    886 		break;
    887 	}
    888 
    889 	return (result);
    890 }
    891 
    892 /*
    893  * kauth(9) listener
    894  *
    895  * Security model: Traditional NetBSD
    896  * Scope: Device
    897  * Responsibility: Superuser access
    898  */
    899 int
    900 secmodel_suser_device_cb(kauth_cred_t cred, kauth_action_t action,
    901     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    902 {
    903         bool isroot;
    904         int result;
    905 
    906         isroot = (kauth_cred_geteuid(cred) == 0);
    907         result = KAUTH_RESULT_DEFER;
    908 
    909 	switch (action) {
    910 	case KAUTH_DEVICE_BLUETOOTH_SETPRIV:
    911 	case KAUTH_DEVICE_BLUETOOTH_SEND:
    912 	case KAUTH_DEVICE_BLUETOOTH_RECV:
    913 		if (isroot)
    914 			result = KAUTH_RESULT_ALLOW;
    915 		break;
    916 
    917 	case KAUTH_DEVICE_BLUETOOTH_BCSP:
    918 	case KAUTH_DEVICE_BLUETOOTH_BTUART: {
    919 		enum kauth_device_req req;
    920 
    921 		req = (enum kauth_device_req)arg0;
    922 		switch (req) {
    923 		case KAUTH_REQ_DEVICE_BLUETOOTH_BCSP_ADD:
    924 		case KAUTH_REQ_DEVICE_BLUETOOTH_BTUART_ADD:
    925 			if (isroot)
    926 				result = KAUTH_RESULT_ALLOW;
    927 			break;
    928 
    929 		default:
    930 			break;
    931 		}
    932 
    933 		break;
    934 		}
    935 
    936 	case KAUTH_DEVICE_RAWIO_SPEC:
    937 	case KAUTH_DEVICE_RAWIO_PASSTHRU:
    938 		/*
    939 		 * Decision is root-agnostic.
    940 		 *
    941 		 * Both requests can be issued on devices subject to their
    942 		 * permission bits.
    943 		 */
    944 		result = KAUTH_RESULT_ALLOW;
    945 		break;
    946 
    947 	case KAUTH_DEVICE_TTY_OPEN:
    948 		if (isroot)
    949 			result = KAUTH_RESULT_ALLOW;
    950 
    951 		break;
    952 
    953 	case KAUTH_DEVICE_TTY_PRIVSET:
    954 		if (isroot)
    955 			result = KAUTH_RESULT_ALLOW;
    956 
    957 		break;
    958 
    959 	case KAUTH_DEVICE_TTY_STI:
    960 		if (isroot)
    961 			result = KAUTH_RESULT_ALLOW;
    962 
    963 		break;
    964 
    965 	case KAUTH_DEVICE_RND_ADDDATA:
    966 	case KAUTH_DEVICE_RND_GETPRIV:
    967 	case KAUTH_DEVICE_RND_SETPRIV:
    968 		if (isroot)
    969 			result = KAUTH_RESULT_ALLOW;
    970 		break;
    971 
    972 	case KAUTH_DEVICE_GPIO_PINSET:
    973 		/*
    974 		 * root can access gpio pins, secmodel_securlevel can veto
    975 		 * this decision.
    976 		 */
    977 		if (isroot)
    978 			result = KAUTH_RESULT_ALLOW;
    979 		break;
    980 
    981 	default:
    982 		break;
    983 	}
    984 
    985 	return (result);
    986 }
    987 
    988 int
    989 secmodel_suser_vnode_cb(kauth_cred_t cred, kauth_action_t action,
    990     void *cookie, void *arg0, void *arg1, void *arg2, void *arg3)
    991 {
    992 	bool isroot;
    993 	int result;
    994 
    995 	isroot = (kauth_cred_geteuid(cred) == 0);
    996 	result = KAUTH_RESULT_DEFER;
    997 
    998 	if (isroot)
    999 		result = KAUTH_RESULT_ALLOW;
   1000 
   1001 	return (result);
   1002 }
   1003 
   1004