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.
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.
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]
22 * Copyright 2010 Sun Microsystems, Inc. All rights reserved.
23 * Use is subject to license terms.
27 * Privilege implementation.
29 * This file provides the infrastructure for privilege sets and limits
30 * the number of files that requires to include <sys/cred_impl.h> and/or
33 * The Solaris privilege mechanism has been designed in a
34 * future proof manner. While the kernel may use fixed size arrays
35 * and fixed bitmasks and bit values, the representation of those
36 * is kernel private. All external interfaces as well as K-to-K interfaces
37 * have been constructed in a manner to provide the maximum flexibility.
39 * There can be X privilege sets each containing Y 32 bit words.
40 * <X, Y> are constant for a kernel invocation.
42 * As a consequence, all privilege set manipulation happens in functions
47 #include <sys/systm.h>
50 #include <sys/sunddi.h>
51 #include <sys/errno.h>
52 #include <sys/debug.h>
53 #include <sys/priv_impl.h>
54 #include <sys/procfs.h>
55 #include <sys/policy.h>
56 #include <sys/cred_impl.h>
57 #include <sys/devpolicy.h>
58 #include <sys/atomic.h>
61 * Privilege name to number mapping table consists in the generated
62 * priv_const.c file. This lock protects against updates of the privilege
63 * names and counts; all other priv_info fields are read-only.
64 * The actual protected values are:
65 * global variable nprivs
67 * the priv_names field
68 * the priv names info item (cnt/strings)
70 krwlock_t privinfo_lock
;
72 static boolean_t
priv_valid(const cred_t
*);
74 priv_set_t priv_fullset
; /* set of all privileges */
75 priv_set_t priv_unsafe
; /* unsafe to exec set-uid root if these are not in L */
78 * Privilege initialization functions.
79 * Called from common/os/cred.c when cred_init is called.
86 int alloc_test_priv
= 1;
88 int alloc_test_priv
= priv_debug
;
90 rw_init(&privinfo_lock
, NULL
, RW_DRIVER
, NULL
);
92 PRIV_BASIC_ASSERT(priv_basic
);
93 PRIV_UNSAFE_ASSERT(&priv_unsafe
);
94 priv_fillset(&priv_fullset
);
97 * When booting with priv_debug set or in a DEBUG kernel, then we'll
98 * add an additional basic privilege and we verify that it is always
101 if (alloc_test_priv
!= 0 &&
102 (priv_basic_test
= priv_getbyname("basic_test", PRIV_ALLOC
)) >= 0) {
103 priv_addset(priv_basic
, priv_basic_test
);
109 /* Utility functions: privilege sets as opaque data types */
112 * Guts of prgetprivsize.
115 priv_prgetprivsize(prpriv_t
*tmpl
)
117 return (sizeof (prpriv_t
) +
118 PRIV_SETBYTES
- sizeof (priv_chunk_t
) +
119 (tmpl
? tmpl
->pr_infosize
: priv_info
->priv_infosize
));
126 cred2prpriv(const cred_t
*cp
, prpriv_t
*pr
)
131 pr
->pr_nsets
= PRIV_NSET
;
132 pr
->pr_setsize
= PRIV_SETSIZE
;
133 pr
->pr_infosize
= priv_info
->priv_infosize
;
135 psa
= (priv_set_t
*)pr
->pr_sets
;
137 for (i
= 0; i
< PRIV_NSET
; i
++)
138 psa
[i
] = *priv_getset(cp
, i
);
140 priv_getinfo(cp
, (char *)pr
+ PRIV_PRPRIV_INFO_OFFSET(pr
));
146 * Set the privileges of a process.
148 * In order to set the privileges, the setting process will need to
149 * have those privileges in its effective set in order to prevent
150 * specially privileged processes to easily gain additional privileges.
151 * Pre-existing privileges can be retained. To change any privileges,
152 * PRIV_PROC_OWNER needs to be asserted.
156 * S' <= S || S' <= S + Ea
158 * the new set must either be subset of the old set or a subset of
159 * the oldset merged with the effective set of the acting process; or just:
163 * It's not legal to grow the limit set this way.
167 priv_pr_spriv(proc_t
*p
, prpriv_t
*prpriv
, const cred_t
*cr
)
173 cred_priv_t
*cp
, *ocp
;
176 ASSERT(MUTEX_HELD(&p
->p_lock
));
179 * Set must have proper dimension; infosize must be absent
182 if (prpriv
->pr_nsets
!= PRIV_NSET
||
183 prpriv
->pr_setsize
!= PRIV_SETSIZE
||
184 (prpriv
->pr_infosize
& (sizeof (uint32_t) - 1)) != 0 ||
185 prpriv
->pr_infosize
> priv_info
->priv_infosize
||
186 prpriv
->pr_infosize
< 0)
189 mutex_exit(&p
->p_lock
);
191 if (priv_proc_cred_perm(cr
, p
, &oldcred
, VWRITE
) != 0) {
192 mutex_enter(&p
->p_lock
);
196 newcred
= crdup(oldcred
);
198 /* Copy the privilege sets from prpriv to newcred */
199 bcopy(prpriv
->pr_sets
, CR_PRIVSETS(newcred
), PRIV_SETBYTES
);
201 cp
= &newcred
->cr_priv
;
202 ocp
= &oldcred
->cr_priv
;
203 eset
= CR_OEPRIV(cr
);
205 priv_intersect(&CR_LPRIV(oldcred
), &eset
);
208 * Verify the constraints laid out:
209 * for the limit set, we require that the new set is a subset
210 * of the old limit set.
211 * for all other sets, we require that the new set is either a
212 * subset of the old set or a subset of the intersection of
213 * the old limit set and the effective set of the acting process.
215 for (i
= 0; i
< PRIV_NSET
; i
++)
216 if (!priv_issubset(&cp
->crprivs
[i
], &ocp
->crprivs
[i
]) &&
217 (i
== PRIV_LIMIT
|| !priv_issubset(&cp
->crprivs
[i
], &eset
)))
222 if (i
< PRIV_NSET
|| !priv_valid(newcred
))
225 /* Load the settable privilege information */
226 if (prpriv
->pr_infosize
> 0) {
227 char *x
= (char *)prpriv
+ PRIV_PRPRIV_INFO_OFFSET(prpriv
);
228 char *lastx
= x
+ prpriv
->pr_infosize
;
231 priv_info_t
*pi
= (priv_info_t
*)x
;
232 priv_info_uint_t
*pii
;
234 switch (pi
->priv_info_type
) {
235 case PRIV_INFO_FLAGS
:
236 pii
= (priv_info_uint_t
*)x
;
237 if (pii
->info
.priv_info_size
!= sizeof (*pii
)) {
241 CR_FLAGS(newcred
) &= ~PRIV_USER
;
242 CR_FLAGS(newcred
) |= (pii
->val
& PRIV_USER
);
248 /* Guarantee alignment and forward progress */
249 if ((pi
->priv_info_size
& (sizeof (uint32_t) - 1)) ||
250 pi
->priv_info_size
< sizeof (*pi
) ||
251 lastx
- x
> pi
->priv_info_size
) {
256 x
+= pi
->priv_info_size
;
261 * We'll try to copy the privilege aware flag; but since the
262 * privileges sets are all individually set, they are set
263 * as if we're privilege aware. If PRIV_AWARE wasn't set
264 * or was explicitely unset, we need to set the flag and then
265 * try to get rid of it.
267 if ((CR_FLAGS(newcred
) & PRIV_AWARE
) == 0) {
268 CR_FLAGS(newcred
) |= PRIV_AWARE
;
269 priv_adjust_PA(newcred
);
272 mutex_enter(&p
->p_crlock
);
275 mutex_exit(&p
->p_crlock
);
278 mutex_enter(&p
->p_lock
);
283 mutex_enter(&p
->p_lock
);
288 *priv_hold_implinfo(void)
290 rw_enter(&privinfo_lock
, RW_READER
);
295 priv_release_implinfo(void)
297 rw_exit(&privinfo_lock
);
301 priv_get_implinfo_size(void)
303 return (privinfosize
);
308 * Return the nth privilege set
311 priv_getset(const cred_t
*cr
, int set
)
313 ASSERT(PRIV_VALIDSET(set
));
315 if ((CR_FLAGS(cr
) & PRIV_AWARE
) == 0)
318 return (&CR_OEPRIV(cr
));
320 return (&CR_OPPRIV(cr
));
322 return (&CR_PRIVS(cr
)->crprivs
[set
]);
326 * Buf must be allocated by caller and contain sufficient space to
327 * contain all additional info structures using priv_info.priv_infosize.
328 * The buffer must be properly aligned.
332 priv_getinfo(const cred_t
*cr
, void *buf
)
334 struct priv_info_uint
*ii
;
337 ii
->val
= CR_FLAGS(cr
);
338 ii
->info
.priv_info_size
= (uint32_t)sizeof (*ii
);
339 ii
->info
.priv_info_type
= PRIV_INFO_FLAGS
;
343 priv_getbyname(const char *name
, uint_t flag
)
350 if (flag
!= 0 && flag
!= PRIV_ALLOC
)
353 if (strncasecmp(name
, "priv_", 5) == 0)
356 rw_enter(&privinfo_lock
, RW_READER
);
358 for (i
= 0; i
< nprivs
; i
++)
359 if (strcasecmp(priv_names
[i
], name
) == 0) {
360 rw_exit(&privinfo_lock
);
366 if (!(flag
& PRIV_ALLOC
)) {
367 rw_exit(&privinfo_lock
);
371 /* check length, validity and available space */
372 len
= strlen(name
) + 1;
374 if (len
> PRIVNAME_MAX
) {
375 rw_exit(&privinfo_lock
);
376 return (-ENAMETOOLONG
);
379 for (p
= (char *)name
; *p
!= '\0'; p
++) {
382 if (!((c
>= 'A' && c
<= 'Z') ||
383 (c
>= 'a' && c
<= 'z') ||
384 (c
>= '0' && c
<= '9') ||
386 rw_exit(&privinfo_lock
);
391 if (!rw_tryupgrade(&privinfo_lock
)) {
392 rw_exit(&privinfo_lock
);
393 rw_enter(&privinfo_lock
, RW_WRITER
);
395 /* Someone may have added our privilege */
400 if (nprivs
== MAX_PRIVILEGE
|| len
+ privbytes
> maxprivbytes
) {
401 rw_exit(&privinfo_lock
);
405 priv_names
[i
] = p
= priv_str
+ privbytes
;
409 /* make the priv_names[i] and privilege name globally visible */
412 /* adjust priv count and bytes count */
413 priv_ninfo
->cnt
= priv_info
->priv_max
= ++nprivs
;
416 rw_exit(&privinfo_lock
);
421 * We can't afford locking the privileges here because of the locations
422 * we call this from; so we make sure that the privileges table
423 * is visible to us; it is made visible before the value of nprivs is
427 priv_getbynum(int priv
)
429 int maxpriv
= nprivs
;
433 if (priv
>= 0 && priv
< maxpriv
)
434 return (priv_names
[priv
]);
440 priv_getsetbynum(int setno
)
442 if (!PRIV_VALIDSET(setno
))
445 return (priv_setnames
[setno
]);
449 * Privilege sanity checking when setting: E <= P.
452 priv_valid(const cred_t
*cr
)
454 return (priv_issubset(&CR_EPRIV(cr
), &CR_PPRIV(cr
)));
458 * Privilege manipulation functions
460 * Without knowing the details of the privilege set implementation,
461 * opaque pointers can be used to manipulate sets at will.
464 priv_emptyset(priv_set_t
*set
)
466 bzero(set
, sizeof (*set
));
470 priv_fillset(priv_set_t
*set
)
475 for (i
= 0; i
< PRIV_SETSIZE
; i
++)
476 set
->pbits
[i
] = ~(priv_chunk_t
)0;
480 priv_addset(priv_set_t
*set
, int priv
)
482 ASSERT(priv
>= 0 && priv
< MAX_PRIVILEGE
);
483 __PRIV_ASSERT(set
, priv
);
487 priv_delset(priv_set_t
*set
, int priv
)
489 ASSERT(priv
>= 0 && priv
< MAX_PRIVILEGE
);
490 __PRIV_CLEAR(set
, priv
);
494 priv_ismember(const priv_set_t
*set
, int priv
)
496 ASSERT(priv
>= 0 && priv
< MAX_PRIVILEGE
);
497 return (__PRIV_ISASSERT(set
, priv
) ? B_TRUE
: B_FALSE
);
500 #define PRIV_TEST_BODY(test) \
503 for (i = 0; i < PRIV_SETSIZE; i++) \
510 priv_isequalset(const priv_set_t
*a
, const priv_set_t
*b
)
512 return ((boolean_t
)(bcmp(a
, b
, sizeof (*a
)) == 0));
516 priv_isemptyset(const priv_set_t
*set
)
518 PRIV_TEST_BODY(set
->pbits
[i
] == 0);
522 priv_isfullset(const priv_set_t
*set
)
524 PRIV_TEST_BODY(set
->pbits
[i
] == ~(priv_chunk_t
)0);
528 * Return true if a is a subset of b
531 priv_issubset(const priv_set_t
*a
, const priv_set_t
*b
)
533 PRIV_TEST_BODY((a
->pbits
[i
] | b
->pbits
[i
]) == b
->pbits
[i
]);
536 #define PRIV_CHANGE_BODY(a, op, b) \
539 for (i = 0; i < PRIV_SETSIZE; i++) \
540 a->pbits[i] op b->pbits[i]
544 priv_intersect(const priv_set_t
*a
, priv_set_t
*b
)
547 PRIV_CHANGE_BODY(b
, &=, a
);
552 priv_union(const priv_set_t
*a
, priv_set_t
*b
)
555 PRIV_CHANGE_BODY(b
, |=, a
);
560 priv_inverse(priv_set_t
*a
)
562 PRIV_CHANGE_BODY(a
, = ~, a
);
566 * Can the source cred act on the target credential?
568 * We will you allow to gain uids this way but not privileges.
571 priv_proc_cred_perm(const cred_t
*scr
, proc_t
*tp
, cred_t
**pcr
, int mode
)
573 const priv_set_t
*eset
;
578 /* prevent the cred from going away */
579 mutex_enter(&tp
->p_crlock
);
580 crhold(tcr
= tp
->p_cred
);
581 mutex_exit(&tp
->p_crlock
);
583 if (scr
== tcr
&& !(tp
->p_flag
& SNOCD
))
586 idsmatch
= (scr
->cr_uid
== tcr
->cr_uid
&&
587 scr
->cr_uid
== tcr
->cr_ruid
&&
588 scr
->cr_uid
== tcr
->cr_suid
&&
589 scr
->cr_gid
== tcr
->cr_gid
&&
590 scr
->cr_gid
== tcr
->cr_rgid
&&
591 scr
->cr_gid
== tcr
->cr_sgid
&&
592 !(tp
->p_flag
& SNOCD
));
595 * Source credential must have the proc_zone privilege if referencing
596 * a process in another zone.
598 if (scr
->cr_zone
!= tcr
->cr_zone
&& secpolicy_proc_zone(scr
) != 0) {
603 if (!(mode
& VWRITE
)) {
604 if (!idsmatch
&& secpolicy_proc_owner(scr
, tcr
, 0) != 0)
610 * For writing, the effective set of scr must dominate all sets of tcr,
611 * We test Pt <= Es (Et <= Pt so no need to test) and It <= Es
612 * The Limit set of scr must be a superset of the limitset of
615 eset
= &CR_OEPRIV(scr
);
617 if (!priv_issubset(&CR_IPRIV(tcr
), eset
) ||
618 !priv_issubset(&CR_OPPRIV(tcr
), eset
) ||
619 !priv_issubset(&CR_LPRIV(tcr
), &CR_LPRIV(scr
)) ||
620 !idsmatch
&& secpolicy_proc_owner(scr
, tcr
, mode
) != 0)
624 if (res
== 0 && pcr
!= NULL
)
632 * Set the privilege aware bit, adding L to E/P if necessary.
633 * Each time we set it, we also clear PRIV_AWARE_RESET.
636 priv_set_PA(cred_t
*cr
)
638 ASSERT(cr
->cr_ref
<= 2);
640 if ((CR_FLAGS(cr
) & (PRIV_AWARE
|PRIV_AWARE_RESET
)) == PRIV_AWARE
)
643 CR_FLAGS(cr
) |= PRIV_AWARE
;
644 CR_FLAGS(cr
) &= ~PRIV_AWARE_RESET
;
647 priv_union(&CR_LPRIV(cr
), &CR_EPRIV(cr
));
649 if (cr
->cr_uid
== 0 || cr
->cr_suid
== 0 || cr
->cr_ruid
== 0)
650 priv_union(&CR_LPRIV(cr
), &CR_PPRIV(cr
));
654 priv_can_clear_PA(const cred_t
*cr
)
657 * We can clear PA in the following cases:
659 * None of the uids are 0.
660 * Any uid == 0 and P == L and (Euid != 0 or E == L)
662 return ((cr
->cr_suid
!= 0 && cr
->cr_ruid
!= 0 && cr
->cr_uid
!= 0) ||
663 priv_isequalset(&CR_PPRIV(cr
), &CR_LPRIV(cr
)) &&
664 (cr
->cr_uid
!= 0 || priv_isequalset(&CR_EPRIV(cr
), &CR_LPRIV(cr
))));
668 * Clear privilege aware bit if it is an idempotent operation and by
669 * clearing it the process cannot get to uid 0 and all privileges.
671 * This function should be called with caution as it may cause "E" to be
672 * lost once a processes assumes euid 0 again.
675 priv_adjust_PA(cred_t
*cr
)
677 ASSERT(cr
->cr_ref
<= 2);
679 if (!(CR_FLAGS(cr
) & PRIV_AWARE
) ||
680 !priv_can_clear_PA(cr
)) {
681 CR_FLAGS(cr
) &= ~PRIV_AWARE_RESET
;
685 if (CR_FLAGS(cr
) & PRIV_AWARE_INHERIT
)
689 * We now need to adjust P/E in those cases when uids
690 * are zero; the rules are P' = I & L, E' = I & L;
691 * but since P = L and E = L, we can use P &= I, E &= I,
692 * depending on which uids are 0.
694 if (cr
->cr_suid
== 0 || cr
->cr_ruid
== 0 || cr
->cr_uid
== 0) {
696 priv_intersect(&CR_IPRIV(cr
), &CR_EPRIV(cr
));
697 priv_intersect(&CR_IPRIV(cr
), &CR_PPRIV(cr
));
700 CR_FLAGS(cr
) &= ~(PRIV_AWARE
|PRIV_AWARE_RESET
);
704 * Reset privilege aware bit if so requested by setting the PRIV_AWARE_RESET
708 priv_reset_PA(cred_t
*cr
, boolean_t finalize
)
710 ASSERT(cr
->cr_ref
<= 2);
712 if ((CR_FLAGS(cr
) & (PRIV_AWARE
|PRIV_AWARE_RESET
)) !=
713 (PRIV_AWARE
|PRIV_AWARE_RESET
)) {
714 CR_FLAGS(cr
) &= ~PRIV_AWARE_RESET
;
719 * When PRIV_AWARE_RESET is enabled, any change of uids causes
720 * a change to the P and E sets. Bracketing with
721 * seteuid(0) ... seteuid(uid)/setreuid(-1, 0) .. setreuid(-1, uid)
722 * will cause the privilege sets "do the right thing.".
723 * When the change of the uid is "final", e.g., by using setuid(uid),
724 * or setreuid(uid, uid) or when the last set*uid() call causes all
725 * uids to be the same, we set P and E to I & L, like when you exec.
726 * We make an exception when all the uids are 0; this is required
727 * when we login as root as in that particular case we cannot
728 * make a distinction between seteuid(0) and seteuid(uid).
729 * We rely on seteuid/setreuid/setuid to tell us with the
730 * "finalize" argument that we no longer expect new uid changes,
731 * cf. setreuid(uid, uid) and setuid(uid).
733 if (cr
->cr_suid
== cr
->cr_ruid
&& cr
->cr_suid
== cr
->cr_uid
) {
734 if (finalize
|| cr
->cr_uid
!= 0) {
735 CR_EPRIV(cr
) = CR_IPRIV(cr
);
736 priv_intersect(&CR_LPRIV(cr
), &CR_EPRIV(cr
));
737 CR_PPRIV(cr
) = CR_EPRIV(cr
);
738 CR_FLAGS(cr
) &= ~(PRIV_AWARE
|PRIV_AWARE_RESET
);
740 CR_EPRIV(cr
) = CR_PPRIV(cr
);
742 } else if (cr
->cr_uid
!= 0 && (cr
->cr_ruid
== 0 || cr
->cr_suid
== 0)) {
743 CR_EPRIV(cr
) = CR_IPRIV(cr
);
744 priv_intersect(&CR_LPRIV(cr
), &CR_EPRIV(cr
));