xref: /titanic_51/usr/src/uts/common/os/policy.c (revision 0c4606f05172c66c6c65847c0f940871a0ea1c15)
1 /*
2  * CDDL HEADER START
3  *
4  * The contents of this file are subject to the terms of the
5  * Common Development and Distribution License (the "License").
6  * You may not use this file except in compliance with the License.
7  *
8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9  * or http://www.opensolaris.org/os/licensing.
10  * See the License for the specific language governing permissions
11  * and limitations under the License.
12  *
13  * When distributing Covered Code, include this CDDL HEADER in each
14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15  * If applicable, add the following below this CDDL HEADER, with the
16  * fields enclosed by brackets "[]" replaced with your own identifying
17  * information: Portions Copyright [yyyy] [name of copyright owner]
18  *
19  * CDDL HEADER END
20  */
21 /*
22  * Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
23  * Use is subject to license terms.
24  */
25 
26 #include <sys/types.h>
27 #include <sys/sysmacros.h>
28 #include <sys/param.h>
29 #include <sys/systm.h>
30 #include <sys/cred_impl.h>
31 #include <sys/vnode.h>
32 #include <sys/vfs.h>
33 #include <sys/stat.h>
34 #include <sys/errno.h>
35 #include <sys/kmem.h>
36 #include <sys/user.h>
37 #include <sys/proc.h>
38 #include <sys/acct.h>
39 #include <sys/ipc_impl.h>
40 #include <sys/cmn_err.h>
41 #include <sys/debug.h>
42 #include <sys/policy.h>
43 #include <sys/kobj.h>
44 #include <sys/msg.h>
45 #include <sys/devpolicy.h>
46 #include <c2/audit.h>
47 #include <sys/varargs.h>
48 #include <sys/klpd.h>
49 #include <sys/modctl.h>
50 #include <sys/disp.h>
51 #include <sys/zone.h>
52 #include <inet/optcom.h>
53 #include <sys/sdt.h>
54 #include <sys/vfs.h>
55 #include <sys/mntent.h>
56 #include <sys/contract_impl.h>
57 #include <sys/dld_ioc.h>
58 
59 /*
60  * There are two possible layers of privilege routines and two possible
61  * levels of secpolicy.  Plus one other we may not be interested in, so
62  * we may need as many as 6 but no more.
63  */
64 #define	MAXPRIVSTACK		6
65 
66 #ifdef DEBUG
67 int priv_debug = 1;
68 #else
69 int priv_debug = 0;
70 #endif
71 int priv_basic_test = -1;
72 
73 /*
74  * This file contains the majority of the policy routines.
75  * Since the policy routines are defined by function and not
76  * by privilege, there is quite a bit of duplication of
77  * functions.
78  *
79  * The secpolicy functions must not make assumptions about
80  * locks held or not held as any lock can be held while they're
81  * being called.
82  *
83  * Credentials are read-only so no special precautions need to
84  * be taken while locking them.
85  *
86  * When a new policy check needs to be added to the system the
87  * following procedure should be followed:
88  *
89  *		Pick an appropriate secpolicy_*() function
90  *			-> done if one exists.
91  *		Create a new secpolicy function, preferably with
92  *		a descriptive name using the standard template.
93  *		Pick an appropriate privilege for the policy.
94  *		If no appropraite privilege exists, define new one
95  *		(this should be done with extreme care; in most cases
96  *		little is gained by adding another privilege)
97  *
98  * WHY ROOT IS STILL SPECIAL.
99  *
100  * In a number of the policy functions, there are still explicit
101  * checks for uid 0.  The rationale behind these is that many root
102  * owned files/objects hold configuration information which can give full
103  * privileges to the user once written to.  To prevent escalation
104  * of privilege by allowing just a single privilege to modify root owned
105  * objects, we've added these root specific checks where we considered
106  * them necessary: modifying root owned files, changing uids to 0, etc.
107  *
108  * PRIVILEGE ESCALATION AND ZONES.
109  *
110  * A number of operations potentially allow the caller to achieve
111  * privileges beyond the ones normally required to perform the operation.
112  * For example, if allowed to create a setuid 0 executable, a process can
113  * gain privileges beyond PRIV_FILE_SETID.  Zones, however, place
114  * restrictions on the ability to gain privileges beyond those available
115  * within the zone through file and process manipulation.  Hence, such
116  * operations require that the caller have an effective set that includes
117  * all privileges available within the current zone, or all privileges
118  * if executing in the global zone.
119  *
120  * This is indicated in the priv_policy* policy checking functions
121  * through a combination of parameters.  The "priv" parameter indicates
122  * the privilege that is required, and the "allzone" parameter indicates
123  * whether or not all privileges in the zone are required.  In addition,
124  * priv can be set to PRIV_ALL to indicate that all privileges are
125  * required (regardless of zone).  There are three scenarios of interest:
126  * (1) operation requires a specific privilege
127  * (2) operation requires a specific privilege, and requires all
128  *     privileges available within the zone (or all privileges if in
129  *     the global zone)
130  * (3) operation requires all privileges, regardless of zone
131  *
132  * For (1), priv should be set to the specific privilege, and allzone
133  * should be set to B_FALSE.
134  * For (2), priv should be set to the specific privilege, and allzone
135  * should be set to B_TRUE.
136  * For (3), priv should be set to PRIV_ALL, and allzone should be set
137  * to B_FALSE.
138  *
139  */
140 
141 /*
142  * The privileges are checked against the Effective set for
143  * ordinary processes and checked against the Limit set
144  * for euid 0 processes that haven't manipulated their privilege
145  * sets.
146  */
147 #define	HAS_ALLPRIVS(cr)	priv_isfullset(&CR_OEPRIV(cr))
148 #define	ZONEPRIVS(cr)		((cr)->cr_zone->zone_privset)
149 #define	HAS_ALLZONEPRIVS(cr)	priv_issubset(ZONEPRIVS(cr), &CR_OEPRIV(cr))
150 #define	HAS_PRIVILEGE(cr, pr)	((pr) == PRIV_ALL ? \
151 					HAS_ALLPRIVS(cr) : \
152 					PRIV_ISASSERT(&CR_OEPRIV(cr), pr))
153 
154 /*
155  * Policy checking functions.
156  *
157  * All of the system's policy should be implemented here.
158  */
159 
160 /*
161  * Private functions which take an additional va_list argument to
162  * implement an object specific policy override.
163  */
164 static int priv_policy_ap(const cred_t *, int, boolean_t, int,
165     const char *, va_list);
166 static int priv_policy_va(const cred_t *, int, boolean_t, int,
167     const char *, ...);
168 
169 /*
170  * Generic policy calls
171  *
172  * The "bottom" functions of policy control
173  */
174 static char *
175 mprintf(const char *fmt, ...)
176 {
177 	va_list args;
178 	char *buf;
179 	size_t len;
180 
181 	va_start(args, fmt);
182 	len = vsnprintf(NULL, 0, fmt, args) + 1;
183 	va_end(args);
184 
185 	buf = kmem_alloc(len, KM_NOSLEEP);
186 
187 	if (buf == NULL)
188 		return (NULL);
189 
190 	va_start(args, fmt);
191 	(void) vsnprintf(buf, len, fmt, args);
192 	va_end(args);
193 
194 	return (buf);
195 }
196 
197 /*
198  * priv_policy_errmsg()
199  *
200  * Generate an error message if privilege debugging is enabled system wide
201  * or for this particular process.
202  */
203 
204 #define	FMTHDR	"%s[%d]: missing privilege \"%s\" (euid = %d, syscall = %d)"
205 #define	FMTMSG	" for \"%s\""
206 #define	FMTFUN	" needed at %s+0x%lx"
207 
208 /* The maximum size privilege format: the concatenation of the above */
209 #define	FMTMAX	FMTHDR FMTMSG FMTFUN "\n"
210 
211 static void
212 priv_policy_errmsg(const cred_t *cr, int priv, const char *msg)
213 {
214 	struct proc *me;
215 	pc_t stack[MAXPRIVSTACK];
216 	int depth;
217 	int i;
218 	char *sym;
219 	ulong_t off;
220 	const char *pname;
221 
222 	char *cmd;
223 	char fmt[sizeof (FMTMAX)];
224 
225 	if ((me = curproc) == &p0)
226 		return;
227 
228 	/* Privileges must be defined  */
229 	ASSERT(priv == PRIV_ALL || priv == PRIV_MULTIPLE ||
230 	    priv == PRIV_ALLZONE || priv == PRIV_GLOBAL ||
231 	    priv_getbynum(priv) != NULL);
232 
233 	if (priv == PRIV_ALLZONE && INGLOBALZONE(me))
234 		priv = PRIV_ALL;
235 
236 	if (curthread->t_pre_sys)
237 		ttolwp(curthread)->lwp_badpriv = (short)priv;
238 
239 	if (priv_debug == 0 && (CR_FLAGS(cr) & PRIV_DEBUG) == 0)
240 		return;
241 
242 	(void) strcpy(fmt, FMTHDR);
243 
244 	if (me->p_user.u_comm[0])
245 		cmd = &me->p_user.u_comm[0];
246 	else
247 		cmd = "priv_policy";
248 
249 	if (msg != NULL && *msg != '\0') {
250 		(void) strcat(fmt, FMTMSG);
251 	} else {
252 		(void) strcat(fmt, "%s");
253 		msg = "";
254 	}
255 
256 	sym = NULL;
257 
258 	depth = getpcstack(stack, MAXPRIVSTACK);
259 
260 	/*
261 	 * Try to find the first interesting function on the stack.
262 	 * priv_policy* that's us, so completely uninteresting.
263 	 * suser(), drv_priv(), secpolicy_* are also called from
264 	 * too many locations to convey useful information.
265 	 */
266 	for (i = 0; i < depth; i++) {
267 		sym = kobj_getsymname((uintptr_t)stack[i], &off);
268 		if (sym != NULL &&
269 		    strstr(sym, "hasprocperm") == 0 &&
270 		    strcmp("suser", sym) != 0 &&
271 		    strcmp("ipcaccess", sym) != 0 &&
272 		    strcmp("drv_priv", sym) != 0 &&
273 		    strncmp("secpolicy_", sym, 10) != 0 &&
274 		    strncmp("priv_policy", sym, 11) != 0)
275 			break;
276 	}
277 
278 	if (sym != NULL)
279 		(void) strcat(fmt, FMTFUN);
280 
281 	(void) strcat(fmt, "\n");
282 
283 	switch (priv) {
284 	case PRIV_ALL:
285 		pname = "ALL";
286 		break;
287 	case PRIV_MULTIPLE:
288 		pname = "MULTIPLE";
289 		break;
290 	case PRIV_ALLZONE:
291 		pname = "ZONE";
292 		break;
293 	case PRIV_GLOBAL:
294 		pname = "GLOBAL";
295 		break;
296 	default:
297 		pname = priv_getbynum(priv);
298 		break;
299 	}
300 
301 	if (CR_FLAGS(cr) & PRIV_DEBUG) {
302 		/* Remember last message, just like lwp_badpriv. */
303 		if (curthread->t_pdmsg != NULL) {
304 			kmem_free(curthread->t_pdmsg,
305 			    strlen(curthread->t_pdmsg) + 1);
306 		}
307 
308 		curthread->t_pdmsg = mprintf(fmt, cmd, me->p_pid, pname,
309 		    cr->cr_uid, curthread->t_sysnum, msg, sym, off);
310 
311 		curthread->t_post_sys = 1;
312 	}
313 	if (priv_debug) {
314 		cmn_err(CE_NOTE, fmt, cmd, me->p_pid, pname, cr->cr_uid,
315 		    curthread->t_sysnum, msg, sym, off);
316 	}
317 }
318 
319 /*
320  * Override the policy, if appropriate.  Return 0 if the external
321  * policy engine approves.
322  */
323 static int
324 priv_policy_override(const cred_t *cr, int priv, boolean_t allzone, va_list ap)
325 {
326 	priv_set_t set;
327 	int ret;
328 
329 	if (!(CR_FLAGS(cr) & PRIV_XPOLICY))
330 		return (-1);
331 
332 	if (priv == PRIV_ALL) {
333 		priv_fillset(&set);
334 	} else if (allzone) {
335 		set = *ZONEPRIVS(cr);
336 	} else {
337 		priv_emptyset(&set);
338 		priv_addset(&set, priv);
339 	}
340 	ret = klpd_call(cr, &set, ap);
341 	return (ret);
342 }
343 
344 static int
345 priv_policy_override_set(const cred_t *cr, const priv_set_t *req, ...)
346 {
347 	va_list ap;
348 
349 	if (CR_FLAGS(cr) & PRIV_XPOLICY) {
350 		va_start(ap, req);
351 		return (klpd_call(cr, req, ap));
352 	}
353 	return (-1);
354 }
355 
356 /*
357  * Audit failure, log error message.
358  */
359 static void
360 priv_policy_err(const cred_t *cr, int priv, boolean_t allzone, const char *msg)
361 {
362 
363 	if (audit_active)
364 		audit_priv(priv, allzone ? ZONEPRIVS(cr) : NULL, 0);
365 	DTRACE_PROBE2(priv__err, int, priv, boolean_t, allzone);
366 
367 	if (priv_debug || (CR_FLAGS(cr) & PRIV_DEBUG) ||
368 	    curthread->t_pre_sys) {
369 		if (allzone && !HAS_ALLZONEPRIVS(cr)) {
370 			priv_policy_errmsg(cr, PRIV_ALLZONE, msg);
371 		} else {
372 			ASSERT(!HAS_PRIVILEGE(cr, priv));
373 			priv_policy_errmsg(cr, priv, msg);
374 		}
375 	}
376 }
377 
378 /*
379  * priv_policy_ap()
380  * return 0 or error.
381  * See block comment above for a description of "priv" and "allzone" usage.
382  */
383 static int
384 priv_policy_ap(const cred_t *cr, int priv, boolean_t allzone, int err,
385     const char *msg, va_list ap)
386 {
387 	if ((HAS_PRIVILEGE(cr, priv) && (!allzone || HAS_ALLZONEPRIVS(cr))) ||
388 	    (!servicing_interrupt() &&
389 	    priv_policy_override(cr, priv, allzone, ap) == 0)) {
390 		if ((allzone || priv == PRIV_ALL ||
391 		    !PRIV_ISASSERT(priv_basic, priv)) &&
392 		    !servicing_interrupt()) {
393 			PTOU(curproc)->u_acflag |= ASU; /* Needed for SVVS */
394 			if (audit_active)
395 				audit_priv(priv,
396 				    allzone ? ZONEPRIVS(cr) : NULL, 1);
397 		}
398 		err = 0;
399 		DTRACE_PROBE2(priv__ok, int, priv, boolean_t, allzone);
400 	} else if (!servicing_interrupt()) {
401 		/* Failure audited in this procedure */
402 		priv_policy_err(cr, priv, allzone, msg);
403 	}
404 	return (err);
405 }
406 
407 int
408 priv_policy_va(const cred_t *cr, int priv, boolean_t allzone, int err,
409     const char *msg, ...)
410 {
411 	int ret;
412 	va_list ap;
413 
414 	va_start(ap, msg);
415 	ret = priv_policy_ap(cr, priv, allzone, err, msg, ap);
416 	va_end(ap);
417 
418 	return (ret);
419 }
420 
421 int
422 priv_policy(const cred_t *cr, int priv, boolean_t allzone, int err,
423     const char *msg)
424 {
425 	return (priv_policy_va(cr, priv, allzone, err, msg, KLPDARG_NOMORE));
426 }
427 
428 /*
429  * Return B_TRUE for sufficient privileges, B_FALSE for insufficient privileges.
430  */
431 boolean_t
432 priv_policy_choice(const cred_t *cr, int priv, boolean_t allzone)
433 {
434 	boolean_t res = HAS_PRIVILEGE(cr, priv) &&
435 	    (!allzone || HAS_ALLZONEPRIVS(cr));
436 
437 	/* Audit success only */
438 	if (res && audit_active &&
439 	    (allzone || priv == PRIV_ALL || !PRIV_ISASSERT(priv_basic, priv)) &&
440 	    !servicing_interrupt()) {
441 		audit_priv(priv, allzone ? ZONEPRIVS(cr) : NULL, 1);
442 	}
443 	if (res) {
444 		DTRACE_PROBE2(priv__ok, int, priv, boolean_t, allzone);
445 	} else {
446 		DTRACE_PROBE2(priv__err, int, priv, boolean_t, allzone);
447 	}
448 	return (res);
449 }
450 
451 /*
452  * Non-auditing variant of priv_policy_choice().
453  */
454 boolean_t
455 priv_policy_only(const cred_t *cr, int priv, boolean_t allzone)
456 {
457 	boolean_t res = HAS_PRIVILEGE(cr, priv) &&
458 	    (!allzone || HAS_ALLZONEPRIVS(cr));
459 
460 	if (res) {
461 		DTRACE_PROBE2(priv__ok, int, priv, boolean_t, allzone);
462 	} else {
463 		DTRACE_PROBE2(priv__err, int, priv, boolean_t, allzone);
464 	}
465 	return (res);
466 }
467 
468 /*
469  * Check whether all privileges in the required set are present.
470  */
471 static int
472 secpolicy_require_set(const cred_t *cr, const priv_set_t *req, const char *msg)
473 {
474 	int priv;
475 	int pfound = -1;
476 	priv_set_t pset;
477 
478 	if (req == PRIV_FULLSET ? HAS_ALLPRIVS(cr) : priv_issubset(req,
479 	    &CR_OEPRIV(cr))) {
480 		return (0);
481 	}
482 
483 	if (priv_policy_override_set(cr, req, KLPDARG_NOMORE) == 0)
484 		return (0);
485 
486 	if (req == PRIV_FULLSET || priv_isfullset(req)) {
487 		priv_policy_err(cr, PRIV_ALL, B_FALSE, msg);
488 		return (EACCES);
489 	}
490 
491 	pset = CR_OEPRIV(cr);		/* present privileges */
492 	priv_inverse(&pset);		/* all non present privileges */
493 	priv_intersect(req, &pset);	/* the actual missing privs */
494 
495 	if (audit_active)
496 		audit_priv(PRIV_NONE, &pset, 0);
497 	/*
498 	 * Privilege debugging; special case "one privilege in set".
499 	 */
500 	if (priv_debug || (CR_FLAGS(cr) & PRIV_DEBUG) || curthread->t_pre_sys) {
501 		for (priv = 0; priv < nprivs; priv++) {
502 			if (priv_ismember(&pset, priv)) {
503 				if (pfound != -1) {
504 					/* Multiple missing privs */
505 					priv_policy_errmsg(cr, PRIV_MULTIPLE,
506 					    msg);
507 					return (EACCES);
508 				}
509 				pfound = priv;
510 			}
511 		}
512 		ASSERT(pfound != -1);
513 		/* Just the one missing privilege */
514 		priv_policy_errmsg(cr, pfound, msg);
515 	}
516 
517 	return (EACCES);
518 }
519 
520 /*
521  * Called when an operation requires that the caller be in the
522  * global zone, regardless of privilege.
523  */
524 static int
525 priv_policy_global(const cred_t *cr)
526 {
527 	if (crgetzoneid(cr) == GLOBAL_ZONEID)
528 		return (0);	/* success */
529 
530 	if (priv_debug || (CR_FLAGS(cr) & PRIV_DEBUG) ||
531 	    curthread->t_pre_sys) {
532 		priv_policy_errmsg(cr, PRIV_GLOBAL, NULL);
533 	}
534 	return (EPERM);
535 }
536 
537 /*
538  * Changing process priority
539  */
540 int
541 secpolicy_setpriority(const cred_t *cr)
542 {
543 	return (PRIV_POLICY(cr, PRIV_PROC_PRIOCNTL, B_FALSE, EPERM, NULL));
544 }
545 
546 /*
547  * Binding to a privileged port, port must be specified in host byte
548  * order.
549  */
550 int
551 secpolicy_net_privaddr(const cred_t *cr, in_port_t port, int proto)
552 {
553 	char *reason;
554 	int priv;
555 
556 	switch (port) {
557 	case 137:
558 	case 138:
559 	case 139:
560 	case 445:
561 		/*
562 		 * NBT and SMB ports, these are extra privileged ports,
563 		 * allow bind only if the SYS_SMB privilege is present.
564 		 */
565 		priv = PRIV_SYS_SMB;
566 		reason = "NBT or SMB port";
567 		break;
568 
569 	case 2049:
570 	case 4045:
571 		/*
572 		 * NFS ports, these are extra privileged ports, allow bind
573 		 * only if the SYS_NFS privilege is present.
574 		 */
575 		priv = PRIV_SYS_NFS;
576 		reason = "NFS port";
577 		break;
578 
579 	default:
580 		priv = PRIV_NET_PRIVADDR;
581 		reason = NULL;
582 		break;
583 
584 	}
585 
586 	return (priv_policy_va(cr, priv, B_FALSE, EACCES, reason,
587 	    KLPDARG_PORT, (int)proto, (int)port, KLPDARG_NOMORE));
588 }
589 
590 /*
591  * Binding to a multilevel port on a trusted (labeled) system.
592  */
593 int
594 secpolicy_net_bindmlp(const cred_t *cr)
595 {
596 	return (PRIV_POLICY(cr, PRIV_NET_BINDMLP, B_FALSE, EACCES, NULL));
597 }
598 
599 /*
600  * Allow a communication between a zone and an unlabeled host when their
601  * labels don't match.
602  */
603 int
604 secpolicy_net_mac_aware(const cred_t *cr)
605 {
606 	return (PRIV_POLICY(cr, PRIV_NET_MAC_AWARE, B_FALSE, EACCES, NULL));
607 }
608 
609 /*
610  * Allow a privileged process to transmit traffic without explicit labels
611  */
612 int
613 secpolicy_net_mac_implicit(const cred_t *cr)
614 {
615 	return (PRIV_POLICY(cr, PRIV_NET_MAC_IMPLICIT, B_FALSE, EACCES, NULL));
616 }
617 
618 /*
619  * Common routine which determines whether a given credential can
620  * act on a given mount.
621  * When called through mount, the parameter needoptcheck is a pointer
622  * to a boolean variable which will be set to either true or false,
623  * depending on whether the mount policy should change the mount options.
624  * In all other cases, needoptcheck should be a NULL pointer.
625  */
626 static int
627 secpolicy_fs_common(cred_t *cr, vnode_t *mvp, const vfs_t *vfsp,
628     boolean_t *needoptcheck)
629 {
630 	boolean_t allzone = B_FALSE;
631 	boolean_t mounting = needoptcheck != NULL;
632 
633 	/*
634 	 * Short circuit the following cases:
635 	 *	vfsp == NULL or mvp == NULL (pure privilege check)
636 	 *	have all privileges - no further checks required
637 	 *	and no mount options need to be set.
638 	 */
639 	if (vfsp == NULL || mvp == NULL || HAS_ALLPRIVS(cr)) {
640 		if (mounting)
641 			*needoptcheck = B_FALSE;
642 
643 		return (priv_policy_va(cr, PRIV_SYS_MOUNT, allzone, EPERM,
644 		    NULL, KLPDARG_VNODE, mvp, (char *)NULL, KLPDARG_NOMORE));
645 	}
646 
647 	/*
648 	 * When operating on an existing mount (either we're not mounting
649 	 * or we're doing a remount and VFS_REMOUNT will be set), zones
650 	 * can operate only on mounts established by the zone itself.
651 	 */
652 	if (!mounting || (vfsp->vfs_flag & VFS_REMOUNT) != 0) {
653 		zoneid_t zoneid = crgetzoneid(cr);
654 
655 		if (zoneid != GLOBAL_ZONEID &&
656 		    vfsp->vfs_zone->zone_id != zoneid) {
657 			return (EPERM);
658 		}
659 	}
660 
661 	if (mounting)
662 		*needoptcheck = B_TRUE;
663 
664 	/*
665 	 * Overlay mounts may hide important stuff; if you can't write to a
666 	 * mount point but would be able to mount on top of it, you can
667 	 * escalate your privileges.
668 	 * So we go about asking the same questions namefs does when it
669 	 * decides whether you can mount over a file or not but with the
670 	 * added restriction that you can only mount on top of a regular
671 	 * file or directory.
672 	 * If we have all the zone's privileges, we skip all other checks,
673 	 * or else we may actually get in trouble inside the automounter.
674 	 */
675 	if ((mvp->v_flag & VROOT) != 0 ||
676 	    (mvp->v_type != VDIR && mvp->v_type != VREG) ||
677 	    HAS_ALLZONEPRIVS(cr)) {
678 		allzone = B_TRUE;
679 	} else {
680 		vattr_t va;
681 		int err;
682 
683 		va.va_mask = AT_UID|AT_MODE;
684 		err = VOP_GETATTR(mvp, &va, 0, cr, NULL);
685 		if (err != 0)
686 			return (err);
687 
688 		if ((err = secpolicy_vnode_owner(cr, va.va_uid)) != 0)
689 			return (err);
690 
691 		if ((va.va_mode & VWRITE) == 0 &&
692 		    secpolicy_vnode_access(cr, mvp, va.va_uid, VWRITE) != 0) {
693 			return (EACCES);
694 		}
695 	}
696 	return (priv_policy_va(cr, PRIV_SYS_MOUNT, allzone, EPERM,
697 	    NULL, KLPDARG_VNODE, mvp, (char *)NULL, KLPDARG_NOMORE));
698 }
699 
700 void
701 secpolicy_fs_mount_clearopts(cred_t *cr, struct vfs *vfsp)
702 {
703 	boolean_t amsuper = HAS_ALLZONEPRIVS(cr);
704 
705 	/*
706 	 * check; if we don't have either "nosuid" or
707 	 * both "nosetuid" and "nodevices", then we add
708 	 * "nosuid"; this depends on how the current
709 	 * implementation works (it first checks nosuid).  In a
710 	 * zone, a user with all zone privileges can mount with
711 	 * "setuid" but never with "devices".
712 	 */
713 	if (!vfs_optionisset(vfsp, MNTOPT_NOSUID, NULL) &&
714 	    (!vfs_optionisset(vfsp, MNTOPT_NODEVICES, NULL) ||
715 	    !vfs_optionisset(vfsp, MNTOPT_NOSETUID, NULL))) {
716 		if (crgetzoneid(cr) == GLOBAL_ZONEID || !amsuper)
717 			vfs_setmntopt(vfsp, MNTOPT_NOSUID, NULL, 0);
718 		else
719 			vfs_setmntopt(vfsp, MNTOPT_NODEVICES, NULL, 0);
720 	}
721 	/*
722 	 * If we're not the local super user, we set the "restrict"
723 	 * option to indicate to automountd that this mount should
724 	 * be handled with care.
725 	 */
726 	if (!amsuper)
727 		vfs_setmntopt(vfsp, MNTOPT_RESTRICT, NULL, 0);
728 
729 }
730 
731 extern vnode_t *rootvp;
732 extern vfs_t *rootvfs;
733 
734 int
735 secpolicy_fs_mount(cred_t *cr, vnode_t *mvp, struct vfs *vfsp)
736 {
737 	boolean_t needoptchk;
738 	int error;
739 
740 	/*
741 	 * If it's a remount, get the underlying mount point,
742 	 * except for the root where we use the rootvp.
743 	 */
744 	if ((vfsp->vfs_flag & VFS_REMOUNT) != 0) {
745 		if (vfsp == rootvfs)
746 			mvp = rootvp;
747 		else
748 			mvp = vfsp->vfs_vnodecovered;
749 	}
750 
751 	error = secpolicy_fs_common(cr, mvp, vfsp, &needoptchk);
752 
753 	if (error == 0 && needoptchk) {
754 		secpolicy_fs_mount_clearopts(cr, vfsp);
755 	}
756 
757 	return (error);
758 }
759 
760 /*
761  * Does the policy computations for "ownership" of a mount;
762  * here ownership is defined as the ability to "mount"
763  * the filesystem originally.  The rootvfs doesn't cover any
764  * vnodes; we attribute its ownership to the rootvp.
765  */
766 static int
767 secpolicy_fs_owner(cred_t *cr, const struct vfs *vfsp)
768 {
769 	vnode_t *mvp;
770 
771 	if (vfsp == NULL)
772 		mvp = NULL;
773 	else if (vfsp == rootvfs)
774 		mvp = rootvp;
775 	else
776 		mvp = vfsp->vfs_vnodecovered;
777 
778 	return (secpolicy_fs_common(cr, mvp, vfsp, NULL));
779 }
780 
781 int
782 secpolicy_fs_unmount(cred_t *cr, struct vfs *vfsp)
783 {
784 	return (secpolicy_fs_owner(cr, vfsp));
785 }
786 
787 /*
788  * Quotas are a resource, but if one has the ability to mount a filesystem, he
789  * should be able to modify quotas on it.
790  */
791 int
792 secpolicy_fs_quota(const cred_t *cr, const vfs_t *vfsp)
793 {
794 	return (secpolicy_fs_owner((cred_t *)cr, vfsp));
795 }
796 
797 /*
798  * Exceeding minfree: also a per-mount resource constraint.
799  */
800 int
801 secpolicy_fs_minfree(const cred_t *cr, const vfs_t *vfsp)
802 {
803 	return (secpolicy_fs_owner((cred_t *)cr, vfsp));
804 }
805 
806 int
807 secpolicy_fs_config(const cred_t *cr, const vfs_t *vfsp)
808 {
809 	return (secpolicy_fs_owner((cred_t *)cr, vfsp));
810 }
811 
812 /* ARGSUSED */
813 int
814 secpolicy_fs_linkdir(const cred_t *cr, const vfs_t *vfsp)
815 {
816 	return (PRIV_POLICY(cr, PRIV_SYS_LINKDIR, B_FALSE, EPERM, NULL));
817 }
818 
819 /*
820  * Name:        secpolicy_vnode_access()
821  *
822  * Parameters:  Process credential
823  *		vnode
824  *		uid of owner of vnode
825  *		permission bits not granted to the caller when examining
826  *		file mode bits (i.e., when a process wants to open a
827  *		mode 444 file for VREAD|VWRITE, this function should be
828  *		called only with a VWRITE argument).
829  *
830  * Normal:      Verifies that cred has the appropriate privileges to
831  *              override the mode bits that were denied.
832  *
833  * Override:    file_dac_execute - if VEXEC bit was denied and vnode is
834  *                      not a directory.
835  *              file_dac_read - if VREAD bit was denied.
836  *              file_dac_search - if VEXEC bit was denied and vnode is
837  *                      a directory.
838  *              file_dac_write - if VWRITE bit was denied.
839  *
840  *		Root owned files are special cased to protect system
841  *		configuration files and such.
842  *
843  * Output:      EACCES - if privilege check fails.
844  */
845 
846 /* ARGSUSED */
847 int
848 secpolicy_vnode_access(const cred_t *cr, vnode_t *vp, uid_t owner, mode_t mode)
849 {
850 	if ((mode & VREAD) && priv_policy_va(cr, PRIV_FILE_DAC_READ, B_FALSE,
851 	    EACCES, NULL, KLPDARG_VNODE, vp, (char *)NULL,
852 	    KLPDARG_NOMORE) != 0) {
853 		return (EACCES);
854 	}
855 
856 	if (mode & VWRITE) {
857 		boolean_t allzone;
858 
859 		if (owner == 0 && cr->cr_uid != 0)
860 			allzone = B_TRUE;
861 		else
862 			allzone = B_FALSE;
863 		if (priv_policy_va(cr, PRIV_FILE_DAC_WRITE, allzone, EACCES,
864 		    NULL, KLPDARG_VNODE, vp, (char *)NULL,
865 		    KLPDARG_NOMORE) != 0) {
866 			return (EACCES);
867 		}
868 	}
869 
870 	if (mode & VEXEC) {
871 		/*
872 		 * Directories use file_dac_search to override the execute bit.
873 		 */
874 		int p = vp->v_type == VDIR ? PRIV_FILE_DAC_SEARCH :
875 		    PRIV_FILE_DAC_EXECUTE;
876 
877 		return (priv_policy_va(cr, p, B_FALSE, EACCES, NULL,
878 		    KLPDARG_VNODE, vp, (char *)NULL, KLPDARG_NOMORE));
879 	}
880 	return (0);
881 }
882 
883 /*
884  * Name:	secpolicy_vnode_setid_modify()
885  *
886  * Normal:	verify that subject can set the file setid flags.
887  *
888  * Output:	EPERM - if not privileged.
889  */
890 
891 static int
892 secpolicy_vnode_setid_modify(const cred_t *cr, uid_t owner)
893 {
894 	/* If changing to suid root, must have all zone privs */
895 	boolean_t allzone = B_TRUE;
896 
897 	if (owner != 0) {
898 		if (owner == cr->cr_uid)
899 			return (0);
900 		allzone = B_FALSE;
901 	}
902 	return (PRIV_POLICY(cr, PRIV_FILE_SETID, allzone, EPERM, NULL));
903 }
904 
905 /*
906  * Are we allowed to retain the set-uid/set-gid bits when
907  * changing ownership or when writing to a file?
908  * "issuid" should be true when set-uid; only in that case
909  * root ownership is checked (setgid is assumed).
910  */
911 int
912 secpolicy_vnode_setid_retain(const cred_t *cred, boolean_t issuidroot)
913 {
914 	if (issuidroot && !HAS_ALLZONEPRIVS(cred))
915 		return (EPERM);
916 
917 	return (!PRIV_POLICY_CHOICE(cred, PRIV_FILE_SETID, B_FALSE));
918 }
919 
920 /*
921  * Name:	secpolicy_vnode_setids_setgids()
922  *
923  * Normal:	verify that subject can set the file setgid flag.
924  *
925  * Output:	EPERM - if not privileged
926  */
927 
928 int
929 secpolicy_vnode_setids_setgids(const cred_t *cred, gid_t gid)
930 {
931 	if (!groupmember(gid, cred))
932 		return (PRIV_POLICY(cred, PRIV_FILE_SETID, B_FALSE, EPERM,
933 		    NULL));
934 	return (0);
935 }
936 
937 /*
938  * Name:	secpolicy_vnode_chown
939  *
940  * Normal:	Determine if subject can chown owner of a file.
941  *
942  * Output:	EPERM - if access denied
943  */
944 
945 int
946 secpolicy_vnode_chown(const cred_t *cred, uid_t owner)
947 {
948 	boolean_t is_owner = (owner == crgetuid(cred));
949 	boolean_t allzone = B_FALSE;
950 	int priv;
951 
952 	if (!is_owner) {
953 		allzone = (owner == 0);
954 		priv = PRIV_FILE_CHOWN;
955 	} else {
956 		priv = HAS_PRIVILEGE(cred, PRIV_FILE_CHOWN) ?
957 		    PRIV_FILE_CHOWN : PRIV_FILE_CHOWN_SELF;
958 	}
959 
960 	return (PRIV_POLICY(cred, priv, allzone, EPERM, NULL));
961 }
962 
963 /*
964  * Name:	secpolicy_vnode_create_gid
965  *
966  * Normal:	Determine if subject can change group ownership of a file.
967  *
968  * Output:	EPERM - if access denied
969  */
970 int
971 secpolicy_vnode_create_gid(const cred_t *cred)
972 {
973 	if (HAS_PRIVILEGE(cred, PRIV_FILE_CHOWN))
974 		return (PRIV_POLICY(cred, PRIV_FILE_CHOWN, B_FALSE, EPERM,
975 		    NULL));
976 	else
977 		return (PRIV_POLICY(cred, PRIV_FILE_CHOWN_SELF, B_FALSE, EPERM,
978 		    NULL));
979 }
980 
981 /*
982  * Name:	secpolicy_vnode_utime_modify()
983  *
984  * Normal:	verify that subject can modify the utime on a file.
985  *
986  * Output:	EPERM - if access denied.
987  */
988 
989 static int
990 secpolicy_vnode_utime_modify(const cred_t *cred)
991 {
992 	return (PRIV_POLICY(cred, PRIV_FILE_OWNER, B_FALSE, EPERM,
993 	    "modify file times"));
994 }
995 
996 
997 /*
998  * Name:	secpolicy_vnode_setdac()
999  *
1000  * Normal:	verify that subject can modify the mode of a file.
1001  *		allzone privilege needed when modifying root owned object.
1002  *
1003  * Output:	EPERM - if access denied.
1004  */
1005 
1006 int
1007 secpolicy_vnode_setdac(const cred_t *cred, uid_t owner)
1008 {
1009 	if (owner == cred->cr_uid)
1010 		return (0);
1011 
1012 	return (PRIV_POLICY(cred, PRIV_FILE_OWNER, owner == 0, EPERM, NULL));
1013 }
1014 /*
1015  * Name:	secpolicy_vnode_stky_modify()
1016  *
1017  * Normal:	verify that subject can make a file a "sticky".
1018  *
1019  * Output:	EPERM - if access denied.
1020  */
1021 
1022 int
1023 secpolicy_vnode_stky_modify(const cred_t *cred)
1024 {
1025 	return (PRIV_POLICY(cred, PRIV_SYS_CONFIG, B_FALSE, EPERM,
1026 	    "set file sticky"));
1027 }
1028 
1029 /*
1030  * Policy determines whether we can remove an entry from a directory,
1031  * regardless of permission bits.
1032  */
1033 int
1034 secpolicy_vnode_remove(const cred_t *cr)
1035 {
1036 	return (PRIV_POLICY(cr, PRIV_FILE_OWNER, B_FALSE, EACCES,
1037 	    "sticky directory"));
1038 }
1039 
1040 int
1041 secpolicy_vnode_owner(const cred_t *cr, uid_t owner)
1042 {
1043 	boolean_t allzone = (owner == 0);
1044 
1045 	if (owner == cr->cr_uid)
1046 		return (0);
1047 
1048 	return (PRIV_POLICY(cr, PRIV_FILE_OWNER, allzone, EPERM, NULL));
1049 }
1050 
1051 void
1052 secpolicy_setid_clear(vattr_t *vap, cred_t *cr)
1053 {
1054 	if ((vap->va_mode & (S_ISUID | S_ISGID)) != 0 &&
1055 	    secpolicy_vnode_setid_retain(cr,
1056 	    (vap->va_mode & S_ISUID) != 0 &&
1057 	    (vap->va_mask & AT_UID) != 0 && vap->va_uid == 0) != 0) {
1058 		vap->va_mask |= AT_MODE;
1059 		vap->va_mode &= ~(S_ISUID|S_ISGID);
1060 	}
1061 }
1062 
1063 int
1064 secpolicy_setid_setsticky_clear(vnode_t *vp, vattr_t *vap, const vattr_t *ovap,
1065     cred_t *cr)
1066 {
1067 	int error;
1068 
1069 	if ((vap->va_mode & S_ISUID) != 0 &&
1070 	    (error = secpolicy_vnode_setid_modify(cr,
1071 	    ovap->va_uid)) != 0) {
1072 		return (error);
1073 	}
1074 
1075 	/*
1076 	 * Check privilege if attempting to set the
1077 	 * sticky bit on a non-directory.
1078 	 */
1079 	if (vp->v_type != VDIR && (vap->va_mode & S_ISVTX) != 0 &&
1080 	    secpolicy_vnode_stky_modify(cr) != 0) {
1081 		vap->va_mode &= ~S_ISVTX;
1082 	}
1083 
1084 	/*
1085 	 * Check for privilege if attempting to set the
1086 	 * group-id bit.
1087 	 */
1088 	if ((vap->va_mode & S_ISGID) != 0 &&
1089 	    secpolicy_vnode_setids_setgids(cr, ovap->va_gid) != 0) {
1090 		vap->va_mode &= ~S_ISGID;
1091 	}
1092 
1093 	return (0);
1094 }
1095 
1096 #define	ATTR_FLAG_PRIV(attr, value, cr)	\
1097 	PRIV_POLICY(cr, value ? PRIV_FILE_FLAG_SET : PRIV_ALL, \
1098 	B_FALSE, EPERM, NULL)
1099 
1100 /*
1101  * Check privileges for setting xvattr attributes
1102  */
1103 int
1104 secpolicy_xvattr(xvattr_t *xvap, uid_t owner, cred_t *cr, vtype_t vtype)
1105 {
1106 	xoptattr_t *xoap;
1107 	int error = 0;
1108 
1109 	if ((xoap = xva_getxoptattr(xvap)) == NULL)
1110 		return (EINVAL);
1111 
1112 	/*
1113 	 * First process the DOS bits
1114 	 */
1115 	if (XVA_ISSET_REQ(xvap, XAT_ARCHIVE) ||
1116 	    XVA_ISSET_REQ(xvap, XAT_HIDDEN) ||
1117 	    XVA_ISSET_REQ(xvap, XAT_READONLY) ||
1118 	    XVA_ISSET_REQ(xvap, XAT_SYSTEM) ||
1119 	    XVA_ISSET_REQ(xvap, XAT_CREATETIME)) {
1120 		if ((error = secpolicy_vnode_owner(cr, owner)) != 0)
1121 			return (error);
1122 	}
1123 
1124 	/*
1125 	 * Now handle special attributes
1126 	 */
1127 
1128 	if (XVA_ISSET_REQ(xvap, XAT_IMMUTABLE))
1129 		error = ATTR_FLAG_PRIV(XAT_IMMUTABLE,
1130 		    xoap->xoa_immutable, cr);
1131 	if (error == 0 && XVA_ISSET_REQ(xvap, XAT_NOUNLINK))
1132 		error = ATTR_FLAG_PRIV(XAT_NOUNLINK,
1133 		    xoap->xoa_nounlink, cr);
1134 	if (error == 0 && XVA_ISSET_REQ(xvap, XAT_APPENDONLY))
1135 		error = ATTR_FLAG_PRIV(XAT_APPENDONLY,
1136 		    xoap->xoa_appendonly, cr);
1137 	if (error == 0 && XVA_ISSET_REQ(xvap, XAT_NODUMP))
1138 		error = ATTR_FLAG_PRIV(XAT_NODUMP,
1139 		    xoap->xoa_nodump, cr);
1140 	if (error == 0 && XVA_ISSET_REQ(xvap, XAT_OPAQUE))
1141 		error = EPERM;
1142 	if (error == 0 && XVA_ISSET_REQ(xvap, XAT_AV_QUARANTINED)) {
1143 		error = ATTR_FLAG_PRIV(XAT_AV_QUARANTINED,
1144 		    xoap->xoa_av_quarantined, cr);
1145 		if (error == 0 && vtype != VREG && xoap->xoa_av_quarantined)
1146 			error = EINVAL;
1147 	}
1148 	if (error == 0 && XVA_ISSET_REQ(xvap, XAT_AV_MODIFIED))
1149 		error = ATTR_FLAG_PRIV(XAT_AV_MODIFIED,
1150 		    xoap->xoa_av_modified, cr);
1151 	if (error == 0 && XVA_ISSET_REQ(xvap, XAT_AV_SCANSTAMP)) {
1152 		error = ATTR_FLAG_PRIV(XAT_AV_SCANSTAMP,
1153 		    xoap->xoa_av_scanstamp, cr);
1154 		if (error == 0 && vtype != VREG)
1155 			error = EINVAL;
1156 	}
1157 	return (error);
1158 }
1159 
1160 /*
1161  * This function checks the policy decisions surrounding the
1162  * vop setattr call.
1163  *
1164  * It should be called after sufficient locks have been established
1165  * on the underlying data structures.  No concurrent modifications
1166  * should be allowed.
1167  *
1168  * The caller must pass in unlocked version of its vaccess function
1169  * this is required because vop_access function should lock the
1170  * node for reading.  A three argument function should be defined
1171  * which accepts the following argument:
1172  * 	A pointer to the internal "node" type (inode *)
1173  *	vnode access bits (VREAD|VWRITE|VEXEC)
1174  *	a pointer to the credential
1175  *
1176  * This function makes the following policy decisions:
1177  *
1178  *		- change permissions
1179  *			- permission to change file mode if not owner
1180  *			- permission to add sticky bit to non-directory
1181  *			- permission to add set-gid bit
1182  *
1183  * The ovap argument should include AT_MODE|AT_UID|AT_GID.
1184  *
1185  * If the vap argument does not include AT_MODE, the mode will be copied from
1186  * ovap.  In certain situations set-uid/set-gid bits need to be removed;
1187  * this is done by marking vap->va_mask to include AT_MODE and va_mode
1188  * is updated to the newly computed mode.
1189  */
1190 
1191 int
1192 secpolicy_vnode_setattr(cred_t *cr, struct vnode *vp, struct vattr *vap,
1193 	const struct vattr *ovap, int flags,
1194 	int unlocked_access(void *, int, cred_t *),
1195 	void *node)
1196 {
1197 	int mask = vap->va_mask;
1198 	int error = 0;
1199 	boolean_t skipaclchk = (flags & ATTR_NOACLCHECK) ? B_TRUE : B_FALSE;
1200 
1201 	if (mask & AT_SIZE) {
1202 		if (vp->v_type == VDIR) {
1203 			error = EISDIR;
1204 			goto out;
1205 		}
1206 
1207 		/*
1208 		 * If ATTR_NOACLCHECK is set in the flags, then we don't
1209 		 * perform the secondary unlocked_access() call since the
1210 		 * ACL (if any) is being checked there.
1211 		 */
1212 		if (skipaclchk == B_FALSE) {
1213 			error = unlocked_access(node, VWRITE, cr);
1214 			if (error)
1215 				goto out;
1216 		}
1217 	}
1218 	if (mask & AT_MODE) {
1219 		/*
1220 		 * If not the owner of the file then check privilege
1221 		 * for two things: the privilege to set the mode at all
1222 		 * and, if we're setting setuid, we also need permissions
1223 		 * to add the set-uid bit, if we're not the owner.
1224 		 * In the specific case of creating a set-uid root
1225 		 * file, we need even more permissions.
1226 		 */
1227 		if ((error = secpolicy_vnode_setdac(cr, ovap->va_uid)) != 0)
1228 			goto out;
1229 
1230 		if ((error = secpolicy_setid_setsticky_clear(vp, vap,
1231 		    ovap, cr)) != 0)
1232 			goto out;
1233 	} else
1234 		vap->va_mode = ovap->va_mode;
1235 
1236 	if (mask & (AT_UID|AT_GID)) {
1237 		boolean_t checkpriv = B_FALSE;
1238 
1239 		/*
1240 		 * Chowning files.
1241 		 *
1242 		 * If you are the file owner:
1243 		 *	chown to other uid		FILE_CHOWN_SELF
1244 		 *	chown to gid (non-member) 	FILE_CHOWN_SELF
1245 		 *	chown to gid (member) 		<none>
1246 		 *
1247 		 * Instead of PRIV_FILE_CHOWN_SELF, FILE_CHOWN is also
1248 		 * acceptable but the first one is reported when debugging.
1249 		 *
1250 		 * If you are not the file owner:
1251 		 *	chown from root			PRIV_FILE_CHOWN + zone
1252 		 *	chown from other to any		PRIV_FILE_CHOWN
1253 		 *
1254 		 */
1255 		if (cr->cr_uid != ovap->va_uid) {
1256 			checkpriv = B_TRUE;
1257 		} else {
1258 			if (((mask & AT_UID) && vap->va_uid != ovap->va_uid) ||
1259 			    ((mask & AT_GID) && vap->va_gid != ovap->va_gid &&
1260 			    !groupmember(vap->va_gid, cr))) {
1261 				checkpriv = B_TRUE;
1262 			}
1263 		}
1264 		/*
1265 		 * If necessary, check privilege to see if update can be done.
1266 		 */
1267 		if (checkpriv &&
1268 		    (error = secpolicy_vnode_chown(cr, ovap->va_uid)) != 0) {
1269 			goto out;
1270 		}
1271 
1272 		/*
1273 		 * If the file has either the set UID or set GID bits
1274 		 * set and the caller can set the bits, then leave them.
1275 		 */
1276 		secpolicy_setid_clear(vap, cr);
1277 	}
1278 	if (mask & (AT_ATIME|AT_MTIME)) {
1279 		/*
1280 		 * If not the file owner and not otherwise privileged,
1281 		 * always return an error when setting the
1282 		 * time other than the current (ATTR_UTIME flag set).
1283 		 * If setting the current time (ATTR_UTIME not set) then
1284 		 * unlocked_access will check permissions according to policy.
1285 		 */
1286 		if (cr->cr_uid != ovap->va_uid) {
1287 			if (flags & ATTR_UTIME)
1288 				error = secpolicy_vnode_utime_modify(cr);
1289 			else if (skipaclchk == B_FALSE) {
1290 				error = unlocked_access(node, VWRITE, cr);
1291 				if (error == EACCES &&
1292 				    secpolicy_vnode_utime_modify(cr) == 0)
1293 					error = 0;
1294 			}
1295 			if (error)
1296 				goto out;
1297 		}
1298 	}
1299 
1300 	/*
1301 	 * Check for optional attributes here by checking the following:
1302 	 */
1303 	if (mask & AT_XVATTR)
1304 		error = secpolicy_xvattr((xvattr_t *)vap, ovap->va_uid, cr,
1305 		    vp->v_type);
1306 out:
1307 	return (error);
1308 }
1309 
1310 /*
1311  * Name:	secpolicy_pcfs_modify_bootpartition()
1312  *
1313  * Normal:	verify that subject can modify a pcfs boot partition.
1314  *
1315  * Output:	EACCES - if privilege check failed.
1316  */
1317 /*ARGSUSED*/
1318 int
1319 secpolicy_pcfs_modify_bootpartition(const cred_t *cred)
1320 {
1321 	return (PRIV_POLICY(cred, PRIV_ALL, B_FALSE, EACCES,
1322 	    "modify pcfs boot partition"));
1323 }
1324 
1325 /*
1326  * System V IPC routines
1327  */
1328 int
1329 secpolicy_ipc_owner(const cred_t *cr, const struct kipc_perm *ip)
1330 {
1331 	if (crgetzoneid(cr) != ip->ipc_zoneid ||
1332 	    (cr->cr_uid != ip->ipc_uid && cr->cr_uid != ip->ipc_cuid)) {
1333 		boolean_t allzone = B_FALSE;
1334 		if (ip->ipc_uid == 0 || ip->ipc_cuid == 0)
1335 			allzone = B_TRUE;
1336 		return (PRIV_POLICY(cr, PRIV_IPC_OWNER, allzone, EPERM, NULL));
1337 	}
1338 	return (0);
1339 }
1340 
1341 int
1342 secpolicy_ipc_config(const cred_t *cr)
1343 {
1344 	return (PRIV_POLICY(cr, PRIV_SYS_IPC_CONFIG, B_FALSE, EPERM, NULL));
1345 }
1346 
1347 int
1348 secpolicy_ipc_access(const cred_t *cr, const struct kipc_perm *ip, mode_t mode)
1349 {
1350 
1351 	boolean_t allzone = B_FALSE;
1352 
1353 	ASSERT((mode & (MSG_R|MSG_W)) != 0);
1354 
1355 	if ((mode & MSG_R) &&
1356 	    PRIV_POLICY(cr, PRIV_IPC_DAC_READ, allzone, EACCES, NULL) != 0)
1357 		return (EACCES);
1358 
1359 	if (mode & MSG_W) {
1360 		if (cr->cr_uid != 0 && (ip->ipc_uid == 0 || ip->ipc_cuid == 0))
1361 			allzone = B_TRUE;
1362 
1363 		return (PRIV_POLICY(cr, PRIV_IPC_DAC_WRITE, allzone, EACCES,
1364 		    NULL));
1365 	}
1366 	return (0);
1367 }
1368 
1369 int
1370 secpolicy_rsm_access(const cred_t *cr, uid_t owner, mode_t mode)
1371 {
1372 	boolean_t allzone = B_FALSE;
1373 
1374 	ASSERT((mode & (MSG_R|MSG_W)) != 0);
1375 
1376 	if ((mode & MSG_R) &&
1377 	    PRIV_POLICY(cr, PRIV_IPC_DAC_READ, allzone, EACCES, NULL) != 0)
1378 		return (EACCES);
1379 
1380 	if (mode & MSG_W) {
1381 		if (cr->cr_uid != 0 && owner == 0)
1382 			allzone = B_TRUE;
1383 
1384 		return (PRIV_POLICY(cr, PRIV_IPC_DAC_WRITE, allzone, EACCES,
1385 		    NULL));
1386 	}
1387 	return (0);
1388 }
1389 
1390 /*
1391  * Audit configuration.
1392  */
1393 int
1394 secpolicy_audit_config(const cred_t *cr)
1395 {
1396 	return (PRIV_POLICY(cr, PRIV_SYS_AUDIT, B_FALSE, EPERM, NULL));
1397 }
1398 
1399 /*
1400  * Audit record generation.
1401  */
1402 int
1403 secpolicy_audit_modify(const cred_t *cr)
1404 {
1405 	return (PRIV_POLICY(cr, PRIV_PROC_AUDIT, B_FALSE, EPERM, NULL));
1406 }
1407 
1408 /*
1409  * Get audit attributes.
1410  * Either PRIV_SYS_AUDIT or PRIV_PROC_AUDIT required; report the
1411  * "Least" of the two privileges on error.
1412  */
1413 int
1414 secpolicy_audit_getattr(const cred_t *cr)
1415 {
1416 	if (!PRIV_POLICY_ONLY(cr, PRIV_SYS_AUDIT, B_FALSE)) {
1417 		return (PRIV_POLICY(cr, PRIV_PROC_AUDIT, B_FALSE, EPERM,
1418 		    NULL));
1419 	} else {
1420 		return (PRIV_POLICY(cr, PRIV_SYS_AUDIT, B_FALSE, EPERM, NULL));
1421 	}
1422 }
1423 
1424 
1425 /*
1426  * Locking physical memory
1427  */
1428 int
1429 secpolicy_lock_memory(const cred_t *cr)
1430 {
1431 	return (PRIV_POLICY(cr, PRIV_PROC_LOCK_MEMORY, B_FALSE, EPERM, NULL));
1432 }
1433 
1434 /*
1435  * Accounting (both acct(2) and exacct).
1436  */
1437 int
1438 secpolicy_acct(const cred_t *cr)
1439 {
1440 	return (PRIV_POLICY(cr, PRIV_SYS_ACCT, B_FALSE, EPERM, NULL));
1441 }
1442 
1443 /*
1444  * Is this process privileged to change its uids at will?
1445  * Uid 0 is still considered "special" and having the SETID
1446  * privilege is not sufficient to get uid 0.
1447  * Files are owned by root, so the privilege would give
1448  * full access and euid 0 is still effective.
1449  *
1450  * If you have the privilege and euid 0 only then do you
1451  * get the powers of root wrt uid 0.
1452  *
1453  * For gid manipulations, this is should be called with an
1454  * uid of -1.
1455  *
1456  */
1457 int
1458 secpolicy_allow_setid(const cred_t *cr, uid_t newuid, boolean_t checkonly)
1459 {
1460 	boolean_t allzone = B_FALSE;
1461 
1462 	if (newuid == 0 && cr->cr_uid != 0 && cr->cr_suid != 0 &&
1463 	    cr->cr_ruid != 0) {
1464 		allzone = B_TRUE;
1465 	}
1466 
1467 	return (checkonly ? !PRIV_POLICY_ONLY(cr, PRIV_PROC_SETID, allzone) :
1468 	    PRIV_POLICY(cr, PRIV_PROC_SETID, allzone, EPERM, NULL));
1469 }
1470 
1471 
1472 /*
1473  * Acting on a different process: if the mode is for writing,
1474  * the restrictions are more severe.  This is called after
1475  * we've verified that the uids do not match.
1476  */
1477 int
1478 secpolicy_proc_owner(const cred_t *scr, const cred_t *tcr, int mode)
1479 {
1480 	boolean_t allzone = B_FALSE;
1481 
1482 	if ((mode & VWRITE) && scr->cr_uid != 0 &&
1483 	    (tcr->cr_uid == 0 || tcr->cr_ruid == 0 || tcr->cr_suid == 0))
1484 		allzone = B_TRUE;
1485 
1486 	return (PRIV_POLICY(scr, PRIV_PROC_OWNER, allzone, EPERM, NULL));
1487 }
1488 
1489 int
1490 secpolicy_proc_access(const cred_t *scr)
1491 {
1492 	return (PRIV_POLICY(scr, PRIV_PROC_OWNER, B_FALSE, EACCES, NULL));
1493 }
1494 
1495 int
1496 secpolicy_proc_excl_open(const cred_t *scr)
1497 {
1498 	return (PRIV_POLICY(scr, PRIV_PROC_OWNER, B_FALSE, EBUSY, NULL));
1499 }
1500 
1501 int
1502 secpolicy_proc_zone(const cred_t *scr)
1503 {
1504 	return (PRIV_POLICY(scr, PRIV_PROC_ZONE, B_FALSE, EPERM, NULL));
1505 }
1506 
1507 /*
1508  * Destroying the system
1509  */
1510 
1511 int
1512 secpolicy_kmdb(const cred_t *scr)
1513 {
1514 	return (PRIV_POLICY(scr, PRIV_ALL, B_FALSE, EPERM, NULL));
1515 }
1516 
1517 int
1518 secpolicy_error_inject(const cred_t *scr)
1519 {
1520 	return (PRIV_POLICY(scr, PRIV_ALL, B_FALSE, EPERM, NULL));
1521 }
1522 
1523 /*
1524  * Processor sets, cpu configuration, resource pools.
1525  */
1526 int
1527 secpolicy_pset(const cred_t *cr)
1528 {
1529 	return (PRIV_POLICY(cr, PRIV_SYS_RES_CONFIG, B_FALSE, EPERM, NULL));
1530 }
1531 
1532 int
1533 secpolicy_ponline(const cred_t *cr)
1534 {
1535 	return (PRIV_POLICY(cr, PRIV_SYS_RES_CONFIG, B_FALSE, EPERM, NULL));
1536 }
1537 
1538 int
1539 secpolicy_pool(const cred_t *cr)
1540 {
1541 	return (PRIV_POLICY(cr, PRIV_SYS_RES_CONFIG, B_FALSE, EPERM, NULL));
1542 }
1543 
1544 int
1545 secpolicy_blacklist(const cred_t *cr)
1546 {
1547 	return (PRIV_POLICY(cr, PRIV_SYS_RES_CONFIG, B_FALSE, EPERM, NULL));
1548 }
1549 
1550 /*
1551  * Catch all system configuration.
1552  */
1553 int
1554 secpolicy_sys_config(const cred_t *cr, boolean_t checkonly)
1555 {
1556 	if (checkonly) {
1557 		return (PRIV_POLICY_ONLY(cr, PRIV_SYS_CONFIG, B_FALSE) ? 0 :
1558 		    EPERM);
1559 	} else {
1560 		return (PRIV_POLICY(cr, PRIV_SYS_CONFIG, B_FALSE, EPERM, NULL));
1561 	}
1562 }
1563 
1564 /*
1565  * Zone administration (halt, reboot, etc.) from within zone.
1566  */
1567 int
1568 secpolicy_zone_admin(const cred_t *cr, boolean_t checkonly)
1569 {
1570 	if (checkonly) {
1571 		return (PRIV_POLICY_ONLY(cr, PRIV_SYS_ADMIN, B_FALSE) ? 0 :
1572 		    EPERM);
1573 	} else {
1574 		return (PRIV_POLICY(cr, PRIV_SYS_ADMIN, B_FALSE, EPERM,
1575 		    NULL));
1576 	}
1577 }
1578 
1579 /*
1580  * Zone configuration (create, halt, enter).
1581  */
1582 int
1583 secpolicy_zone_config(const cred_t *cr)
1584 {
1585 	/*
1586 	 * Require all privileges to avoid possibility of privilege
1587 	 * escalation.
1588 	 */
1589 	return (secpolicy_require_set(cr, PRIV_FULLSET, NULL));
1590 }
1591 
1592 /*
1593  * Various other system configuration calls
1594  */
1595 int
1596 secpolicy_coreadm(const cred_t *cr)
1597 {
1598 	return (PRIV_POLICY(cr, PRIV_SYS_ADMIN, B_FALSE, EPERM, NULL));
1599 }
1600 
1601 int
1602 secpolicy_systeminfo(const cred_t *cr)
1603 {
1604 	return (PRIV_POLICY(cr, PRIV_SYS_ADMIN, B_FALSE, EPERM, NULL));
1605 }
1606 
1607 int
1608 secpolicy_dispadm(const cred_t *cr)
1609 {
1610 	return (PRIV_POLICY(cr, PRIV_SYS_CONFIG, B_FALSE, EPERM, NULL));
1611 }
1612 
1613 int
1614 secpolicy_settime(const cred_t *cr)
1615 {
1616 	return (PRIV_POLICY(cr, PRIV_SYS_TIME, B_FALSE, EPERM, NULL));
1617 }
1618 
1619 /*
1620  * For realtime users: high resolution clock.
1621  */
1622 int
1623 secpolicy_clock_highres(const cred_t *cr)
1624 {
1625 	return (PRIV_POLICY(cr, PRIV_PROC_CLOCK_HIGHRES, B_FALSE, EPERM,
1626 	    NULL));
1627 }
1628 
1629 /*
1630  * drv_priv() is documented as callable from interrupt context, not that
1631  * anyone ever does, but still.  No debugging or auditing can be done when
1632  * it is called from interrupt context.
1633  * returns 0 on succes, EPERM on failure.
1634  */
1635 int
1636 drv_priv(cred_t *cr)
1637 {
1638 	return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EPERM, NULL));
1639 }
1640 
1641 int
1642 secpolicy_sys_devices(const cred_t *cr)
1643 {
1644 	return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EPERM, NULL));
1645 }
1646 
1647 int
1648 secpolicy_excl_open(const cred_t *cr)
1649 {
1650 	return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EBUSY, NULL));
1651 }
1652 
1653 int
1654 secpolicy_rctlsys(const cred_t *cr, boolean_t is_zone_rctl)
1655 {
1656 	/* zone.* rctls can only be set from the global zone */
1657 	if (is_zone_rctl && priv_policy_global(cr) != 0)
1658 		return (EPERM);
1659 	return (PRIV_POLICY(cr, PRIV_SYS_RESOURCE, B_FALSE, EPERM, NULL));
1660 }
1661 
1662 int
1663 secpolicy_resource(const cred_t *cr)
1664 {
1665 	return (PRIV_POLICY(cr, PRIV_SYS_RESOURCE, B_FALSE, EPERM, NULL));
1666 }
1667 
1668 int
1669 secpolicy_resource_anon_mem(const cred_t *cr)
1670 {
1671 	return (PRIV_POLICY_ONLY(cr, PRIV_SYS_RESOURCE, B_FALSE));
1672 }
1673 
1674 /*
1675  * Processes with a real uid of 0 escape any form of accounting, much
1676  * like before.
1677  */
1678 int
1679 secpolicy_newproc(const cred_t *cr)
1680 {
1681 	if (cr->cr_ruid == 0)
1682 		return (0);
1683 
1684 	return (PRIV_POLICY(cr, PRIV_SYS_RESOURCE, B_FALSE, EPERM, NULL));
1685 }
1686 
1687 /*
1688  * Networking
1689  */
1690 int
1691 secpolicy_net_rawaccess(const cred_t *cr)
1692 {
1693 	return (PRIV_POLICY(cr, PRIV_NET_RAWACCESS, B_FALSE, EACCES, NULL));
1694 }
1695 
1696 int
1697 secpolicy_net_observability(const cred_t *cr)
1698 {
1699 	return (PRIV_POLICY(cr, PRIV_NET_OBSERVABILITY, B_FALSE, EACCES, NULL));
1700 }
1701 
1702 /*
1703  * Need this privilege for accessing the ICMP device
1704  */
1705 int
1706 secpolicy_net_icmpaccess(const cred_t *cr)
1707 {
1708 	return (PRIV_POLICY(cr, PRIV_NET_ICMPACCESS, B_FALSE, EACCES, NULL));
1709 }
1710 
1711 /*
1712  * There are a few rare cases where the kernel generates ioctls() from
1713  * interrupt context with a credential of kcred rather than NULL.
1714  * In those cases, we take the safe and cheap test.
1715  */
1716 int
1717 secpolicy_net_config(const cred_t *cr, boolean_t checkonly)
1718 {
1719 	if (checkonly) {
1720 		return (PRIV_POLICY_ONLY(cr, PRIV_SYS_NET_CONFIG, B_FALSE) ?
1721 		    0 : EPERM);
1722 	} else {
1723 		return (PRIV_POLICY(cr, PRIV_SYS_NET_CONFIG, B_FALSE, EPERM,
1724 		    NULL));
1725 	}
1726 }
1727 
1728 
1729 /*
1730  * PRIV_SYS_NET_CONFIG is a superset of PRIV_SYS_IP_CONFIG.
1731  *
1732  * There are a few rare cases where the kernel generates ioctls() from
1733  * interrupt context with a credential of kcred rather than NULL.
1734  * In those cases, we take the safe and cheap test.
1735  */
1736 int
1737 secpolicy_ip_config(const cred_t *cr, boolean_t checkonly)
1738 {
1739 	if (PRIV_POLICY_ONLY(cr, PRIV_SYS_NET_CONFIG, B_FALSE))
1740 		return (secpolicy_net_config(cr, checkonly));
1741 
1742 	if (checkonly) {
1743 		return (PRIV_POLICY_ONLY(cr, PRIV_SYS_IP_CONFIG, B_FALSE) ?
1744 		    0 : EPERM);
1745 	} else {
1746 		return (PRIV_POLICY(cr, PRIV_SYS_IP_CONFIG, B_FALSE, EPERM,
1747 		    NULL));
1748 	}
1749 }
1750 
1751 /*
1752  * PRIV_SYS_NET_CONFIG is a superset of PRIV_SYS_DL_CONFIG.
1753  */
1754 int
1755 secpolicy_dl_config(const cred_t *cr)
1756 {
1757 	if (PRIV_POLICY_ONLY(cr, PRIV_SYS_NET_CONFIG, B_FALSE))
1758 		return (secpolicy_net_config(cr, B_FALSE));
1759 	return (PRIV_POLICY(cr, PRIV_SYS_DL_CONFIG, B_FALSE, EPERM, NULL));
1760 }
1761 
1762 /*
1763  * PRIV_SYS_DL_CONFIG is a superset of PRIV_SYS_IPTUN_CONFIG.
1764  */
1765 int
1766 secpolicy_iptun_config(const cred_t *cr)
1767 {
1768 	if (PRIV_POLICY_ONLY(cr, PRIV_SYS_NET_CONFIG, B_FALSE))
1769 		return (secpolicy_net_config(cr, B_FALSE));
1770 	if (PRIV_POLICY_ONLY(cr, PRIV_SYS_DL_CONFIG, B_FALSE))
1771 		return (secpolicy_dl_config(cr));
1772 	return (PRIV_POLICY(cr, PRIV_SYS_IPTUN_CONFIG, B_FALSE, EPERM, NULL));
1773 }
1774 
1775 /*
1776  * Map IP pseudo privileges to actual privileges.
1777  * So we don't need to recompile IP when we change the privileges.
1778  */
1779 int
1780 secpolicy_ip(const cred_t *cr, int netpriv, boolean_t checkonly)
1781 {
1782 	int priv = PRIV_ALL;
1783 
1784 	switch (netpriv) {
1785 	case OP_CONFIG:
1786 		priv = PRIV_SYS_IP_CONFIG;
1787 		break;
1788 	case OP_RAW:
1789 		priv = PRIV_NET_RAWACCESS;
1790 		break;
1791 	case OP_PRIVPORT:
1792 		priv = PRIV_NET_PRIVADDR;
1793 		break;
1794 	}
1795 	ASSERT(priv != PRIV_ALL);
1796 	if (checkonly)
1797 		return (PRIV_POLICY_ONLY(cr, priv, B_FALSE) ? 0 : EPERM);
1798 	else
1799 		return (PRIV_POLICY(cr, priv, B_FALSE, EPERM, NULL));
1800 }
1801 
1802 /*
1803  * Map network pseudo privileges to actual privileges.
1804  * So we don't need to recompile IP when we change the privileges.
1805  */
1806 int
1807 secpolicy_net(const cred_t *cr, int netpriv, boolean_t checkonly)
1808 {
1809 	int priv = PRIV_ALL;
1810 
1811 	switch (netpriv) {
1812 	case OP_CONFIG:
1813 		priv = PRIV_SYS_NET_CONFIG;
1814 		break;
1815 	case OP_RAW:
1816 		priv = PRIV_NET_RAWACCESS;
1817 		break;
1818 	case OP_PRIVPORT:
1819 		priv = PRIV_NET_PRIVADDR;
1820 		break;
1821 	}
1822 	ASSERT(priv != PRIV_ALL);
1823 	if (checkonly)
1824 		return (PRIV_POLICY_ONLY(cr, priv, B_FALSE) ? 0 : EPERM);
1825 	else
1826 		return (PRIV_POLICY(cr, priv, B_FALSE, EPERM, NULL));
1827 }
1828 
1829 /*
1830  * Checks for operations that are either client-only or are used by
1831  * both clients and servers.
1832  */
1833 int
1834 secpolicy_nfs(const cred_t *cr)
1835 {
1836 	return (PRIV_POLICY(cr, PRIV_SYS_NFS, B_FALSE, EPERM, NULL));
1837 }
1838 
1839 /*
1840  * Special case for opening rpcmod: have NFS privileges or network
1841  * config privileges.
1842  */
1843 int
1844 secpolicy_rpcmod_open(const cred_t *cr)
1845 {
1846 	if (PRIV_POLICY_ONLY(cr, PRIV_SYS_NFS, B_FALSE))
1847 		return (secpolicy_nfs(cr));
1848 	else
1849 		return (secpolicy_net_config(cr, NULL));
1850 }
1851 
1852 int
1853 secpolicy_chroot(const cred_t *cr)
1854 {
1855 	return (PRIV_POLICY(cr, PRIV_PROC_CHROOT, B_FALSE, EPERM, NULL));
1856 }
1857 
1858 int
1859 secpolicy_tasksys(const cred_t *cr)
1860 {
1861 	return (PRIV_POLICY(cr, PRIV_PROC_TASKID, B_FALSE, EPERM, NULL));
1862 }
1863 
1864 /*
1865  * Basic privilege checks.
1866  */
1867 int
1868 secpolicy_basic_exec(const cred_t *cr, vnode_t *vp)
1869 {
1870 	return (priv_policy_va(cr, PRIV_PROC_EXEC, B_FALSE, EPERM, NULL,
1871 	    KLPDARG_VNODE, vp, (char *)NULL, KLPDARG_NOMORE));
1872 }
1873 
1874 int
1875 secpolicy_basic_fork(const cred_t *cr)
1876 {
1877 	return (PRIV_POLICY(cr, PRIV_PROC_FORK, B_FALSE, EPERM, NULL));
1878 }
1879 
1880 int
1881 secpolicy_basic_proc(const cred_t *cr)
1882 {
1883 	return (PRIV_POLICY(cr, PRIV_PROC_SESSION, B_FALSE, EPERM, NULL));
1884 }
1885 
1886 /*
1887  * Slightly complicated because we don't want to trigger the policy too
1888  * often.  First we shortcircuit access to "self" (tp == sp) or if
1889  * we don't have the privilege but if we have permission
1890  * just return (0) and we don't flag the privilege as needed.
1891  * Else, we test for the privilege because we either have it or need it.
1892  */
1893 int
1894 secpolicy_basic_procinfo(const cred_t *cr, proc_t *tp, proc_t *sp)
1895 {
1896 	if (tp == sp ||
1897 	    !HAS_PRIVILEGE(cr, PRIV_PROC_INFO) && prochasprocperm(tp, sp, cr)) {
1898 		return (0);
1899 	} else {
1900 		return (PRIV_POLICY(cr, PRIV_PROC_INFO, B_FALSE, EPERM, NULL));
1901 	}
1902 }
1903 
1904 int
1905 secpolicy_basic_link(const cred_t *cr)
1906 {
1907 	return (PRIV_POLICY(cr, PRIV_FILE_LINK_ANY, B_FALSE, EPERM, NULL));
1908 }
1909 
1910 int
1911 secpolicy_basic_net_access(const cred_t *cr)
1912 {
1913 	return (PRIV_POLICY(cr, PRIV_NET_ACCESS, B_FALSE, EACCES, NULL));
1914 }
1915 
1916 /*
1917  * Additional device protection.
1918  *
1919  * Traditionally, a device has specific permissions on the node in
1920  * the filesystem which govern which devices can be opened by what
1921  * processes.  In certain cases, it is desirable to add extra
1922  * restrictions, as writing to certain devices is identical to
1923  * having a complete run of the system.
1924  *
1925  * This mechanism is called the device policy.
1926  *
1927  * When a device is opened, its policy entry is looked up in the
1928  * policy cache and checked.
1929  */
1930 int
1931 secpolicy_spec_open(const cred_t *cr, struct vnode *vp, int oflag)
1932 {
1933 	devplcy_t *plcy;
1934 	int err;
1935 	struct snode *csp = VTOS(common_specvp(vp));
1936 	priv_set_t pset;
1937 
1938 	mutex_enter(&csp->s_lock);
1939 
1940 	if (csp->s_plcy == NULL || csp->s_plcy->dp_gen != devplcy_gen) {
1941 		plcy = devpolicy_find(vp);
1942 		if (csp->s_plcy)
1943 			dpfree(csp->s_plcy);
1944 		csp->s_plcy = plcy;
1945 		ASSERT(plcy != NULL);
1946 	} else
1947 		plcy = csp->s_plcy;
1948 
1949 	if (plcy == nullpolicy) {
1950 		mutex_exit(&csp->s_lock);
1951 		return (0);
1952 	}
1953 
1954 	dphold(plcy);
1955 
1956 	mutex_exit(&csp->s_lock);
1957 
1958 	if (oflag & FWRITE)
1959 		pset = plcy->dp_wrp;
1960 	else
1961 		pset = plcy->dp_rdp;
1962 	/*
1963 	 * Special case:
1964 	 * PRIV_SYS_NET_CONFIG is a superset of PRIV_SYS_IP_CONFIG.
1965 	 * If PRIV_SYS_NET_CONFIG is present and PRIV_SYS_IP_CONFIG is
1966 	 * required, replace PRIV_SYS_IP_CONFIG with PRIV_SYS_NET_CONFIG
1967 	 * in the required privilege set before doing the check.
1968 	 */
1969 	if (priv_ismember(&pset, PRIV_SYS_IP_CONFIG) &&
1970 	    priv_ismember(&CR_OEPRIV(cr), PRIV_SYS_NET_CONFIG) &&
1971 	    !priv_ismember(&CR_OEPRIV(cr), PRIV_SYS_IP_CONFIG)) {
1972 		priv_delset(&pset, PRIV_SYS_IP_CONFIG);
1973 		priv_addset(&pset, PRIV_SYS_NET_CONFIG);
1974 	}
1975 
1976 	err = secpolicy_require_set(cr, &pset, "devpolicy");
1977 	dpfree(plcy);
1978 
1979 	return (err);
1980 }
1981 
1982 int
1983 secpolicy_modctl(const cred_t *cr, int cmd)
1984 {
1985 	switch (cmd) {
1986 	case MODINFO:
1987 	case MODGETMAJBIND:
1988 	case MODGETPATH:
1989 	case MODGETPATHLEN:
1990 	case MODGETNAME:
1991 	case MODGETFBNAME:
1992 	case MODGETDEVPOLICY:
1993 	case MODGETDEVPOLICYBYNAME:
1994 	case MODDEVT2INSTANCE:
1995 	case MODSIZEOF_DEVID:
1996 	case MODGETDEVID:
1997 	case MODSIZEOF_MINORNAME:
1998 	case MODGETMINORNAME:
1999 	case MODGETDEVFSPATH_LEN:
2000 	case MODGETDEVFSPATH:
2001 	case MODGETDEVFSPATH_MI_LEN:
2002 	case MODGETDEVFSPATH_MI:
2003 		/* Unprivileged */
2004 		return (0);
2005 	case MODLOAD:
2006 	case MODSETDEVPOLICY:
2007 		return (secpolicy_require_set(cr, PRIV_FULLSET, NULL));
2008 	default:
2009 		return (secpolicy_sys_config(cr, B_FALSE));
2010 	}
2011 }
2012 
2013 int
2014 secpolicy_console(const cred_t *cr)
2015 {
2016 	return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EPERM, NULL));
2017 }
2018 
2019 int
2020 secpolicy_power_mgmt(const cred_t *cr)
2021 {
2022 	return (PRIV_POLICY(cr, PRIV_SYS_DEVICES, B_FALSE, EPERM, NULL));
2023 }
2024 
2025 /*
2026  * Simulate terminal input; another escalation of privileges avenue.
2027  */
2028 
2029 int
2030 secpolicy_sti(const cred_t *cr)
2031 {
2032 	return (secpolicy_require_set(cr, PRIV_FULLSET, NULL));
2033 }
2034 
2035 boolean_t
2036 secpolicy_net_reply_equal(const cred_t *cr)
2037 {
2038 	return (PRIV_POLICY(cr, PRIV_SYS_CONFIG, B_FALSE, EPERM, NULL));
2039 }
2040 
2041 int
2042 secpolicy_swapctl(const cred_t *cr)
2043 {
2044 	return (PRIV_POLICY(cr, PRIV_SYS_CONFIG, B_FALSE, EPERM, NULL));
2045 }
2046 
2047 int
2048 secpolicy_cpc_cpu(const cred_t *cr)
2049 {
2050 	return (PRIV_POLICY(cr, PRIV_CPC_CPU, B_FALSE, EACCES, NULL));
2051 }
2052 
2053 /*
2054  * secpolicy_contract_identity
2055  *
2056  * Determine if the subject may set the process contract FMRI value
2057  */
2058 int
2059 secpolicy_contract_identity(const cred_t *cr)
2060 {
2061 	return (PRIV_POLICY(cr, PRIV_CONTRACT_IDENTITY, B_FALSE, EPERM, NULL));
2062 }
2063 
2064 /*
2065  * secpolicy_contract_observer
2066  *
2067  * Determine if the subject may observe a specific contract's events.
2068  */
2069 int
2070 secpolicy_contract_observer(const cred_t *cr, struct contract *ct)
2071 {
2072 	if (contract_owned(ct, cr, B_FALSE))
2073 		return (0);
2074 	return (PRIV_POLICY(cr, PRIV_CONTRACT_OBSERVER, B_FALSE, EPERM, NULL));
2075 }
2076 
2077 /*
2078  * secpolicy_contract_observer_choice
2079  *
2080  * Determine if the subject may observe any contract's events.  Just
2081  * tests privilege and audits on success.
2082  */
2083 boolean_t
2084 secpolicy_contract_observer_choice(const cred_t *cr)
2085 {
2086 	return (PRIV_POLICY_CHOICE(cr, PRIV_CONTRACT_OBSERVER, B_FALSE));
2087 }
2088 
2089 /*
2090  * secpolicy_contract_event
2091  *
2092  * Determine if the subject may request critical contract events or
2093  * reliable contract event delivery.
2094  */
2095 int
2096 secpolicy_contract_event(const cred_t *cr)
2097 {
2098 	return (PRIV_POLICY(cr, PRIV_CONTRACT_EVENT, B_FALSE, EPERM, NULL));
2099 }
2100 
2101 /*
2102  * secpolicy_contract_event_choice
2103  *
2104  * Determine if the subject may retain contract events in its critical
2105  * set when a change in other terms would normally require a change in
2106  * the critical set.  Just tests privilege and audits on success.
2107  */
2108 boolean_t
2109 secpolicy_contract_event_choice(const cred_t *cr)
2110 {
2111 	return (PRIV_POLICY_CHOICE(cr, PRIV_CONTRACT_EVENT, B_FALSE));
2112 }
2113 
2114 /*
2115  * secpolicy_gart_access
2116  *
2117  * Determine if the subject has sufficient priveleges to make ioctls to agpgart
2118  * device.
2119  */
2120 int
2121 secpolicy_gart_access(const cred_t *cr)
2122 {
2123 	return (PRIV_POLICY(cr, PRIV_GRAPHICS_ACCESS, B_FALSE, EPERM, NULL));
2124 }
2125 
2126 /*
2127  * secpolicy_gart_map
2128  *
2129  * Determine if the subject has sufficient priveleges to map aperture range
2130  * through agpgart driver.
2131  */
2132 int
2133 secpolicy_gart_map(const cred_t *cr)
2134 {
2135 	if (PRIV_POLICY_ONLY(cr, PRIV_GRAPHICS_ACCESS, B_FALSE)) {
2136 		return (PRIV_POLICY(cr, PRIV_GRAPHICS_ACCESS, B_FALSE, EPERM,
2137 		    NULL));
2138 	} else {
2139 		return (PRIV_POLICY(cr, PRIV_GRAPHICS_MAP, B_FALSE, EPERM,
2140 		    NULL));
2141 	}
2142 }
2143 
2144 /*
2145  * secpolicy_zinject
2146  *
2147  * Determine if the subject can inject faults in the ZFS fault injection
2148  * framework.  Requires all privileges.
2149  */
2150 int
2151 secpolicy_zinject(const cred_t *cr)
2152 {
2153 	return (secpolicy_require_set(cr, PRIV_FULLSET, NULL));
2154 }
2155 
2156 /*
2157  * secpolicy_zfs
2158  *
2159  * Determine if the subject has permission to manipulate ZFS datasets
2160  * (not pools).  Equivalent to the SYS_MOUNT privilege.
2161  */
2162 int
2163 secpolicy_zfs(const cred_t *cr)
2164 {
2165 	return (PRIV_POLICY(cr, PRIV_SYS_MOUNT, B_FALSE, EPERM, NULL));
2166 }
2167 
2168 /*
2169  * secpolicy_idmap
2170  *
2171  * Determine if the calling process has permissions to register an SID
2172  * mapping daemon and allocate ephemeral IDs.
2173  */
2174 int
2175 secpolicy_idmap(const cred_t *cr)
2176 {
2177 	return (PRIV_POLICY(cr, PRIV_FILE_SETID, B_TRUE, EPERM, NULL));
2178 }
2179 
2180 /*
2181  * secpolicy_ucode_update
2182  *
2183  * Determine if the subject has sufficient privilege to update microcode.
2184  */
2185 int
2186 secpolicy_ucode_update(const cred_t *scr)
2187 {
2188 	return (PRIV_POLICY(scr, PRIV_ALL, B_FALSE, EPERM, NULL));
2189 }
2190 
2191 /*
2192  * secpolicy_sadopen
2193  *
2194  * Determine if the subject has sufficient privilege to access /dev/sad/admin.
2195  * /dev/sad/admin appear in global zone and exclusive-IP zones only.
2196  * In global zone, sys_config is required.
2197  * In exclusive-IP zones, sys_ip_config is required.
2198  * Note that sys_config is prohibited in non-global zones.
2199  */
2200 int
2201 secpolicy_sadopen(const cred_t *credp)
2202 {
2203 	priv_set_t pset;
2204 
2205 	priv_emptyset(&pset);
2206 
2207 	if (crgetzoneid(credp) == GLOBAL_ZONEID)
2208 		priv_addset(&pset, PRIV_SYS_CONFIG);
2209 	else
2210 		priv_addset(&pset, PRIV_SYS_IP_CONFIG);
2211 
2212 	return (secpolicy_require_set(credp, &pset, "devpolicy"));
2213 }
2214 
2215 
2216 /*
2217  * Add privileges to a particular privilege set; this is called when the
2218  * current sets of privileges are not sufficient.  I.e., we should always
2219  * call the policy override functions from here.
2220  * What we are allowed to have is in the Observed Permitted set; so
2221  * we compute the difference between that and the newset.
2222  */
2223 int
2224 secpolicy_require_privs(const cred_t *cr, const priv_set_t *nset)
2225 {
2226 	priv_set_t rqd;
2227 
2228 	rqd = CR_OPPRIV(cr);
2229 
2230 	priv_inverse(&rqd);
2231 	priv_intersect(nset, &rqd);
2232 
2233 	return (secpolicy_require_set(cr, &rqd, NULL));
2234 }
2235 
2236 /*
2237  * secpolicy_smb
2238  *
2239  * Determine if the cred_t has PRIV_SYS_SMB privilege, indicating
2240  * that it has permission to access the smbsrv kernel driver.
2241  * PRIV_POLICY checks the privilege and audits the check.
2242  *
2243  * Returns:
2244  * 0       Driver access is allowed.
2245  * EPERM   Driver access is NOT permitted.
2246  */
2247 int
2248 secpolicy_smb(const cred_t *cr)
2249 {
2250 	return (PRIV_POLICY(cr, PRIV_SYS_SMB, B_FALSE, EPERM, NULL));
2251 }
2252 
2253 /*
2254  * secpolicy_vscan
2255  *
2256  * Determine if cred_t has the necessary privileges to access a file
2257  * for virus scanning and update its extended system attributes.
2258  * PRIV_FILE_DAC_SEARCH, PRIV_FILE_DAC_READ - file access
2259  * PRIV_FILE_FLAG_SET - set extended system attributes
2260  *
2261  * PRIV_POLICY checks the privilege and audits the check.
2262  *
2263  * Returns:
2264  * 0      file access for virus scanning allowed.
2265  * EPERM  file access for virus scanning is NOT permitted.
2266  */
2267 int
2268 secpolicy_vscan(const cred_t *cr)
2269 {
2270 	if ((PRIV_POLICY(cr, PRIV_FILE_DAC_SEARCH, B_FALSE, EPERM, NULL)) ||
2271 	    (PRIV_POLICY(cr, PRIV_FILE_DAC_READ, B_FALSE, EPERM, NULL)) ||
2272 	    (PRIV_POLICY(cr, PRIV_FILE_FLAG_SET, B_FALSE, EPERM, NULL))) {
2273 		return (EPERM);
2274 	}
2275 
2276 	return (0);
2277 }
2278 
2279 /*
2280  * secpolicy_smbfs_login
2281  *
2282  * Determines if the caller can add and delete the smbfs login
2283  * password in the the nsmb kernel module for the CIFS client.
2284  *
2285  * Returns:
2286  * 0       access is allowed.
2287  * EPERM   access is NOT allowed.
2288  */
2289 int
2290 secpolicy_smbfs_login(const cred_t *cr, uid_t uid)
2291 {
2292 	uid_t cruid = crgetruid(cr);
2293 
2294 	if (cruid == uid)
2295 		return (0);
2296 	return (PRIV_POLICY(cr, PRIV_PROC_OWNER, B_FALSE,
2297 	    EPERM, NULL));
2298 }
2299 
2300 /*
2301  * secpolicy_xvm_control
2302  *
2303  * Determines if a caller can control the xVM hypervisor and/or running
2304  * domains (x86 specific).
2305  *
2306  * Returns:
2307  * 0       access is allowed.
2308  * EPERM   access is NOT allowed.
2309  */
2310 int
2311 secpolicy_xvm_control(const cred_t *cr)
2312 {
2313 	if (PRIV_POLICY(cr, PRIV_XVM_CONTROL, B_FALSE, EPERM, NULL))
2314 		return (EPERM);
2315 	return (0);
2316 }
2317 
2318 /*
2319  * secpolicy_ppp_config
2320  *
2321  * Determine if the subject has sufficient privileges to configure PPP and
2322  * PPP-related devices.
2323  */
2324 int
2325 secpolicy_ppp_config(const cred_t *cr)
2326 {
2327 	if (PRIV_POLICY_ONLY(cr, PRIV_SYS_NET_CONFIG, B_FALSE))
2328 		return (secpolicy_net_config(cr, B_FALSE));
2329 	return (PRIV_POLICY(cr, PRIV_SYS_PPP_CONFIG, B_FALSE, EPERM, NULL));
2330 }
2331