2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
12 /* Copyright 2015, Richard Lowe. */
14 #include <sys/secflags.h>
15 #include <sys/types.h>
19 #include <sys/sunddi.h>
21 #include "lint.h" /* libc header */
28 secflag_to_bit(secflag_t secflag
)
30 return (1 << secflag
);
34 secflag_isset(secflagset_t flags
, secflag_t sf
)
36 return ((flags
& secflag_to_bit(sf
)) != 0);
40 secflag_clear(secflagset_t
*flags
, secflag_t sf
)
42 *flags
&= ~secflag_to_bit(sf
);
46 secflag_set(secflagset_t
*flags
, secflag_t sf
)
48 *flags
|= secflag_to_bit(sf
);
52 secflags_isempty(secflagset_t flags
)
58 secflags_zero(secflagset_t
*flags
)
64 secflags_fullset(secflagset_t
*flags
)
66 *flags
= PROC_SEC_MASK
;
70 secflags_copy(secflagset_t
*dst
, const secflagset_t
*src
)
76 secflags_issubset(secflagset_t a
, secflagset_t b
)
82 secflags_issuperset(secflagset_t a
, secflagset_t b
)
84 return (secflags_issubset(b
, a
));
88 secflags_intersection(secflagset_t a
, secflagset_t b
)
94 secflags_union(secflagset_t
*a
, const secflagset_t
*b
)
100 secflags_difference(secflagset_t
*a
, const secflagset_t
*b
)
106 psecflags_validate_delta(const psecflags_t
*sf
, const secflagdelta_t
*delta
)
108 if (delta
->psd_ass_active
) {
110 * If there's a bit in lower not in args, or a bit args not in
113 if (!secflags_issubset(delta
->psd_assign
, sf
->psf_upper
) ||
114 !secflags_issuperset(delta
->psd_assign
, sf
->psf_lower
)) {
118 if (!secflags_issubset(delta
->psd_assign
, PROC_SEC_MASK
))
121 /* If we're adding a bit not in upper */
122 if (!secflags_isempty(delta
->psd_add
)) {
123 if (!secflags_issubset(delta
->psd_add
, sf
->psf_upper
)) {
128 /* If we're removing a bit that's in lower */
129 if (!secflags_isempty(delta
->psd_rem
)) {
130 if (secflags_intersection(delta
->psd_rem
,
136 if (!secflags_issubset(delta
->psd_add
, PROC_SEC_MASK
) ||
137 !secflags_issubset(delta
->psd_rem
, PROC_SEC_MASK
))
145 psecflags_validate(const psecflags_t
*sf
)
147 if (!secflags_issubset(sf
->psf_lower
, PROC_SEC_MASK
) ||
148 !secflags_issubset(sf
->psf_inherit
, PROC_SEC_MASK
) ||
149 !secflags_issubset(sf
->psf_effective
, PROC_SEC_MASK
) ||
150 !secflags_issubset(sf
->psf_upper
, PROC_SEC_MASK
))
153 if (!secflags_issubset(sf
->psf_lower
, sf
->psf_inherit
))
155 if (!secflags_issubset(sf
->psf_lower
, sf
->psf_upper
))
157 if (!secflags_issubset(sf
->psf_inherit
, sf
->psf_upper
))
164 psecflags_default(psecflags_t
*sf
)
166 secflags_zero(&sf
->psf_effective
);
167 secflags_zero(&sf
->psf_inherit
);
168 secflags_zero(&sf
->psf_lower
);
169 secflags_fullset(&sf
->psf_upper
);
172 static struct flagdesc
{
176 { PROC_SEC_ASLR
, "aslr" },
177 { PROC_SEC_FORBIDNULLMAP
, "forbidnullmap" },
178 { PROC_SEC_NOEXECSTACK
, "noexecstack" },
183 secflag_by_name(const char *str
, secflag_t
*ret
)
187 for (fd
= flagdescs
; fd
->name
!= NULL
; fd
++) {
188 if (strcasecmp(str
, fd
->name
) == 0) {
198 secflag_to_str(secflag_t sf
)
202 for (fd
= flagdescs
; fd
->name
!= NULL
; fd
++) {
211 secflags_to_str(secflagset_t flags
, char *buf
, size_t buflen
)
219 (void) strlcpy(buf
, "none", buflen
);
223 for (fd
= flagdescs
; fd
->name
!= NULL
; fd
++) {
224 if (secflag_isset(flags
, fd
->value
)) {
226 (void) strlcat(buf
, ",", buflen
);
227 (void) strlcat(buf
, fd
->name
, buflen
);
230 secflag_clear(&flags
, fd
->value
);
233 if (flags
!= 0) { /* unknown flags */
234 char hexbuf
[19]; /* 0x%16 PRIx64 */
236 (void) snprintf(hexbuf
, sizeof (hexbuf
), "0x%16" PRIx64
, flags
);
238 (void) strlcat(buf
, ",", buflen
);
239 (void) strlcat(buf
, hexbuf
, buflen
);