From aef3bb81949009450e5f7c8d0c2b85efc1426242 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Thu, 24 Oct 2024 17:46:00 +0200 Subject: [PATCH 1/6] libsepol: misc assertion cleanup MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Use const parameters where applicable to signal immutability. Rename the passed iterator avrule from avrule to narule, to make clear its the neverallow rule to assert against, not the allow rule to check. Drop needless branch in check_assertions(), since in the case avrules is NULL the for loop won't execute and errors will stay at 0, so 0 will be returned regardless. Also there is no call to free() as mentioned in the outdated comment. Signed-off-by: Christian Göttsche --- v3: - use C99 bool where applicable - minor additions v2: add patch --- libsepol/include/sepol/policydb/policydb.h | 4 +- libsepol/src/assertion.c | 222 ++++++++++----------- 2 files changed, 107 insertions(+), 119 deletions(-) diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h index f73e21fc5..88fb36726 100644 --- a/libsepol/include/sepol/policydb/policydb.h +++ b/libsepol/include/sepol/policydb/policydb.h @@ -698,9 +698,9 @@ extern void level_datum_init(level_datum_t * x); extern void level_datum_destroy(level_datum_t * x); extern void cat_datum_init(cat_datum_t * x); extern void cat_datum_destroy(cat_datum_t * x); -extern int check_assertion(policydb_t *p, avrule_t *avrule); +extern int check_assertion(policydb_t *p, const avrule_t *avrule); extern int check_assertions(sepol_handle_t * handle, - policydb_t * p, avrule_t * avrules); + policydb_t * p, const avrule_t * avrules); extern int symtab_insert(policydb_t * x, uint32_t sym, hashtab_key_t key, hashtab_datum_t datum, diff --git a/libsepol/src/assertion.c b/libsepol/src/assertion.c index 5e1298838..e0e8685f2 100644 --- a/libsepol/src/assertion.c +++ b/libsepol/src/assertion.c @@ -20,6 +20,7 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA */ +#include #include #include #include @@ -31,35 +32,31 @@ struct avtab_match_args { sepol_handle_t *handle; policydb_t *p; - avrule_t *avrule; + const avrule_t *narule; avtab_t *avtab; unsigned long errors; }; -static const char* policy_name(policydb_t *p) { - const char *policy_file = "policy.conf"; - if (p->name) { - policy_file = p->name; - } - return policy_file; +static const char* policy_name(const policydb_t *p) { + return p->name ?: "policy.conf"; } -static void report_failure(sepol_handle_t *handle, policydb_t *p, const avrule_t *avrule, +static void report_failure(sepol_handle_t *handle, const policydb_t *p, const avrule_t *narule, unsigned int stype, unsigned int ttype, const class_perm_node_t *curperm, uint32_t perms) { char *permstr = sepol_av_to_string(p, curperm->tclass, perms); - if (avrule->source_filename) { + if (narule->source_filename) { ERR(handle, "neverallow on line %lu of %s (or line %lu of %s) violated by allow %s %s:%s {%s };", - avrule->source_line, avrule->source_filename, avrule->line, policy_name(p), + narule->source_line, narule->source_filename, narule->line, policy_name(p), p->p_type_val_to_name[stype], p->p_type_val_to_name[ttype], p->p_class_val_to_name[curperm->tclass - 1], permstr ?: ""); - } else if (avrule->line) { + } else if (narule->line) { ERR(handle, "neverallow on line %lu violated by allow %s %s:%s {%s };", - avrule->line, p->p_type_val_to_name[stype], + narule->line, p->p_type_val_to_name[stype], p->p_type_val_to_name[ttype], p->p_class_val_to_name[curperm->tclass - 1], permstr ?: ""); @@ -74,29 +71,29 @@ static void report_failure(sepol_handle_t *handle, policydb_t *p, const avrule_t free(permstr); } -static int match_any_class_permissions(class_perm_node_t *cp, uint32_t class, uint32_t data) +static bool match_any_class_permissions(const class_perm_node_t *cp, uint32_t class, uint32_t data) { for (; cp; cp = cp->next) { if ((cp->tclass == class) && (cp->data & data)) - return 1; + return true; } - return 0; + return false; } -static int extended_permissions_and(uint32_t *perms1, uint32_t *perms2) { +static bool extended_permissions_and(const uint32_t *perms1, const uint32_t *perms2) { size_t i; for (i = 0; i < EXTENDED_PERMS_LEN; i++) { if (perms1[i] & perms2[i]) - return 1; + return true; } - return 0; + return false; } -static int check_extended_permissions(av_extended_perms_t *neverallow, avtab_extended_perms_t *allow) +static bool check_extended_permissions(const av_extended_perms_t *neverallow, const avtab_extended_perms_t *allow) { - int rc = 0; + bool rc = false; if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION) && (allow->specified == AVTAB_XPERMS_IOCTLFUNCTION)) { if (neverallow->driver == allow->driver) @@ -121,8 +118,8 @@ static int check_extended_permissions(av_extended_perms_t *neverallow, avtab_ext /* Compute which allowed extended permissions violate the neverallow rule */ static void extended_permissions_violated(avtab_extended_perms_t *result, - av_extended_perms_t *neverallow, - avtab_extended_perms_t *allow) + const av_extended_perms_t *neverallow, + const avtab_extended_perms_t *allow) { size_t i; if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION) @@ -157,21 +154,20 @@ static void extended_permissions_violated(avtab_extended_perms_t *result, /* Same scenarios of interest as check_assertion_extended_permissions */ static int report_assertion_extended_permissions(sepol_handle_t *handle, - policydb_t *p, const avrule_t *avrule, + policydb_t *p, const avrule_t *narule, unsigned int stype, unsigned int ttype, const class_perm_node_t *curperm, uint32_t perms, - avtab_key_t *k, avtab_t *avtab) + const avtab_key_t *k, avtab_t *avtab) { avtab_ptr_t node; avtab_key_t tmp_key; avtab_extended_perms_t *xperms; avtab_extended_perms_t error; - ebitmap_t *sattr = &p->type_attr_map[stype]; - ebitmap_t *tattr = &p->type_attr_map[ttype]; + const ebitmap_t *sattr = &p->type_attr_map[stype]; + const ebitmap_t *tattr = &p->type_attr_map[ttype]; ebitmap_node_t *snode, *tnode; unsigned int i, j; - int rc; - int found_xperm = 0; + bool found_xperm = false; int errors = 0; memcpy(&tmp_key, k, sizeof(avtab_key_t)); @@ -189,18 +185,17 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle, && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER) && (xperms->specified != AVTAB_XPERMS_NLMSG)) continue; - found_xperm = 1; - rc = check_extended_permissions(avrule->xperms, xperms); + found_xperm = true; /* failure on the extended permission check_extended_permissions */ - if (rc) { + if (check_extended_permissions(narule->xperms, xperms)) { char *permstring; - extended_permissions_violated(&error, avrule->xperms, xperms); + extended_permissions_violated(&error, narule->xperms, xperms); permstring = sepol_extended_perms_to_string(&error); ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n" "allowxperm %s %s:%s %s;", - avrule->source_line, avrule->source_filename, avrule->line, policy_name(p), + narule->source_line, narule->source_filename, narule->line, policy_name(p), p->p_type_val_to_name[i], p->p_type_val_to_name[j], p->p_class_val_to_name[curperm->tclass - 1], @@ -219,7 +214,7 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle, ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n" "allow %s %s:%s {%s };", - avrule->source_line, avrule->source_filename, avrule->line, policy_name(p), + narule->source_line, narule->source_filename, narule->line, policy_name(p), p->p_type_val_to_name[stype], p->p_type_val_to_name[ttype], p->p_class_val_to_name[curperm->tclass - 1], @@ -240,26 +235,26 @@ static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void sepol_handle_t *handle = a->handle; policydb_t *p = a->p; avtab_t *avtab = a->avtab; - avrule_t *avrule = a->avrule; - class_perm_node_t *cp; + const avrule_t *narule = a->narule; + const class_perm_node_t *cp; uint32_t perms; ebitmap_t src_matches, tgt_matches, self_matches; ebitmap_node_t *snode, *tnode; unsigned int i, j; - const int is_avrule_self = (avrule->flags & RULE_SELF) != 0; - const int is_avrule_notself = (avrule->flags & RULE_NOTSELF) != 0; + const bool is_narule_self = (narule->flags & RULE_SELF) != 0; + const bool is_narule_notself = (narule->flags & RULE_NOTSELF) != 0; if ((k->specified & AVTAB_ALLOWED) == 0) return 0; - if (!match_any_class_permissions(avrule->perms, k->target_class, d->data)) + if (!match_any_class_permissions(narule->perms, k->target_class, d->data)) return 0; ebitmap_init(&src_matches); ebitmap_init(&tgt_matches); ebitmap_init(&self_matches); - rc = ebitmap_and(&src_matches, &avrule->stypes.types, + rc = ebitmap_and(&src_matches, &narule->stypes.types, &p->attr_type_map[k->source_type - 1]); if (rc < 0) goto oom; @@ -267,22 +262,22 @@ static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void if (ebitmap_is_empty(&src_matches)) goto exit; - if (is_avrule_notself) { - if (ebitmap_is_empty(&avrule->ttypes.types)) { + if (is_narule_notself) { + if (ebitmap_is_empty(&narule->ttypes.types)) { /* avrule tgt is of the form ~self */ rc = ebitmap_cpy(&tgt_matches, &p->attr_type_map[k->target_type -1]); } else { /* avrule tgt is of the form {ATTR -self} */ - rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type - 1]); + rc = ebitmap_and(&tgt_matches, &narule->ttypes.types, &p->attr_type_map[k->target_type - 1]); } if (rc) goto oom; } else { - rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type -1]); + rc = ebitmap_and(&tgt_matches, &narule->ttypes.types, &p->attr_type_map[k->target_type -1]); if (rc < 0) goto oom; - if (is_avrule_self) { + if (is_narule_self) { rc = ebitmap_and(&self_matches, &src_matches, &p->attr_type_map[k->target_type - 1]); if (rc < 0) goto oom; @@ -298,7 +293,7 @@ static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void if (ebitmap_is_empty(&tgt_matches)) goto exit; - for (cp = avrule->perms; cp; cp = cp->next) { + for (cp = narule->perms; cp; cp = cp->next) { perms = cp->data & d->data; if ((cp->tclass != k->target_class) || !perms) { @@ -307,16 +302,16 @@ static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void ebitmap_for_each_positive_bit(&src_matches, snode, i) { ebitmap_for_each_positive_bit(&tgt_matches, tnode, j) { - if (is_avrule_self && i != j) + if (is_narule_self && i != j) continue; - if (is_avrule_notself && i == j) + if (is_narule_notself && i == j) continue; - if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) { - a->errors += report_assertion_extended_permissions(handle,p, avrule, + if (narule->specified == AVRULE_XPERMS_NEVERALLOW) { + a->errors += report_assertion_extended_permissions(handle,p, narule, i, j, cp, perms, k, avtab); } else { a->errors++; - report_failure(handle, p, avrule, i, j, cp, perms); + report_failure(handle, p, narule, i, j, cp, perms); } } } @@ -330,22 +325,22 @@ static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void return rc; } -static int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, avrule_t *avrule) +static int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, const avrule_t *narule) { int rc; - struct avtab_match_args args; - - args.handle = handle; - args.p = p; - args.avrule = avrule; - args.errors = 0; + struct avtab_match_args args = { + .handle = handle, + .p = p, + .narule = narule, + .errors = 0, + }; - args.avtab = &p->te_avtab; + args.avtab = &p->te_avtab; rc = avtab_map(&p->te_avtab, report_assertion_avtab_matches, &args); if (rc < 0) goto oom; - args.avtab = &p->te_cond_avtab; + args.avtab = &p->te_cond_avtab; rc = avtab_map(&p->te_cond_avtab, report_assertion_avtab_matches, &args); if (rc < 0) goto oom; @@ -360,19 +355,19 @@ static int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, avru * Look up the extended permissions in avtab and verify that neverallowed * permissions are not granted. */ -static int check_assertion_extended_permissions_avtab(avrule_t *avrule, avtab_t *avtab, +static bool check_assertion_extended_permissions_avtab(const avrule_t *narule, avtab_t *avtab, unsigned int stype, unsigned int ttype, - avtab_key_t *k, policydb_t *p) + const avtab_key_t *k, policydb_t *p) { avtab_ptr_t node; avtab_key_t tmp_key; - avtab_extended_perms_t *xperms; - av_extended_perms_t *neverallow_xperms = avrule->xperms; - ebitmap_t *sattr = &p->type_attr_map[stype]; - ebitmap_t *tattr = &p->type_attr_map[ttype]; + const avtab_extended_perms_t *xperms; + const av_extended_perms_t *neverallow_xperms = narule->xperms; + const ebitmap_t *sattr = &p->type_attr_map[stype]; + const ebitmap_t *tattr = &p->type_attr_map[ttype]; ebitmap_node_t *snode, *tnode; unsigned int i, j; - int rc = 1; + bool ret = true; memcpy(&tmp_key, k, sizeof(avtab_key_t)); tmp_key.specified = AVTAB_XPERMS_ALLOWED; @@ -390,14 +385,14 @@ static int check_assertion_extended_permissions_avtab(avrule_t *avrule, avtab_t && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER) && (xperms->specified != AVTAB_XPERMS_NLMSG)) continue; - rc = check_extended_permissions(neverallow_xperms, xperms); - if (rc) - return rc; + ret = check_extended_permissions(neverallow_xperms, xperms); + if (ret) + return ret; } } } - return rc; + return ret; } /* @@ -416,21 +411,21 @@ static int check_assertion_extended_permissions_avtab(avrule_t *avrule, avtab_t * 4. FAIL - The ioctl permission is granted AND the extended permission is * granted */ -static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab, - avtab_key_t *k, policydb_t *p) +static int check_assertion_extended_permissions(const avrule_t *narule, avtab_t *avtab, + const avtab_key_t *k, policydb_t *p) { ebitmap_t src_matches, tgt_matches, self_matches; unsigned int i, j; ebitmap_node_t *snode, *tnode; - const int is_avrule_self = (avrule->flags & RULE_SELF) != 0; - const int is_avrule_notself = (avrule->flags & RULE_NOTSELF) != 0; + const bool is_narule_self = (narule->flags & RULE_SELF) != 0; + const bool is_narule_notself = (narule->flags & RULE_NOTSELF) != 0; int rc; ebitmap_init(&src_matches); ebitmap_init(&tgt_matches); ebitmap_init(&self_matches); - rc = ebitmap_and(&src_matches, &avrule->stypes.types, + rc = ebitmap_and(&src_matches, &narule->stypes.types, &p->attr_type_map[k->source_type - 1]); if (rc < 0) goto oom; @@ -440,22 +435,22 @@ static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab goto exit; } - if (is_avrule_notself) { - if (ebitmap_is_empty(&avrule->ttypes.types)) { + if (is_narule_notself) { + if (ebitmap_is_empty(&narule->ttypes.types)) { /* avrule tgt is of the form ~self */ rc = ebitmap_cpy(&tgt_matches, &p->attr_type_map[k->target_type -1]); } else { /* avrule tgt is of the form {ATTR -self} */ - rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type - 1]); + rc = ebitmap_and(&tgt_matches, &narule->ttypes.types, &p->attr_type_map[k->target_type - 1]); } if (rc < 0) goto oom; } else { - rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type -1]); + rc = ebitmap_and(&tgt_matches, &narule->ttypes.types, &p->attr_type_map[k->target_type -1]); if (rc < 0) goto oom; - if (is_avrule_self) { + if (is_narule_self) { rc = ebitmap_and(&self_matches, &src_matches, &p->attr_type_map[k->target_type - 1]); if (rc < 0) goto oom; @@ -475,11 +470,11 @@ static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab ebitmap_for_each_positive_bit(&src_matches, snode, i) { ebitmap_for_each_positive_bit(&tgt_matches, tnode, j) { - if (is_avrule_self && i != j) + if (is_narule_self && i != j) continue; - if (is_avrule_notself && i == j) + if (is_narule_notself && i == j) continue; - if (check_assertion_extended_permissions_avtab(avrule, avtab, i, j, k, p)) { + if (check_assertion_extended_permissions_avtab(narule, avtab, i, j, k, p)) { rc = 1; goto exit; } @@ -496,7 +491,7 @@ static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab return rc; } -static int check_assertion_notself_match(avtab_key_t *k, avrule_t *avrule, policydb_t *p) +static int check_assertion_notself_match(const avtab_key_t *k, const avrule_t *narule, policydb_t *p) { ebitmap_t src_matches, tgt_matches; unsigned int num_src_matches, num_tgt_matches; @@ -505,16 +500,16 @@ static int check_assertion_notself_match(avtab_key_t *k, avrule_t *avrule, polic ebitmap_init(&src_matches); ebitmap_init(&tgt_matches); - rc = ebitmap_and(&src_matches, &avrule->stypes.types, &p->attr_type_map[k->source_type - 1]); + rc = ebitmap_and(&src_matches, &narule->stypes.types, &p->attr_type_map[k->source_type - 1]); if (rc < 0) goto oom; - if (ebitmap_is_empty(&avrule->ttypes.types)) { + if (ebitmap_is_empty(&narule->ttypes.types)) { /* avrule tgt is of the form ~self */ rc = ebitmap_cpy(&tgt_matches, &p->attr_type_map[k->target_type - 1]); } else { /* avrule tgt is of the form {ATTR -self} */ - rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, &p->attr_type_map[k->target_type - 1]); + rc = ebitmap_and(&tgt_matches, &narule->ttypes.types, &p->attr_type_map[k->target_type - 1]); } if (rc < 0) goto oom; @@ -551,7 +546,7 @@ static int check_assertion_notself_match(avtab_key_t *k, avrule_t *avrule, polic return rc; } -static int check_assertion_self_match(avtab_key_t *k, avrule_t *avrule, policydb_t *p) +static int check_assertion_self_match(const avtab_key_t *k, const avrule_t *narule, policydb_t *p) { ebitmap_t src_matches; int rc; @@ -560,7 +555,7 @@ static int check_assertion_self_match(avtab_key_t *k, avrule_t *avrule, policydb * and the key's source. */ - rc = ebitmap_and(&src_matches, &avrule->stypes.types, &p->attr_type_map[k->source_type - 1]); + rc = ebitmap_and(&src_matches, &narule->stypes.types, &p->attr_type_map[k->source_type - 1]); if (rc < 0) goto oom; @@ -582,29 +577,29 @@ static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *a int rc; struct avtab_match_args *a = (struct avtab_match_args *)args; policydb_t *p = a->p; - avrule_t *avrule = a->avrule; + const avrule_t *narule = a->narule; avtab_t *avtab = a->avtab; if ((k->specified & AVTAB_ALLOWED) == 0) goto nomatch; - if (!match_any_class_permissions(avrule->perms, k->target_class, d->data)) + if (!match_any_class_permissions(narule->perms, k->target_class, d->data)) goto nomatch; - if (!ebitmap_match_any(&avrule->stypes.types, &p->attr_type_map[k->source_type - 1])) + if (!ebitmap_match_any(&narule->stypes.types, &p->attr_type_map[k->source_type - 1])) goto nomatch; - if (avrule->flags & RULE_NOTSELF) { - rc = check_assertion_notself_match(k, avrule, p); + if (narule->flags & RULE_NOTSELF) { + rc = check_assertion_notself_match(k, narule, p); if (rc < 0) goto oom; if (rc == 0) goto nomatch; } else { /* neverallow may have tgts even if it uses SELF */ - if (!ebitmap_match_any(&avrule->ttypes.types, &p->attr_type_map[k->target_type -1])) { - if (avrule->flags == RULE_SELF) { - rc = check_assertion_self_match(k, avrule, p); + if (!ebitmap_match_any(&narule->ttypes.types, &p->attr_type_map[k->target_type -1])) { + if (narule->flags == RULE_SELF) { + rc = check_assertion_self_match(k, narule, p); if (rc < 0) goto oom; if (rc == 0) @@ -615,8 +610,8 @@ static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *a } } - if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) { - rc = check_assertion_extended_permissions(avrule, avtab, k, p); + if (narule->specified == AVRULE_XPERMS_NEVERALLOW) { + rc = check_assertion_extended_permissions(narule, avtab, k, p); if (rc < 0) goto oom; if (rc == 0) @@ -631,17 +626,17 @@ static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *a return rc; } -int check_assertion(policydb_t *p, avrule_t *avrule) +int check_assertion(policydb_t *p, const avrule_t *narule) { int rc; - struct avtab_match_args args; + struct avtab_match_args args = { + .handle = NULL, + .p = p, + .narule = narule, + .errors = 0, + }; - args.handle = NULL; - args.p = p; - args.avrule = avrule; - args.errors = 0; args.avtab = &p->te_avtab; - rc = avtab_map(&p->te_avtab, check_assertion_avtab_match, &args); if (rc == 0) { @@ -653,20 +648,13 @@ int check_assertion(policydb_t *p, avrule_t *avrule) } int check_assertions(sepol_handle_t * handle, policydb_t * p, - avrule_t * avrules) + const avrule_t * narules) { int rc; - avrule_t *a; + const avrule_t *a; unsigned long errors = 0; - if (!avrules) { - /* Since assertions are stored in avrules, if it is NULL - there won't be any to check. This also prevents an invalid - free if the avtabs are never initialized */ - return 0; - } - - for (a = avrules; a != NULL; a = a->next) { + for (a = narules; a != NULL; a = a->next) { if (!(a->specified & (AVRULE_NEVERALLOW | AVRULE_XPERMS_NEVERALLOW))) continue; rc = check_assertion(p, a); From 36e5e97f4a7c5e47917c56bf6f05e57c313087ba Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Fri, 5 Apr 2024 15:22:50 +0200 Subject: [PATCH 2/6] libsepol: add support for xperms in conditional policies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for extended permission rules in conditional policies by adding a new policy version and adjusting writing and validating policies accordingly. Signed-off-by: Christian Göttsche --- v5: - reintroduce correct avrule checking for conditional policies regressed in v4 via deduplication v4: - fix assertion logic on CIL generated policy - enhance xperm validation - rebase onto main v3: - several assertion logic fixes v2: - rebase onto libsepol: Support nlmsg xperms in assertions - fix assertion checking with xperm av rules in conditional policies (spotted by Jim, thanks!) --- libsepol/include/sepol/policydb/policydb.h | 12 +- libsepol/src/assertion.c | 217 ++++++++++++++++++--- libsepol/src/policydb.c | 21 ++ libsepol/src/policydb_validate.c | 52 +++-- libsepol/src/write.c | 46 +++-- 5 files changed, 276 insertions(+), 72 deletions(-) diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h index 88fb36726..f833354be 100644 --- a/libsepol/include/sepol/policydb/policydb.h +++ b/libsepol/include/sepol/policydb/policydb.h @@ -759,10 +759,11 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); #define POLICYDB_VERSION_INFINIBAND 31 /* Linux-specific */ #define POLICYDB_VERSION_GLBLUB 32 #define POLICYDB_VERSION_COMP_FTRANS 33 /* compressed filename transitions */ +#define POLICYDB_VERSION_COND_XPERMS 34 /* extended permissions in conditional policies */ /* Range of policy versions we understand*/ #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_COMP_FTRANS +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_COND_XPERMS /* Module versions and specific changes*/ #define MOD_POLICYDB_VERSION_BASE 4 @@ -785,9 +786,10 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); #define MOD_POLICYDB_VERSION_INFINIBAND 19 #define MOD_POLICYDB_VERSION_GLBLUB 20 #define MOD_POLICYDB_VERSION_SELF_TYPETRANS 21 +#define MOD_POLICYDB_VERSION_COND_XPERMS 22 #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE -#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_SELF_TYPETRANS +#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_COND_XPERMS #define POLICYDB_CONFIG_MLS 1 @@ -801,6 +803,12 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); ((p)->policy_type != POLICY_KERN \ && (p)->policyvers >= MOD_POLICYDB_VERSION_BOUNDARY)) +#define policydb_has_cond_xperms_feature(p) \ + (((p)->policy_type == POLICY_KERN \ + && (p)->policyvers >= POLICYDB_VERSION_COND_XPERMS) || \ + ((p)->policy_type != POLICY_KERN \ + && (p)->policyvers >= MOD_POLICYDB_VERSION_COND_XPERMS)) + /* the config flags related to unknown classes/perms are bits 2 and 3 */ #define DENY_UNKNOWN SEPOL_DENY_UNKNOWN #define REJECT_UNKNOWN SEPOL_REJECT_UNKNOWN diff --git a/libsepol/src/assertion.c b/libsepol/src/assertion.c index e0e8685f2..4028a33d6 100644 --- a/libsepol/src/assertion.c +++ b/libsepol/src/assertion.c @@ -33,8 +33,8 @@ struct avtab_match_args { sepol_handle_t *handle; policydb_t *p; const avrule_t *narule; - avtab_t *avtab; unsigned long errors; + bool conditional; }; static const char* policy_name(const policydb_t *p) { @@ -152,12 +152,19 @@ static void extended_permissions_violated(avtab_extended_perms_t *result, } } +static bool match_node_key(const struct avtab_node *node, const avtab_key_t *key) +{ + return node->key.source_type == key->source_type + && node->key.target_type == key->target_type + && node->key.target_class == key->target_class; +} + /* Same scenarios of interest as check_assertion_extended_permissions */ static int report_assertion_extended_permissions(sepol_handle_t *handle, policydb_t *p, const avrule_t *narule, unsigned int stype, unsigned int ttype, const class_perm_node_t *curperm, uint32_t perms, - const avtab_key_t *k, avtab_t *avtab) + const avtab_key_t *k, bool conditional) { avtab_ptr_t node; avtab_key_t tmp_key; @@ -167,7 +174,7 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle, const ebitmap_t *tattr = &p->type_attr_map[ttype]; ebitmap_node_t *snode, *tnode; unsigned int i, j; - bool found_xperm = false; + bool found_xperm = false, found_cond_conflict = false; int errors = 0; memcpy(&tmp_key, k, sizeof(avtab_key_t)); @@ -177,7 +184,7 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle, tmp_key.source_type = i + 1; ebitmap_for_each_positive_bit(tattr, tnode, j) { tmp_key.target_type = j + 1; - for (node = avtab_search_node(avtab, &tmp_key); + for (node = avtab_search_node(&p->te_avtab, &tmp_key); node; node = avtab_search_node_next(node, tmp_key.specified)) { xperms = node->datum.xperms; @@ -205,11 +212,105 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle, errors++; } } + + for (const cond_list_t *cl = p->cond_list; cl; cl = cl->next) { + bool found_true_base = false, found_true_xperm = false; + bool found_false_base = false, found_false_xperm = false; + + for (const cond_av_list_t *cal = cl->true_list; cal; cal = cal->next) { + node = cal->node; /* node->next is not from the same condition */ + if (!node) + continue; + + if (!match_node_key(node, &tmp_key)) + continue; + + if (match_any_class_permissions(narule->perms, node->key.target_class, node->datum.data)) { + found_true_base = true; + continue; + } + + if (!(node->key.specified & AVTAB_XPERMS_ALLOWED)) + continue; + + xperms = node->datum.xperms; + if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) + && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER) + && (xperms->specified != AVTAB_XPERMS_NLMSG)) + continue; + found_true_xperm = true; + /* failure on the extended permission check_extended_permissions */ + if (check_extended_permissions(narule->xperms, xperms)) { + char *permstring; + + extended_permissions_violated(&error, narule->xperms, xperms); + permstring = sepol_extended_perms_to_string(&error); + + ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n" + "allowxperm %s %s:%s %s;", + narule->source_line, narule->source_filename, narule->line, policy_name(p), + p->p_type_val_to_name[i], + p->p_type_val_to_name[j], + p->p_class_val_to_name[curperm->tclass - 1], + permstring ?: ""); + + free(permstring); + errors++; + } + } + + for (const cond_av_list_t *cal = cl->false_list; cal; cal = cal->next) { + node = cal->node; /* node->next is not from the same condition */ + if (!node) + continue; + + if (!match_node_key(node, &tmp_key)) + continue; + + if (match_any_class_permissions(narule->perms, node->key.target_class, node->datum.data)) { + found_false_base = true; + continue; + } + + if (!(node->key.specified & AVTAB_XPERMS_ALLOWED)) + continue; + + xperms = node->datum.xperms; + if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) + && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER) + && (xperms->specified != AVTAB_XPERMS_NLMSG)) + continue; + found_false_xperm = true; + /* failure on the extended permission check_extended_permissions */ + if (check_extended_permissions(narule->xperms, xperms)) { + char *permstring; + + extended_permissions_violated(&error, narule->xperms, xperms); + permstring = sepol_extended_perms_to_string(&error); + + ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n" + "allowxperm %s %s:%s %s;", + narule->source_line, narule->source_filename, narule->line, policy_name(p), + p->p_type_val_to_name[i], + p->p_type_val_to_name[j], + p->p_class_val_to_name[curperm->tclass - 1], + permstring ?: ""); + + free(permstring); + errors++; + } + } + + if (found_true_xperm && found_false_xperm) + found_xperm = true; + else if (conditional && ((found_true_base && !found_true_xperm) || (found_false_base && !found_false_xperm))) + found_cond_conflict = true; + } } } - /* failure on the regular permissions */ - if (!found_xperm) { + if ((!found_xperm && !conditional) || found_cond_conflict) { + /* failure on the regular permissions */ char *permstr = sepol_av_to_string(p, curperm->tclass, perms); ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n" @@ -222,7 +323,6 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle, free(permstr); errors++; - } return errors; @@ -234,7 +334,6 @@ static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void struct avtab_match_args *a = (struct avtab_match_args *)args; sepol_handle_t *handle = a->handle; policydb_t *p = a->p; - avtab_t *avtab = a->avtab; const avrule_t *narule = a->narule; const class_perm_node_t *cp; uint32_t perms; @@ -308,7 +407,8 @@ static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void continue; if (narule->specified == AVRULE_XPERMS_NEVERALLOW) { a->errors += report_assertion_extended_permissions(handle,p, narule, - i, j, cp, perms, k, avtab); + i, j, cp, perms, k, + a->conditional); } else { a->errors++; report_failure(handle, p, narule, i, j, cp, perms); @@ -335,12 +435,12 @@ static int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, cons .errors = 0, }; - args.avtab = &p->te_avtab; + args.conditional = false; rc = avtab_map(&p->te_avtab, report_assertion_avtab_matches, &args); if (rc < 0) goto oom; - args.avtab = &p->te_cond_avtab; + args.conditional = true; rc = avtab_map(&p->te_cond_avtab, report_assertion_avtab_matches, &args); if (rc < 0) goto oom; @@ -355,9 +455,10 @@ static int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, cons * Look up the extended permissions in avtab and verify that neverallowed * permissions are not granted. */ -static bool check_assertion_extended_permissions_avtab(const avrule_t *narule, avtab_t *avtab, +static bool check_assertion_extended_permissions_avtab(const avrule_t *narule, unsigned int stype, unsigned int ttype, - const avtab_key_t *k, policydb_t *p) + const avtab_key_t *k, policydb_t *p, + bool conditional) { avtab_ptr_t node; avtab_key_t tmp_key; @@ -367,7 +468,7 @@ static bool check_assertion_extended_permissions_avtab(const avrule_t *narule, a const ebitmap_t *tattr = &p->type_attr_map[ttype]; ebitmap_node_t *snode, *tnode; unsigned int i, j; - bool ret = true; + bool found_xperm = false, found_cond_conflict = false; memcpy(&tmp_key, k, sizeof(avtab_key_t)); tmp_key.specified = AVTAB_XPERMS_ALLOWED; @@ -376,7 +477,7 @@ static bool check_assertion_extended_permissions_avtab(const avrule_t *narule, a tmp_key.source_type = i + 1; ebitmap_for_each_positive_bit(tattr, tnode, j) { tmp_key.target_type = j + 1; - for (node = avtab_search_node(avtab, &tmp_key); + for (node = avtab_search_node(&p->te_avtab, &tmp_key); node; node = avtab_search_node_next(node, tmp_key.specified)) { xperms = node->datum.xperms; @@ -385,14 +486,78 @@ static bool check_assertion_extended_permissions_avtab(const avrule_t *narule, a && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER) && (xperms->specified != AVTAB_XPERMS_NLMSG)) continue; - ret = check_extended_permissions(neverallow_xperms, xperms); - if (ret) - return ret; + found_xperm = true; + if (check_extended_permissions(neverallow_xperms, xperms)) + return true; + } + + for (const cond_list_t *cl = p->cond_list; cl; cl = cl->next) { + bool found_true_base = false, found_true_xperm = false; + bool found_false_base = false, found_false_xperm = false; + + for (const cond_av_list_t *cal = cl->true_list; cal; cal = cal->next) { + node = cal->node; /* node->next is not from the same condition */ + if (!node) + continue; + + if (!match_node_key(node, &tmp_key)) + continue; + + if ((node->key.specified & AVTAB_ALLOWED) && match_any_class_permissions(narule->perms, node->key.target_class, node->datum.data)) { + found_true_base = true; + continue; + } + + if (!(node->key.specified & AVTAB_XPERMS_ALLOWED)) + continue; + + xperms = node->datum.xperms; + + if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) + && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER) + && (xperms->specified != AVTAB_XPERMS_NLMSG)) + continue; + found_true_xperm = true; + if (check_extended_permissions(neverallow_xperms, xperms)) + return true; + } + + for (const cond_av_list_t *cal = cl->false_list; cal; cal = cal->next) { + node = cal->node; /* node->next is not from the same condition */ + if (!node) + continue; + + if (!match_node_key(node, &tmp_key)) + continue; + + if ((node->key.specified & AVTAB_ALLOWED) && match_any_class_permissions(narule->perms, node->key.target_class, node->datum.data)) { + found_false_base = true; + continue; + } + + if (!(node->key.specified & AVTAB_XPERMS_ALLOWED)) + continue; + + xperms = node->datum.xperms; + + if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) + && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER) + && (xperms->specified != AVTAB_XPERMS_NLMSG)) + continue; + found_false_xperm = true; + if (check_extended_permissions(neverallow_xperms, xperms)) + return true; + } + + if (found_true_xperm && found_false_xperm) + found_xperm = true; + else if (conditional && ((found_true_base && !found_true_xperm) || (found_false_base && !found_false_xperm))) + found_cond_conflict = true; } } } - return ret; + return (!conditional && !found_xperm) || found_cond_conflict; } /* @@ -411,8 +576,9 @@ static bool check_assertion_extended_permissions_avtab(const avrule_t *narule, a * 4. FAIL - The ioctl permission is granted AND the extended permission is * granted */ -static int check_assertion_extended_permissions(const avrule_t *narule, avtab_t *avtab, - const avtab_key_t *k, policydb_t *p) +static int check_assertion_extended_permissions(const avrule_t *narule, + const avtab_key_t *k, policydb_t *p, + bool conditional) { ebitmap_t src_matches, tgt_matches, self_matches; unsigned int i, j; @@ -474,7 +640,7 @@ static int check_assertion_extended_permissions(const avrule_t *narule, avtab_t continue; if (is_narule_notself && i == j) continue; - if (check_assertion_extended_permissions_avtab(narule, avtab, i, j, k, p)) { + if (check_assertion_extended_permissions_avtab(narule, i, j, k, p, conditional)) { rc = 1; goto exit; } @@ -578,7 +744,6 @@ static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *a struct avtab_match_args *a = (struct avtab_match_args *)args; policydb_t *p = a->p; const avrule_t *narule = a->narule; - avtab_t *avtab = a->avtab; if ((k->specified & AVTAB_ALLOWED) == 0) goto nomatch; @@ -611,7 +776,7 @@ static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *a } if (narule->specified == AVRULE_XPERMS_NEVERALLOW) { - rc = check_assertion_extended_permissions(narule, avtab, k, p); + rc = check_assertion_extended_permissions(narule, k, p, a->conditional); if (rc < 0) goto oom; if (rc == 0) @@ -636,11 +801,11 @@ int check_assertion(policydb_t *p, const avrule_t *narule) .errors = 0, }; - args.avtab = &p->te_avtab; + args.conditional = false; rc = avtab_map(&p->te_avtab, check_assertion_avtab_match, &args); if (rc == 0) { - args.avtab = &p->te_cond_avtab; + args.conditional = true; rc = avtab_map(&p->te_cond_avtab, check_assertion_avtab_match, &args); } diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c index e90ccca1f..0747e7891 100644 --- a/libsepol/src/policydb.c +++ b/libsepol/src/policydb.c @@ -208,6 +208,13 @@ static const struct policydb_compat_info policydb_compat[] = { .ocon_num = OCON_IBENDPORT + 1, .target_platform = SEPOL_TARGET_SELINUX, }, + { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_COND_XPERMS, + .sym_num = SYM_NUM, + .ocon_num = OCON_IBENDPORT + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, { .type = POLICY_BASE, .version = MOD_POLICYDB_VERSION_BASE, @@ -334,6 +341,13 @@ static const struct policydb_compat_info policydb_compat[] = { .ocon_num = OCON_IBENDPORT + 1, .target_platform = SEPOL_TARGET_SELINUX, }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_COND_XPERMS, + .sym_num = SYM_NUM, + .ocon_num = OCON_IBENDPORT + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, { .type = POLICY_MOD, .version = MOD_POLICYDB_VERSION_BASE, @@ -460,6 +474,13 @@ static const struct policydb_compat_info policydb_compat[] = { .ocon_num = 0, .target_platform = SEPOL_TARGET_SELINUX, }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_COND_XPERMS, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, }; #if 0 diff --git a/libsepol/src/policydb_validate.c b/libsepol/src/policydb_validate.c index 5035313ba..9ee4b948a 100644 --- a/libsepol/src/policydb_validate.c +++ b/libsepol/src/policydb_validate.c @@ -22,6 +22,7 @@ typedef struct map_arg { validate_t *flavors; sepol_handle_t *handle; const policydb_t *policy; + int conditional; } map_arg_t; typedef struct perm_arg { @@ -837,7 +838,7 @@ static int validate_datum(__attribute__ ((unused))hashtab_key_t k, hashtab_datum static int validate_datum_array_entries(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[]) { - map_arg_t margs = { flavors, handle, p }; + map_arg_t margs = { flavors, handle, p, 0 }; if (hashtab_map(p->p_commons.table, validate_common_datum_wrapper, &margs)) goto bad; @@ -903,7 +904,7 @@ static int validate_avtab_key(const avtab_key_t *key, int conditional, const pol case AVTAB_XPERMS_DONTAUDIT: if (p->target_platform != SEPOL_TARGET_SELINUX) goto bad; - if (conditional) + if (conditional && !policydb_has_cond_xperms_feature(p)) goto bad; break; default: @@ -956,7 +957,7 @@ static int validate_avtab_key_and_datum(avtab_key_t *k, avtab_datum_t *d, void * { map_arg_t *margs = args; - if (validate_avtab_key(k, 0, margs->policy, margs->flavors)) + if (validate_avtab_key(k, margs->conditional, margs->policy, margs->flavors)) return -1; if (k->specified & AVTAB_AV) { @@ -972,15 +973,23 @@ static int validate_avtab_key_and_datum(avtab_key_t *k, avtab_datum_t *d, void * if ((k->specified & AVTAB_TYPE) && validate_simpletype(d->data, margs->policy, margs->flavors)) return -1; - if ((k->specified & AVTAB_XPERMS) && validate_xperms(d->xperms)) - return -1; + if (k->specified & AVTAB_XPERMS) { + uint32_t data = d->data; + + /* checkpolicy does not touch data for xperms, CIL sets it. */ + if (data != 0 && validate_access_vector(margs->handle, margs->policy, k->target_class, data)) + return -1; + + if (validate_xperms(d->xperms)) + return -1; + } return 0; } static int validate_avtab(sepol_handle_t *handle, const avtab_t *avtab, const policydb_t *p, validate_t flavors[]) { - map_arg_t margs = { flavors, handle, p }; + map_arg_t margs = { flavors, handle, p, 0 }; if (avtab_map(avtab, validate_avtab_key_and_datum, &margs)) { ERR(handle, "Invalid avtab"); @@ -992,28 +1001,13 @@ static int validate_avtab(sepol_handle_t *handle, const avtab_t *avtab, const po static int validate_cond_av_list(sepol_handle_t *handle, const cond_av_list_t *cond_av, const policydb_t *p, validate_t flavors[]) { - const struct avtab_node *avtab_ptr; - - for (; cond_av; cond_av = cond_av->next) { - for (avtab_ptr = cond_av->node; avtab_ptr; avtab_ptr = avtab_ptr->next) { - const avtab_key_t *key = &avtab_ptr->key; - const avtab_datum_t *datum = &avtab_ptr->datum; + struct avtab_node *avtab_ptr; + map_arg_t margs = { flavors, handle, p, 1 }; - if (validate_avtab_key(key, 1, p, flavors)) + for (; cond_av; cond_av = cond_av->next) + for (avtab_ptr = cond_av->node; avtab_ptr; avtab_ptr = avtab_ptr->next) + if (validate_avtab_key_and_datum(&avtab_ptr->key, &avtab_ptr->datum, &margs)) goto bad; - if (key->specified & AVTAB_AV) { - uint32_t data = datum->data; - - if ((0xFFF & key->specified) == AVTAB_AUDITDENY) - data = ~data; - - if (validate_access_vector(handle, p, key->target_class, data)) - goto bad; - } - if ((key->specified & AVTAB_TYPE) && validate_simpletype(datum->data, p, flavors)) - goto bad; - } - } return 0; @@ -1046,7 +1040,7 @@ static int validate_avrules(sepol_handle_t *handle, const avrule_t *avrule, int case AVRULE_XPERMS_AUDITALLOW: case AVRULE_XPERMS_DONTAUDIT: case AVRULE_XPERMS_NEVERALLOW: - if (conditional) + if (conditional && !policydb_has_cond_xperms_feature(p)) goto bad; break; default: @@ -1278,7 +1272,7 @@ static int validate_filename_trans(hashtab_key_t k, hashtab_datum_t d, void *arg static int validate_filename_trans_hashtab(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[]) { - map_arg_t margs = { flavors, handle, p }; + map_arg_t margs = { flavors, handle, p, 0 }; if (hashtab_map(p->filename_trans, validate_filename_trans, &margs)) { ERR(handle, "Invalid filename trans"); @@ -1631,7 +1625,7 @@ static int validate_range_transition(hashtab_key_t key, hashtab_datum_t data, vo static int validate_range_transitions(sepol_handle_t *handle, const policydb_t *p, validate_t flavors[]) { - map_arg_t margs = { flavors, handle, p }; + map_arg_t margs = { flavors, handle, p, 0 }; if (hashtab_map(p->range_tr, validate_range_transition, &margs)) { ERR(handle, "Invalid range transition"); diff --git a/libsepol/src/write.c b/libsepol/src/write.c index a52e2e829..4ef984499 100644 --- a/libsepol/src/write.c +++ b/libsepol/src/write.c @@ -56,7 +56,8 @@ struct policy_data { }; static int avrule_write_list(policydb_t *p, - avrule_t * avrules, struct policy_file *fp); + avrule_t * avrules, struct policy_file *fp, + unsigned conditional); static int ebitmap_write(ebitmap_t * e, struct policy_file *fp) { @@ -104,7 +105,8 @@ static uint16_t spec_order[] = { static int avtab_write_item(policydb_t * p, avtab_ptr_t cur, struct policy_file *fp, - unsigned merge, unsigned commit, uint32_t * nel) + unsigned merge, unsigned commit, unsigned conditional, + uint32_t * nel) { avtab_ptr_t node; uint8_t buf8; @@ -229,14 +231,20 @@ static int avtab_write_item(policydb_t * p, return POLICYDB_ERROR; if ((p->policyvers < POLICYDB_VERSION_XPERMS_IOCTL) && (cur->key.specified & AVTAB_XPERMS)) { - ERR(fp->handle, "policy version %u does not support ioctl extended" + ERR(fp->handle, "policy version %u does not support extended" "permissions rules and one was specified", p->policyvers); return POLICYDB_ERROR; } + if (!policydb_has_cond_xperms_feature(p) && (cur->key.specified & AVTAB_XPERMS) && conditional) { + ERR(fp->handle, "policy version %u does not support extended" + "permissions rules in conditional policies and one was specified", p->policyvers); + return POLICYDB_ERROR; + } + if (p->target_platform != SEPOL_TARGET_SELINUX && (cur->key.specified & AVTAB_XPERMS)) { - ERR(fp->handle, "Target platform %s does not support ioctl " + ERR(fp->handle, "Target platform %s does not support " "extended permissions rules and one was specified", policydb_target_strings[p->target_platform]); return POLICYDB_ERROR; @@ -313,7 +321,7 @@ static int avtab_write(struct policydb *p, avtab_t * a, struct policy_file *fp) for (cur = a->htable[i]; cur; cur = cur->next) { /* If old format, compute final nel. If new format, write out the items. */ - if (avtab_write_item(p, cur, fp, 1, !oldvers, &nel)) { + if (avtab_write_item(p, cur, fp, 1, !oldvers, 0, &nel)) { rc = -1; goto out; } @@ -332,7 +340,7 @@ static int avtab_write(struct policydb *p, avtab_t * a, struct policy_file *fp) avtab_reset_merged(a); for (i = 0; i < a->nslot; i++) { for (cur = a->htable[i]; cur; cur = cur->next) { - if (avtab_write_item(p, cur, fp, 1, 1, NULL)) { + if (avtab_write_item(p, cur, fp, 1, 1, 0, NULL)) { rc = -1; goto out; } @@ -795,7 +803,7 @@ static int cond_write_av_list(policydb_t * p, for (cur_list = list; cur_list != NULL; cur_list = cur_list->next) { if (cur_list->node->parse_context) - if (avtab_write_item(p, cur_list->node, fp, 0, 1, NULL)) + if (avtab_write_item(p, cur_list->node, fp, 0, 1, 1, NULL)) goto out; } @@ -846,9 +854,9 @@ static int cond_write_node(policydb_t * p, if (cond_write_av_list(p, node->false_list, fp) != 0) return POLICYDB_ERROR; } else { - if (avrule_write_list(p, node->avtrue_list, fp)) + if (avrule_write_list(p, node->avtrue_list, fp, 1)) return POLICYDB_ERROR; - if (avrule_write_list(p, node->avfalse_list, fp)) + if (avrule_write_list(p, node->avfalse_list, fp, 1)) return POLICYDB_ERROR; } @@ -1743,7 +1751,7 @@ static int range_write(policydb_t * p, struct policy_file *fp) /************** module writing functions below **************/ static int avrule_write(policydb_t *p, avrule_t * avrule, - struct policy_file *fp) + struct policy_file *fp, unsigned conditional) { size_t items, items2; uint32_t buf[32], len; @@ -1801,15 +1809,23 @@ static int avrule_write(policydb_t *p, avrule_t * avrule, if (p->policyvers < MOD_POLICYDB_VERSION_XPERMS_IOCTL) { ERR(fp->handle, - "module policy version %u does not support ioctl" + "module policy version %u does not support" " extended permissions rules and one was specified", p->policyvers); return POLICYDB_ERROR; } + if (conditional && !policydb_has_cond_xperms_feature(p)) { + ERR(fp->handle, + "module policy version %u does not support" + " extended permissions rules in conditional policies and one was specified", + p->policyvers); + return POLICYDB_ERROR; + } + if (p->target_platform != SEPOL_TARGET_SELINUX) { ERR(fp->handle, - "Target platform %s does not support ioctl" + "Target platform %s does not support" " extended permissions rules and one was specified", policydb_target_strings[p->target_platform]); return POLICYDB_ERROR; @@ -1834,7 +1850,7 @@ static int avrule_write(policydb_t *p, avrule_t * avrule, } static int avrule_write_list(policydb_t *p, avrule_t * avrules, - struct policy_file *fp) + struct policy_file *fp, unsigned conditional) { uint32_t buf[32], len; avrule_t *avrule; @@ -1852,7 +1868,7 @@ static int avrule_write_list(policydb_t *p, avrule_t * avrules, avrule = avrules; while (avrule) { - if (avrule_write(p, avrule, fp)) + if (avrule_write(p, avrule, fp, conditional)) return POLICYDB_ERROR; avrule = avrule->next; } @@ -2056,7 +2072,7 @@ static int avrule_decl_write(avrule_decl_t * decl, int num_scope_syms, return POLICYDB_ERROR; } if (cond_write_list(p, decl->cond_list, fp) == -1 || - avrule_write_list(p, decl->avrules, fp) == -1 || + avrule_write_list(p, decl->avrules, fp, 0) == -1 || role_trans_rule_write(p, decl->role_tr_rules, fp) == -1 || role_allow_rule_write(decl->role_allow_rules, fp) == -1) { return POLICYDB_ERROR; From 439f7d986047f90f8ce61b259e73c11aca558cce Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Fri, 5 Apr 2024 15:22:51 +0200 Subject: [PATCH 3/6] checkpolicy: add support for xperms in conditional policies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for extended permission rules in conditional policies. Signed-off-by: Christian Göttsche --- v2: - resbase onto "libsepol: Support nlmsg xperms in assertions" and adjust resulting (correct) optimization difference - print extended permission range in hexadecimal --- checkpolicy/policy_define.c | 108 +++++++++++++++--- checkpolicy/policy_define.h | 1 + checkpolicy/policy_parse.y | 20 +++- checkpolicy/tests/policy_allonce.conf | 7 +- .../tests/policy_allonce.expected.conf | 10 ++ .../tests/policy_allonce.expected_opt.conf | 10 ++ 6 files changed, 141 insertions(+), 15 deletions(-) diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c index f8a10154e..3c5def9ea 100644 --- a/checkpolicy/policy_define.c +++ b/checkpolicy/policy_define.c @@ -1859,6 +1859,8 @@ int define_bool_tunable(int is_tunable) avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl) { + avrule_t *last; + if (pass == 1) { /* return something so we get through pass 1 */ return (avrule_t *) 1; @@ -1869,8 +1871,12 @@ avrule_t *define_cond_pol_list(avrule_t * avlist, avrule_t * sl) return avlist; } - /* prepend the new avlist to the pre-existing one */ - sl->next = avlist; + /* Prepend the new avlist to the pre-existing one. + * An extended permission statement might consist of multiple av + * rules. */ + for (last = sl; last->next; last = last->next) + ; + last->next = avlist; return sl; } @@ -1972,7 +1978,7 @@ static int avrule_read_xperm_ranges(struct av_xperm_range_list **rangehead) id = queue_remove(id_queue); r->range.high = (uint16_t) strtoul(id,NULL,0); if (r->range.high < r->range.low) { - yyerror2("Ioctl range %d-%d must be in ascending order.", + yyerror2("extended permission range %#x-%#x must be in ascending order.", r->range.low, r->range.high); return -1; } @@ -2454,9 +2460,9 @@ static int avrule_cpy(avrule_t *dest, const avrule_t *src) return 0; } -static int define_te_avtab_ioctl(const avrule_t *avrule_template) +static int define_te_avtab_ioctl(const avrule_t *avrule_template, avrule_t **ret_avrules) { - avrule_t *avrule; + avrule_t *avrule, *ret = NULL, **last = &ret; struct av_xperm_range_list *rangelist, *r; av_extended_perms_t *complete_driver, *partial_driver, *xperms; unsigned int i; @@ -2478,7 +2484,13 @@ static int define_te_avtab_ioctl(const avrule_t *avrule_template) if (avrule_cpy(avrule, avrule_template)) return -1; avrule->xperms = complete_driver; - append_avrule(avrule); + + if (ret_avrules) { + *last = avrule; + last = &(avrule->next); + } else { + append_avrule(avrule); + } } /* flag ioctl driver codes that are partially enabled */ @@ -2507,7 +2519,13 @@ static int define_te_avtab_ioctl(const avrule_t *avrule_template) if (avrule_cpy(avrule, avrule_template)) return -1; avrule->xperms = xperms; - append_avrule(avrule); + + if (ret_avrules) { + *last = avrule; + last = &(avrule->next); + } else { + append_avrule(avrule); + } } } @@ -2521,12 +2539,15 @@ static int define_te_avtab_ioctl(const avrule_t *avrule_template) free(r); } + if (ret_avrules) + *ret_avrules = ret; + return 0; } -static int define_te_avtab_netlink(const avrule_t *avrule_template) +static int define_te_avtab_netlink(const avrule_t *avrule_template, avrule_t **ret_avrules) { - avrule_t *avrule; + avrule_t *avrule, *ret = NULL, **last = &ret; struct av_xperm_range_list *rangelist, *r; av_extended_perms_t *partial_driver, *xperms; unsigned int i; @@ -2561,7 +2582,13 @@ static int define_te_avtab_netlink(const avrule_t *avrule_template) if (avrule_cpy(avrule, avrule_template)) return -1; avrule->xperms = xperms; - append_avrule(avrule); + + if (ret_avrules) { + *last = avrule; + last = &(avrule->next); + } else { + append_avrule(avrule); + } } } @@ -2575,9 +2602,64 @@ static int define_te_avtab_netlink(const avrule_t *avrule_template) free(r); } + if (ret_avrules) + *ret_avrules = ret; + return 0; } +avrule_t *define_cond_te_avtab_extended_perms(int which) +{ + char *id; + unsigned int i; + avrule_t *avrule_template, *rules = NULL; + int rc = 0; + + if (policydbp->policy_type == POLICY_KERN && policydbp->policyvers < POLICYDB_VERSION_COND_XPERMS) { + yyerror2("extended permissions in conditional policies are only supported since policy version %d, found policy version %d", + POLICYDB_VERSION_COND_XPERMS, policydbp->policyvers); + return COND_ERR; + } + if (policydbp->policy_type != POLICY_KERN && policydbp->policyvers < MOD_POLICYDB_VERSION_COND_XPERMS) { + yyerror2("extended permissions in conditional policies are only supported since module policy version %d, found module policy version %d", + MOD_POLICYDB_VERSION_COND_XPERMS, policydbp->policyvers); + return COND_ERR; + } + + if (pass == 1) { + for (i = 0; i < 4; i++) { + while ((id = queue_remove(id_queue))) + free(id); + } + return (avrule_t *) 1; /* any non-NULL value */ + } + + /* populate avrule template with source/target/tclass */ + if (define_te_avtab_xperms_helper(which, &avrule_template)) + return COND_ERR; + + id = queue_remove(id_queue); + if (strcmp(id, "ioctl") == 0) { + rc = define_te_avtab_ioctl(avrule_template, &rules); + } else if (strcmp(id, "nlmsg") == 0) { + rc = define_te_avtab_netlink(avrule_template, &rules); + } else { + yyerror2("only ioctl and nlmsg extended permissions are supported, found %s", id); + rc = -1; + } + + free(id); + avrule_destroy(avrule_template); + free(avrule_template); + + if (rc) { + avrule_destroy(rules); + return NULL; + } + + return rules; +} + int define_te_avtab_extended_perms(int which) { char *id; @@ -2599,11 +2681,11 @@ int define_te_avtab_extended_perms(int which) id = queue_remove(id_queue); if (strcmp(id,"ioctl") == 0) { - rc = define_te_avtab_ioctl(avrule_template); + rc = define_te_avtab_ioctl(avrule_template, NULL); } else if (strcmp(id,"nlmsg") == 0) { - rc = define_te_avtab_netlink(avrule_template); + rc = define_te_avtab_netlink(avrule_template, NULL); } else { - yyerror2("only ioctl extended permissions are supported, found %s", id); + yyerror2("only ioctl and nlmsg extended permissions are supported, found %s", id); rc = -1; } diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h index ef74f6169..216da3ad6 100644 --- a/checkpolicy/policy_define.h +++ b/checkpolicy/policy_define.h @@ -15,6 +15,7 @@ avrule_t *define_cond_compute_type(int which); avrule_t *define_cond_pol_list(avrule_t *avlist, avrule_t *sl); avrule_t *define_cond_te_avtab(int which); +avrule_t *define_cond_te_avtab_extended_perms(int which); avrule_t *define_cond_filename_trans(void); cond_expr_t *define_cond_expr(uint32_t expr_type, void *arg1, void* arg2); int define_attrib(void); diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y index ed1786d80..7e1172226 100644 --- a/checkpolicy/policy_parse.y +++ b/checkpolicy/policy_parse.y @@ -74,6 +74,7 @@ typedef int (* require_func_t)(int pass); %type cond_expr cond_expr_prim cond_pol_list cond_else %type cond_allow_def cond_auditallow_def cond_auditdeny_def cond_dontaudit_def +%type cond_xperm_allow_def cond_xperm_auditallow_def cond_xperm_dontaudit_def %type cond_transition_def cond_te_avtab_def cond_rule_def %type cexpr cexpr_prim op role_mls_op %type ipv4_addr_def number @@ -432,6 +433,12 @@ cond_te_avtab_def : cond_allow_def { $$ = $1; } | cond_dontaudit_def { $$ = $1; } + | cond_xperm_allow_def + { $$ = $1; } + | cond_xperm_auditallow_def + { $$ = $1; } + | cond_xperm_dontaudit_def + { $$ = $1; } ; cond_allow_def : ALLOW names names ':' names names ';' { $$ = define_cond_te_avtab(AVRULE_ALLOWED) ; @@ -449,7 +456,18 @@ cond_dontaudit_def : DONTAUDIT names names ':' names names ';' { $$ = define_cond_te_avtab(AVRULE_DONTAUDIT); if ($$ == COND_ERR) YYABORT; } ; - ; +cond_xperm_allow_def : ALLOWXPERM names names ':' names identifier xperms ';' + { $$ = define_cond_te_avtab_extended_perms(AVRULE_XPERMS_ALLOWED) ; + if ($$ == COND_ERR) YYABORT; } + ; +cond_xperm_auditallow_def : AUDITALLOWXPERM names names ':' names identifier xperms ';' + { $$ = define_cond_te_avtab_extended_perms(AVRULE_XPERMS_AUDITALLOW) ; + if ($$ == COND_ERR) YYABORT; } + ; +cond_xperm_dontaudit_def : DONTAUDITXPERM names names ':' names identifier xperms ';' + { $$ = define_cond_te_avtab_extended_perms(AVRULE_XPERMS_DONTAUDIT) ; + if ($$ == COND_ERR) YYABORT; } + ; transition_def : TYPE_TRANSITION names names ':' names identifier filename ';' {if (define_filename_trans()) YYABORT; } | TYPE_TRANSITION names names ':' names identifier ';' diff --git a/checkpolicy/tests/policy_allonce.conf b/checkpolicy/tests/policy_allonce.conf index 2cfbb7723..51a8c40aa 100644 --- a/checkpolicy/tests/policy_allonce.conf +++ b/checkpolicy/tests/policy_allonce.conf @@ -2,6 +2,7 @@ class CLASS1 class CLASS2 class CLASS3 +class CLASS4 class dir class file class process @@ -10,6 +11,7 @@ common COMMON1 { CPERM1 } class CLASS1 { PERM1 ioctl } class CLASS2 inherits COMMON1 class CLASS3 inherits COMMON1 { PERM1 } +class CLASS4 { nlmsg } default_user { CLASS1 } source; default_role { CLASS2 } target; default_type { CLASS3 } source; @@ -26,6 +28,7 @@ typealias TYPE1 alias TYPEALIAS1; typeattribute TYPE1 ATTR1; typebounds TYPE4 TYPE3; bool BOOL1 true; +bool BOOL2 false; tunable TUNABLE1 false; tunable TUNABLE2 true; type_transition TYPE1 TYPE2 : CLASS1 TYPE3; @@ -37,6 +40,7 @@ auditallow { TYPE1 TYPE2 } TYPE3 : CLASS1 { PERM1 }; dontaudit TYPE1 { TYPE2 TYPE3 } : CLASS3 { PERM1 CPERM1 }; neverallow TYPE1 TYPE2 : { CLASS2 CLASS3 } { CPERM1 }; allowxperm TYPE1 TYPE2 : CLASS1 ioctl { 0x456-0x5678 }; +allowxperm TYPE2 TYPE1 : CLASS4 nlmsg { 0x1 0x12 }; auditallowxperm TYPE1 TYPE2 : CLASS1 ioctl 0x2; dontauditxperm TYPE1 TYPE2 : CLASS1 ioctl 0x3; neverallowxperm TYPE1 TYPE2 : CLASS1 ioctl 0x4; @@ -50,7 +54,8 @@ role_transition ROLE1 TYPE1 : CLASS1 ROLE2; allow ROLE1 ROLE2; roleattribute ROLE3 ROLE_ATTR1; role ROLE1 types { TYPE1 }; -if ! BOOL1 { allow TYPE1 self: CLASS1 *; } +if ! BOOL1 { allow TYPE1 self: CLASS1 *; dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x6789 - 0x9876 }; } +if BOOL2 { allowxperm TYPE2 TYPE1:CLASS4 nlmsg { 0x1 0x2 }; } if TUNABLE1 xor TUNABLE2 { allow TYPE1 self: CLASS2 *; } else { allow TYPE1 self: CLASS3 *; } optional { require { class CLASS2 { CPERM1 }; } allow TYPE1 self: CLASS2 *; } user USER1 roles ROLE1; diff --git a/checkpolicy/tests/policy_allonce.expected.conf b/checkpolicy/tests/policy_allonce.expected.conf index 26d564382..355d99913 100644 --- a/checkpolicy/tests/policy_allonce.expected.conf +++ b/checkpolicy/tests/policy_allonce.expected.conf @@ -2,6 +2,7 @@ class CLASS1 class CLASS2 class CLASS3 +class CLASS4 class dir class file class process @@ -10,6 +11,7 @@ common COMMON1 { CPERM1 } class CLASS1 { PERM1 ioctl } class CLASS2 inherits COMMON1 class CLASS3 inherits COMMON1 { PERM1 } +class CLASS4 { nlmsg } default_user { CLASS1 } source; default_role { CLASS2 } target; default_type { CLASS3 } source; @@ -17,6 +19,7 @@ policycap open_perms; attribute ATTR1; attribute ATTR2; bool BOOL1 true; +bool BOOL2 false; type TYPE1; type TYPE2; type TYPE3; @@ -37,6 +40,7 @@ dontaudit TYPE1 TYPE3:CLASS3 { CPERM1 PERM1 }; allowxperm TYPE1 TYPE2:CLASS1 ioctl { 0x456-0x4ff }; allowxperm TYPE1 TYPE2:CLASS1 ioctl { 0x500-0x55ff }; allowxperm TYPE1 TYPE2:CLASS1 ioctl { 0x5600-0x5678 }; +allowxperm TYPE2 TYPE1:CLASS4 nlmsg { 0x1 0x12 }; auditallowxperm TYPE1 TYPE2:CLASS1 ioctl { 0x2 }; dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x3 }; type_transition TYPE1 TYPE2:CLASS1 TYPE3; @@ -49,6 +53,12 @@ type_transition TYPE2 TYPE4:CLASS1 TYPE1 "FILENAME"; if (BOOL1) { } else { allow TYPE1 self:CLASS1 { PERM1 ioctl }; + dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x6789-0x67ff }; + dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x6800-0x97ff }; + dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x9800-0x9876 }; +} +if (BOOL2) { + allowxperm TYPE2 TYPE1:CLASS4 nlmsg { 0x1-0x2 }; } role ROLE1; role ROLE2; diff --git a/checkpolicy/tests/policy_allonce.expected_opt.conf b/checkpolicy/tests/policy_allonce.expected_opt.conf index 769be2b3a..74eec4ba6 100644 --- a/checkpolicy/tests/policy_allonce.expected_opt.conf +++ b/checkpolicy/tests/policy_allonce.expected_opt.conf @@ -2,6 +2,7 @@ class CLASS1 class CLASS2 class CLASS3 +class CLASS4 class dir class file class process @@ -10,6 +11,7 @@ common COMMON1 { CPERM1 } class CLASS1 { PERM1 ioctl } class CLASS2 inherits COMMON1 class CLASS3 inherits COMMON1 { PERM1 } +class CLASS4 { nlmsg } default_user { CLASS1 } source; default_role { CLASS2 } target; default_type { CLASS3 } source; @@ -17,6 +19,7 @@ policycap open_perms; attribute ATTR1; attribute ATTR2; bool BOOL1 true; +bool BOOL2 false; type TYPE1; type TYPE2; type TYPE3; @@ -37,6 +40,7 @@ dontaudit TYPE1 TYPE3:CLASS3 { CPERM1 PERM1 }; allowxperm TYPE1 TYPE2:CLASS1 ioctl { 0x456-0x4ff }; allowxperm TYPE1 TYPE2:CLASS1 ioctl { 0x500-0x55ff }; allowxperm TYPE1 TYPE2:CLASS1 ioctl { 0x5600-0x5678 }; +allowxperm TYPE2 TYPE1:CLASS4 nlmsg { 0x1 0x12 }; auditallowxperm TYPE1 TYPE2:CLASS1 ioctl { 0x2 }; dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x3 }; type_transition TYPE1 TYPE2:CLASS1 TYPE3; @@ -49,6 +53,12 @@ type_transition TYPE2 TYPE4:CLASS1 TYPE1 "FILENAME"; if (BOOL1) { } else { allow TYPE1 self:CLASS1 { ioctl }; + dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x6789-0x67ff }; + dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x6800-0x97ff }; + dontauditxperm TYPE1 TYPE2:CLASS1 ioctl { 0x9800-0x9876 }; +} +if (BOOL2) { + allowxperm TYPE2 TYPE1:CLASS4 nlmsg { 0x2 }; } role ROLE1; role ROLE2; From 11189b47a3a16b04f13d8c916f3edb57f2506322 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Fri, 5 Apr 2024 15:22:55 +0200 Subject: [PATCH 4/6] libsepol/cil: add support for xperms in conditional policies MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add support for extended permission rules in conditional policies. Signed-off-by: Christian Göttsche --- libsepol/cil/src/cil_binary.c | 153 +++++++++++++++++++++++++---- libsepol/cil/src/cil_build_ast.c | 6 +- libsepol/cil/src/cil_resolve_ast.c | 6 +- libsepol/cil/src/cil_verify.c | 3 +- secilc/test/policy.cil | 13 ++- 5 files changed, 153 insertions(+), 28 deletions(-) diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c index 3d9201822..070bf5253 100644 --- a/libsepol/cil/src/cil_binary.c +++ b/libsepol/cil/src/cil_binary.c @@ -59,14 +59,18 @@ #define AVRULEX_TABLE_SIZE (1 << 10) #define PERMS_PER_CLASS 32 +struct cil_args_xperm_tables { + hashtab_t ioctl; + hashtab_t nlmsg; +}; + struct cil_args_binary { const struct cil_db *db; policydb_t *pdb; struct cil_list *neverallows; int pass; hashtab_t role_trans_table; - hashtab_t avrulex_ioctl_table; - hashtab_t avrulex_nlmsg_table; + struct cil_args_xperm_tables avrulex_xperm_tables; void **type_value_to_cil; }; @@ -75,8 +79,14 @@ struct cil_args_booleanif { policydb_t *pdb; cond_node_t *cond_node; enum cil_flavor cond_flavor; + struct cil_args_xperm_tables avrulex_xperm_tables; }; +static unsigned int avrulex_hash(__attribute__((unused)) hashtab_t h, const_hashtab_key_t key); +static int avrulex_compare(hashtab_t h + __attribute__ ((unused)), const_hashtab_key_t key1, + const_hashtab_key_t key2); + static int __cil_get_sepol_user_datum(policydb_t *pdb, struct cil_symtab_datum *datum, user_datum_t **sepol_user) { *sepol_user = hashtab_search(pdb->p_users.table, datum->fqn); @@ -1758,7 +1768,10 @@ static int __cil_permx_bitmap_to_sepol_xperms_list(uint32_t kind, ebitmap_t *xpe static int __cil_avrulex_xperm_to_policydb(hashtab_key_t k, hashtab_datum_t datum, uint32_t xperm_kind, void *args) { int rc = SEPOL_OK; - struct policydb *pdb; + struct cil_args_booleanif *booleanif_args = args; + struct policydb *pdb = booleanif_args->pdb; + cond_node_t *cond_node = booleanif_args->cond_node; + enum cil_flavor cond_flavor = booleanif_args->cond_flavor; avtab_key_t *avtab_key; avtab_datum_t avtab_datum; struct cil_list *xperms_list = NULL; @@ -1768,7 +1781,6 @@ static int __cil_avrulex_xperm_to_policydb(hashtab_key_t k, hashtab_datum_t datu char *kind = NULL; avtab_key = (avtab_key_t *)k; - pdb = args; sepol_obj = pdb->class_val_to_struct[avtab_key->target_class - 1]; @@ -1789,7 +1801,12 @@ static int __cil_avrulex_xperm_to_policydb(hashtab_key_t k, hashtab_datum_t datu cil_list_for_each(item, xperms_list) { avtab_datum.xperms = item->data; - rc = avtab_insert(&pdb->te_avtab, avtab_key, &avtab_datum); + + if (cond_node) { + rc = __cil_cond_insert_rule(&pdb->te_cond_avtab, avtab_key, &avtab_datum, cond_node, cond_flavor); + } else { + rc = avtab_insert(&pdb->te_avtab, avtab_key, &avtab_datum); + } if (rc != SEPOL_OK) { goto exit; } @@ -1872,7 +1889,7 @@ static int __cil_avrulex_xperm_to_hashtable(hashtab_t h, uint16_t kind, uint32_t return rc; } -static int __cil_avrulex_to_hashtable_helper(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_permissionx *permx, struct cil_args_binary *args) +static int __cil_avrulex_to_hashtable_helper(policydb_t *pdb, uint16_t kind, struct cil_symtab_datum *src, struct cil_symtab_datum *tgt, struct cil_permissionx *permx, struct cil_args_xperm_tables *xt) { int rc = SEPOL_ERR; type_datum_t *sepol_src = NULL; @@ -1895,11 +1912,11 @@ static int __cil_avrulex_to_hashtable_helper(policydb_t *pdb, uint16_t kind, str switch (permx->kind) { case CIL_PERMX_KIND_IOCTL: - rc = __cil_avrulex_xperm_to_hashtable(args->avrulex_ioctl_table, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms); + rc = __cil_avrulex_xperm_to_hashtable(xt->ioctl, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms); if (rc != SEPOL_OK) goto exit; break; case CIL_PERMX_KIND_NLMSG: - rc = __cil_avrulex_xperm_to_hashtable(args->avrulex_nlmsg_table, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms); + rc = __cil_avrulex_xperm_to_hashtable(xt->nlmsg, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, permx->perms); if (rc != SEPOL_OK) goto exit; break; default: @@ -1916,7 +1933,7 @@ static int __cil_avrulex_to_hashtable_helper(policydb_t *pdb, uint16_t kind, str return rc; } -static int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrulex, struct cil_args_binary *args) +static int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrulex, struct cil_args_xperm_tables *xt) { int rc = SEPOL_ERR; uint16_t kind; @@ -1942,7 +1959,7 @@ static int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, st ebitmap_for_each_positive_bit(&src_bitmap, snode, s) { src = DATUM(db->val_to_type[s]); - rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, src, cil_avrulex->perms.x.permx, args); + rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, src, cil_avrulex->perms.x.permx, xt); if (rc != SEPOL_OK) { ebitmap_destroy(&src_bitmap); goto exit; @@ -1960,7 +1977,7 @@ static int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, st for (t = 0; t < (unsigned int)db->num_types; t++) { if (s != t) { tgt = DATUM(db->val_to_type[t]); - rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); + rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, xt); if (rc != SEPOL_OK) { ebitmap_destroy(&src_bitmap); goto exit; @@ -1980,7 +1997,7 @@ static int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, st ebitmap_for_each_positive_bit(&src_bitmap, tnode, t) { if (s != t) { tgt = DATUM(db->val_to_type[t]); - rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); + rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, xt); if (rc != SEPOL_OK) { ebitmap_destroy(&src_bitmap); goto exit; @@ -1994,7 +2011,7 @@ static int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, st int expand_tgt = __cil_should_expand_attribute(db, tgt); if (!expand_src && !expand_tgt) { - rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); + rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, xt); if (rc != SEPOL_OK) { goto exit; } @@ -2015,7 +2032,7 @@ static int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, st ebitmap_for_each_positive_bit(&tgt_bitmap, tnode, t) { tgt = DATUM(db->val_to_type[t]); - rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); + rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, xt); if (rc != SEPOL_OK) { ebitmap_destroy(&src_bitmap); ebitmap_destroy(&tgt_bitmap); @@ -2034,7 +2051,7 @@ static int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, st ebitmap_for_each_positive_bit(&src_bitmap, snode, s) { src = DATUM(db->val_to_type[s]); - rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); + rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, xt); if (rc != SEPOL_OK) { ebitmap_destroy(&src_bitmap); goto exit; @@ -2050,7 +2067,7 @@ static int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, st ebitmap_for_each_positive_bit(&tgt_bitmap, tnode, t) { tgt = DATUM(db->val_to_type[t]); - rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args); + rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, xt); if (rc != SEPOL_OK) { ebitmap_destroy(&tgt_bitmap); goto exit; @@ -2119,6 +2136,21 @@ static int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute goto exit; } break; + case CIL_AVRULEX: + if (db->policy_version < POLICYDB_VERSION_COND_XPERMS) { + cil_tree_log(node, CIL_ERR, "Extended permission rules are not supported in policy version %d\n", + db->policy_version); + rc = SEPOL_ERR; + goto exit; + } + cil_avrule = node->data; + rc = cil_avrulex_to_hashtable(pdb, db, cil_avrule, &args->avrulex_xperm_tables); + if (rc != SEPOL_OK) { + cil_tree_log(node, CIL_ERR, "Failed to insert avrulex into avtab"); + goto exit; + } + break; + case CIL_CALL: case CIL_TUNABLEIF: break; @@ -2425,6 +2457,8 @@ int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c int was_created; int swapped = CIL_FALSE; cond_av_list_t tmp_cl; + hashtab_t avrulex_ioctl_table = NULL; + hashtab_t avrulex_nlmsg_table = NULL; tmp_cond = cond_node_create(pdb, NULL); if (tmp_cond == NULL) { @@ -2493,26 +2527,97 @@ int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c bool_args.cond_node = cond_node; if (true_node != NULL) { + avrulex_ioctl_table = hashtab_create(avrulex_hash, avrulex_compare, AVRULEX_TABLE_SIZE); + if (!avrulex_ioctl_table) { + cil_log(CIL_INFO, "Failure to create hashtab for avrulex\n"); + goto exit; + } + + avrulex_nlmsg_table = hashtab_create(avrulex_hash, avrulex_compare, AVRULEX_TABLE_SIZE); + if (!avrulex_nlmsg_table) { + cil_log(CIL_INFO, "Failure to create hashtab for avrulex\n"); + goto exit; + } + bool_args.cond_flavor = CIL_CONDTRUE; + bool_args.avrulex_xperm_tables.ioctl = avrulex_ioctl_table; + bool_args.avrulex_xperm_tables.nlmsg = avrulex_nlmsg_table; rc = cil_tree_walk(true_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args); if (rc != SEPOL_OK) { cil_tree_log(true_node, CIL_ERR, "Failure while walking true conditional block"); goto exit; } + + rc = hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_to_policydb, &bool_args); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failure creating avrulex rules\n"); + goto exit; + } + + rc = hashtab_map(avrulex_nlmsg_table, __cil_avrulex_nlmsg_to_policydb, &bool_args); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failure creating avrulex rules\n"); + goto exit; + } + + hashtab_map(avrulex_nlmsg_table, __cil_avrulex_xperm_destroy, NULL); + hashtab_destroy(avrulex_nlmsg_table); + avrulex_nlmsg_table = NULL; + + hashtab_map(avrulex_ioctl_table, __cil_avrulex_xperm_destroy, NULL); + hashtab_destroy(avrulex_ioctl_table); + avrulex_ioctl_table = NULL; } if (false_node != NULL) { + avrulex_ioctl_table = hashtab_create(avrulex_hash, avrulex_compare, AVRULEX_TABLE_SIZE); + if (!avrulex_ioctl_table) { + cil_log(CIL_INFO, "Failure to create hashtab for avrulex\n"); + goto exit; + } + + avrulex_nlmsg_table = hashtab_create(avrulex_hash, avrulex_compare, AVRULEX_TABLE_SIZE); + if (!avrulex_nlmsg_table) { + cil_log(CIL_INFO, "Failure to create hashtab for avrulex\n"); + goto exit; + } + bool_args.cond_flavor = CIL_CONDFALSE; + bool_args.avrulex_xperm_tables.ioctl = avrulex_ioctl_table; + bool_args.avrulex_xperm_tables.nlmsg = avrulex_nlmsg_table; rc = cil_tree_walk(false_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args); if (rc != SEPOL_OK) { cil_tree_log(false_node, CIL_ERR, "Failure while walking false conditional block"); goto exit; } + + rc = hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_to_policydb, &bool_args); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failure creating avrulex rules\n"); + goto exit; + } + + rc = hashtab_map(avrulex_nlmsg_table, __cil_avrulex_nlmsg_to_policydb, &bool_args); + if (rc != SEPOL_OK) { + cil_log(CIL_INFO, "Failure creating avrulex rules\n"); + goto exit; + } + + hashtab_map(avrulex_nlmsg_table, __cil_avrulex_xperm_destroy, NULL); + hashtab_destroy(avrulex_nlmsg_table); + avrulex_nlmsg_table = NULL; + + + hashtab_map(avrulex_ioctl_table, __cil_avrulex_xperm_destroy, NULL); + hashtab_destroy(avrulex_ioctl_table); + avrulex_ioctl_table = NULL; } return SEPOL_OK; exit: + hashtab_map(avrulex_ioctl_table, __cil_avrulex_xperm_destroy, NULL); + hashtab_destroy(avrulex_ioctl_table); if (tmp_cond) { if (tmp_cond->expr) cond_expr_destroy(tmp_cond->expr); @@ -4087,7 +4192,7 @@ static int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args) case CIL_AVRULEX: { struct cil_avrule *rule = node->data; if (rule->rule_kind != CIL_AVRULE_NEVERALLOW) { - rc = cil_avrulex_to_hashtable(pdb, db, node->data, args); + rc = cil_avrulex_to_hashtable(pdb, db, node->data, &args->avrulex_xperm_tables); } } break; @@ -5158,6 +5263,7 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p int rc = SEPOL_ERR; int i; struct cil_args_binary extra_args; + struct cil_args_booleanif booleanif_args; policydb_t *pdb = &policydb->p; struct cil_list *neverallows = NULL; hashtab_t role_trans_table = NULL; @@ -5222,10 +5328,15 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p extra_args.pdb = pdb; extra_args.neverallows = neverallows; extra_args.role_trans_table = role_trans_table; - extra_args.avrulex_ioctl_table = avrulex_ioctl_table; - extra_args.avrulex_nlmsg_table = avrulex_nlmsg_table; + extra_args.avrulex_xperm_tables.ioctl = avrulex_ioctl_table; + extra_args.avrulex_xperm_tables.nlmsg = avrulex_nlmsg_table; extra_args.type_value_to_cil = type_value_to_cil; + booleanif_args.db = db; + booleanif_args.pdb = pdb; + booleanif_args.cond_node = NULL; + booleanif_args.cond_flavor = CIL_NONE; + for (i = 1; i <= 3; i++) { extra_args.pass = i; @@ -5244,12 +5355,12 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p } if (i == 3) { - rc = hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_to_policydb, pdb); + rc = hashtab_map(avrulex_ioctl_table, __cil_avrulex_ioctl_to_policydb, &booleanif_args); if (rc != SEPOL_OK) { cil_log(CIL_INFO, "Failure creating avrulex rules\n"); goto exit; } - rc = hashtab_map(avrulex_nlmsg_table, __cil_avrulex_nlmsg_to_policydb, pdb); + rc = hashtab_map(avrulex_nlmsg_table, __cil_avrulex_nlmsg_to_policydb, &booleanif_args); if (rc != SEPOL_OK) { cil_log(CIL_INFO, "Failure creating avrulex rules\n"); goto exit; diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c index 19fbb04e0..8cc3f9b26 100644 --- a/libsepol/cil/src/cil_build_ast.c +++ b/libsepol/cil/src/cil_build_ast.c @@ -6158,7 +6158,11 @@ static int check_for_illegal_statement(struct cil_tree_node *parse_current, stru parse_current->data != CIL_KEY_AUDITALLOW && parse_current->data != CIL_KEY_TYPETRANSITION && parse_current->data != CIL_KEY_TYPECHANGE && - parse_current->data != CIL_KEY_TYPEMEMBER) { + parse_current->data != CIL_KEY_TYPEMEMBER && + ((args->db->policy_version < POLICYDB_VERSION_COND_XPERMS) || + (parse_current->data != CIL_KEY_ALLOWX && + parse_current->data != CIL_KEY_DONTAUDITX && + parse_current->data != CIL_KEY_AUDITALLOWX))) { if (((struct cil_booleanif*)args->boolif->data)->preserved_tunable) { cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in tunableif being treated as a booleanif", (char *)parse_current->data); } else { diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c index da8863c4c..a8fa89df3 100644 --- a/libsepol/cil/src/cil_resolve_ast.c +++ b/libsepol/cil/src/cil_resolve_ast.c @@ -3848,9 +3848,11 @@ static int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *f node->flavor != CIL_CONDBLOCK && node->flavor != CIL_AVRULE && node->flavor != CIL_TYPE_RULE && - node->flavor != CIL_NAMETYPETRANSITION) { + node->flavor != CIL_NAMETYPETRANSITION && + ((args->db->policy_version < POLICYDB_VERSION_COND_XPERMS) || + (node->flavor != CIL_AVRULEX))) { rc = SEPOL_ERR; - } else if (node->flavor == CIL_AVRULE) { + } else if (node->flavor == CIL_AVRULE || node->flavor == CIL_AVRULEX) { struct cil_avrule *rule = node->data; if (rule->rule_kind == CIL_AVRULE_NEVERALLOW) { rc = SEPOL_ERR; diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c index 9621a2478..550b4542f 100644 --- a/libsepol/cil/src/cil_verify.c +++ b/libsepol/cil/src/cil_verify.c @@ -1101,7 +1101,8 @@ static int __cil_verify_booleanif_helper(struct cil_tree_node *node, __attribute struct cil_booleanif *bif = node->parent->parent->data; switch (rule_node->flavor) { - case CIL_AVRULE: { + case CIL_AVRULE: + case CIL_AVRULEX: { struct cil_avrule *avrule = NULL; avrule = rule_node->data; if (avrule->rule_kind == CIL_AVRULE_NEVERALLOW) { diff --git a/secilc/test/policy.cil b/secilc/test/policy.cil index e6b78618f..d0d52d0de 100644 --- a/secilc/test/policy.cil +++ b/secilc/test/policy.cil @@ -47,8 +47,9 @@ (block policy (class file (execute_no_trans entrypoint execmod open audit_access a b c d e)) - ; order should be: file char b c a dir d e f - (classorder (file char)) + (class socket (nlmsg)) + ; order should be: file socket char b c a dir d e f + (classorder (file socket char)) (classorder (unordered dir)) (classorder (unordered c a b d e f)) (classorder (char b c a)) @@ -161,7 +162,10 @@ ;;(allow bad_t not_bad_type (file (execute))) ;;(allow bad_t exec_t (file (execute))) (neverallow bad_t not_bad_type (file (execute))) - + + (auditallowx getty_t console_device_t (ioctl file (range 0x1000 0x10FF))) + (auditallowx getty_t kernel_t (nlmsg socket (range 0x1000 0x10FF))) + (booleanif secure_mode (true (auditallow device_t exec_t (file (read write))) @@ -172,9 +176,12 @@ (true (typechange auditadm_t console_device_t file user_tty_device_t) (allow getty_t console_device_t (file (getattr open read write append))) + (auditallowx getty_t console_device_t (ioctl file (range 0x2000 0x21FF))) + (auditallowx getty_t kernel_t (nlmsg socket (0x1))) ) (false (dontaudit getty_t console_device_t (file (getattr open read write append))) + (dontauditx getty_t console_device_t (ioctl file (range 0x3000 0x31FF))) ) ) From 695bfa6868d0aa65238ac6f48972fb132b049d5c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Fri, 25 Oct 2024 17:45:28 +0200 Subject: [PATCH 5/6] libsepol: indent printed allow rule on assertion failure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Indent the printed allow rule that triggered an assertion by two spaces to improve readability. Signed-off-by: Christian Göttsche --- v3: add patch --- libsepol/src/assertion.c | 8 +-- libsepol/tests/test-neverallow.c | 100 +++++++++++++++---------------- 2 files changed, 54 insertions(+), 54 deletions(-) diff --git a/libsepol/src/assertion.c b/libsepol/src/assertion.c index 4028a33d6..ca4cae25a 100644 --- a/libsepol/src/assertion.c +++ b/libsepol/src/assertion.c @@ -201,7 +201,7 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle, permstring = sepol_extended_perms_to_string(&error); ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n" - "allowxperm %s %s:%s %s;", + " allowxperm %s %s:%s %s;", narule->source_line, narule->source_filename, narule->line, policy_name(p), p->p_type_val_to_name[i], p->p_type_val_to_name[j], @@ -247,7 +247,7 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle, permstring = sepol_extended_perms_to_string(&error); ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n" - "allowxperm %s %s:%s %s;", + " allowxperm %s %s:%s %s;", narule->source_line, narule->source_filename, narule->line, policy_name(p), p->p_type_val_to_name[i], p->p_type_val_to_name[j], @@ -289,7 +289,7 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle, permstring = sepol_extended_perms_to_string(&error); ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n" - "allowxperm %s %s:%s %s;", + " allowxperm %s %s:%s %s;", narule->source_line, narule->source_filename, narule->line, policy_name(p), p->p_type_val_to_name[i], p->p_type_val_to_name[j], @@ -314,7 +314,7 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle, char *permstr = sepol_av_to_string(p, curperm->tclass, perms); ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of %s) violated by\n" - "allow %s %s:%s {%s };", + " allow %s %s:%s {%s };", narule->source_line, narule->source_filename, narule->line, policy_name(p), p->p_type_val_to_name[stype], p->p_type_val_to_name[ttype], diff --git a/libsepol/tests/test-neverallow.c b/libsepol/tests/test-neverallow.c index 7d6ad00e2..80f91bf58 100644 --- a/libsepol/tests/test-neverallow.c +++ b/libsepol/tests/test-neverallow.c @@ -112,18 +112,18 @@ static void test_neverallow_basic(void) "neverallow on line 144 of policies/test-neverallow/policy.conf.std (or line 144 of policies/test-neverallow/policy.conf.std) violated by allow test12_3_t test12_1_t:file { open };", "neverallow on line 144 of policies/test-neverallow/policy.conf.std (or line 144 of policies/test-neverallow/policy.conf.std) violated by allow test12_2_t test12_1_t:file { open };", "neverallow on line 156 of policies/test-neverallow/policy.conf.std (or line 156 of policies/test-neverallow/policy.conf.std) violated by allow test13_1_t test13_1_t:file { read };", - "neverallowxperm on line 174 of policies/test-neverallow/policy.conf.std (or line 174 of policies/test-neverallow/policy.conf.std) violated by\nallow test15_t test15_t:file { ioctl };", - "neverallowxperm on line 182 of policies/test-neverallow/policy.conf.std (or line 182 of policies/test-neverallow/policy.conf.std) violated by\nallowxperm test16_t test16_t:file ioctl { 0x1111 };", - "neverallowxperm on line 198 of policies/test-neverallow/policy.conf.std (or line 198 of policies/test-neverallow/policy.conf.std) violated by\nallowxperm test18_t test18_t:file ioctl { 0x1111 };", - "neverallowxperm on line 206 of policies/test-neverallow/policy.conf.std (or line 206 of policies/test-neverallow/policy.conf.std) violated by\nallowxperm test19_t test19_t:file ioctl { 0x1111 };", - "neverallowxperm on line 216 of policies/test-neverallow/policy.conf.std (or line 216 of policies/test-neverallow/policy.conf.std) violated by\nallowxperm test20_a test20_a:file ioctl { 0x1111 };", - "neverallowxperm on line 227 of policies/test-neverallow/policy.conf.std (or line 227 of policies/test-neverallow/policy.conf.std) violated by\nallowxperm test21_1_a test21_2_a:file ioctl { 0x1111 };", - "neverallowxperm on line 237 of policies/test-neverallow/policy.conf.std (or line 237 of policies/test-neverallow/policy.conf.std) violated by\nallowxperm test22_t test22_t:file ioctl { 0x1111 };", - "neverallowxperm on line 247 of policies/test-neverallow/policy.conf.std (or line 247 of policies/test-neverallow/policy.conf.std) violated by\nallowxperm test23_t test23_t:file ioctl { 0x1111 };", - "neverallowxperm on line 257 of policies/test-neverallow/policy.conf.std (or line 257 of policies/test-neverallow/policy.conf.std) violated by\nallowxperm test24_t test24_a:file ioctl { 0x1111 };", - "neverallowxperm on line 267 of policies/test-neverallow/policy.conf.std (or line 267 of policies/test-neverallow/policy.conf.std) violated by\nallowxperm test25_t test25_t:file ioctl { 0x1111 };", - "neverallowxperm on line 277 of policies/test-neverallow/policy.conf.std (or line 277 of policies/test-neverallow/policy.conf.std) violated by\nallowxperm test26_a test26_a:file ioctl { 0x1111 };", - "neverallowxperm on line 277 of policies/test-neverallow/policy.conf.std (or line 277 of policies/test-neverallow/policy.conf.std) violated by\nallowxperm test26_a test26_a:file ioctl { 0x1111 };", + "neverallowxperm on line 174 of policies/test-neverallow/policy.conf.std (or line 174 of policies/test-neverallow/policy.conf.std) violated by\n allow test15_t test15_t:file { ioctl };", + "neverallowxperm on line 182 of policies/test-neverallow/policy.conf.std (or line 182 of policies/test-neverallow/policy.conf.std) violated by\n allowxperm test16_t test16_t:file ioctl { 0x1111 };", + "neverallowxperm on line 198 of policies/test-neverallow/policy.conf.std (or line 198 of policies/test-neverallow/policy.conf.std) violated by\n allowxperm test18_t test18_t:file ioctl { 0x1111 };", + "neverallowxperm on line 206 of policies/test-neverallow/policy.conf.std (or line 206 of policies/test-neverallow/policy.conf.std) violated by\n allowxperm test19_t test19_t:file ioctl { 0x1111 };", + "neverallowxperm on line 216 of policies/test-neverallow/policy.conf.std (or line 216 of policies/test-neverallow/policy.conf.std) violated by\n allowxperm test20_a test20_a:file ioctl { 0x1111 };", + "neverallowxperm on line 227 of policies/test-neverallow/policy.conf.std (or line 227 of policies/test-neverallow/policy.conf.std) violated by\n allowxperm test21_1_a test21_2_a:file ioctl { 0x1111 };", + "neverallowxperm on line 237 of policies/test-neverallow/policy.conf.std (or line 237 of policies/test-neverallow/policy.conf.std) violated by\n allowxperm test22_t test22_t:file ioctl { 0x1111 };", + "neverallowxperm on line 247 of policies/test-neverallow/policy.conf.std (or line 247 of policies/test-neverallow/policy.conf.std) violated by\n allowxperm test23_t test23_t:file ioctl { 0x1111 };", + "neverallowxperm on line 257 of policies/test-neverallow/policy.conf.std (or line 257 of policies/test-neverallow/policy.conf.std) violated by\n allowxperm test24_t test24_a:file ioctl { 0x1111 };", + "neverallowxperm on line 267 of policies/test-neverallow/policy.conf.std (or line 267 of policies/test-neverallow/policy.conf.std) violated by\n allowxperm test25_t test25_t:file ioctl { 0x1111 };", + "neverallowxperm on line 277 of policies/test-neverallow/policy.conf.std (or line 277 of policies/test-neverallow/policy.conf.std) violated by\n allowxperm test26_a test26_a:file ioctl { 0x1111 };", + "neverallowxperm on line 277 of policies/test-neverallow/policy.conf.std (or line 277 of policies/test-neverallow/policy.conf.std) violated by\n allowxperm test26_a test26_a:file ioctl { 0x1111 };", }; if (policydb_init(&base_expanded)) @@ -174,25 +174,25 @@ static void test_neverallow_minus_self(void) "neverallow on line 175 of policies/test-neverallow/policy_minus_self.conf.std (or line 175 of policies/test-neverallow/policy_minus_self.conf.std) violated by allow test14_1_t test14_2_t:file { read };", "neverallow on line 193 of policies/test-neverallow/policy_minus_self.conf.std (or line 193 of policies/test-neverallow/policy_minus_self.conf.std) violated by allow test16_2_t test16_1_t:file { read };", "neverallow on line 193 of policies/test-neverallow/policy_minus_self.conf.std (or line 193 of policies/test-neverallow/policy_minus_self.conf.std) violated by allow test16_1_t test16_2_t:file { read };", - "neverallowxperm on line 201 of policies/test-neverallow/policy_minus_self.conf.std (or line 201 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallow test17_1_t test17_2_t:class17 { ioctl };", - "neverallowxperm on line 219 of policies/test-neverallow/policy_minus_self.conf.std (or line 219 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallowxperm test19_2_t test19_1_t:file ioctl { 0x101-0x102 };", - "neverallowxperm on line 231 of policies/test-neverallow/policy_minus_self.conf.std (or line 231 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallowxperm test20_2_t test20_1_t:file ioctl { 0x103 };", - "neverallowxperm on line 231 of policies/test-neverallow/policy_minus_self.conf.std (or line 231 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallowxperm test20_1_t test20_2_t:file ioctl { 0x102 };", - "neverallowxperm on line 261 of policies/test-neverallow/policy_minus_self.conf.std (or line 261 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallowxperm test23_1_t test23_2_t:file ioctl { 0x9511 };", - "neverallowxperm on line 272 of policies/test-neverallow/policy_minus_self.conf.std (or line 272 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallowxperm test24_1_t test24_a:file ioctl { 0x9511 };", - "neverallowxperm on line 283 of policies/test-neverallow/policy_minus_self.conf.std (or line 283 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallowxperm test25_a test25_a:file ioctl { 0x9511 };", - "neverallowxperm on line 295 of policies/test-neverallow/policy_minus_self.conf.std (or line 295 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallowxperm test26_1_a test26_2_a:file ioctl { 0x9511 };", - "neverallowxperm on line 295 of policies/test-neverallow/policy_minus_self.conf.std (or line 295 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallowxperm test26_1_a test26_2_a:file ioctl { 0x9511 };", - "neverallowxperm on line 295 of policies/test-neverallow/policy_minus_self.conf.std (or line 295 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallowxperm test26_1_a test26_2_a:file ioctl { 0x9511 };", - "neverallowxperm on line 295 of policies/test-neverallow/policy_minus_self.conf.std (or line 295 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallowxperm test26_1_a test26_2_a:file ioctl { 0x9511 };", - "neverallowxperm on line 317 of policies/test-neverallow/policy_minus_self.conf.std (or line 317 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallow test28_2_t test28_1_t:file { ioctl };", - "neverallowxperm on line 317 of policies/test-neverallow/policy_minus_self.conf.std (or line 317 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallowxperm test28_1_t test28_2_t:file ioctl { 0x9521 };", - "neverallowxperm on line 327 of policies/test-neverallow/policy_minus_self.conf.std (or line 327 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallow test29_2_t test29_1_t:file { ioctl };", - "neverallowxperm on line 327 of policies/test-neverallow/policy_minus_self.conf.std (or line 327 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallowxperm test29_1_t test29_a:file ioctl { 0x9521 };", - "neverallowxperm on line 337 of policies/test-neverallow/policy_minus_self.conf.std (or line 337 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallowxperm test30_a test30_a:file ioctl { 0x9521 };", - "neverallowxperm on line 337 of policies/test-neverallow/policy_minus_self.conf.std (or line 337 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallowxperm test30_a test30_a:file ioctl { 0x9521 };", - "neverallowxperm on line 348 of policies/test-neverallow/policy_minus_self.conf.std (or line 348 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallowxperm test31_1_a test31_2_a:file ioctl { 0x9521 };", - "neverallowxperm on line 348 of policies/test-neverallow/policy_minus_self.conf.std (or line 348 of policies/test-neverallow/policy_minus_self.conf.std) violated by\nallowxperm test31_1_a test31_2_a:file ioctl { 0x9521 };", + "neverallowxperm on line 201 of policies/test-neverallow/policy_minus_self.conf.std (or line 201 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allow test17_1_t test17_2_t:class17 { ioctl };", + "neverallowxperm on line 219 of policies/test-neverallow/policy_minus_self.conf.std (or line 219 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allowxperm test19_2_t test19_1_t:file ioctl { 0x101-0x102 };", + "neverallowxperm on line 231 of policies/test-neverallow/policy_minus_self.conf.std (or line 231 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allowxperm test20_2_t test20_1_t:file ioctl { 0x103 };", + "neverallowxperm on line 231 of policies/test-neverallow/policy_minus_self.conf.std (or line 231 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allowxperm test20_1_t test20_2_t:file ioctl { 0x102 };", + "neverallowxperm on line 261 of policies/test-neverallow/policy_minus_self.conf.std (or line 261 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allowxperm test23_1_t test23_2_t:file ioctl { 0x9511 };", + "neverallowxperm on line 272 of policies/test-neverallow/policy_minus_self.conf.std (or line 272 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allowxperm test24_1_t test24_a:file ioctl { 0x9511 };", + "neverallowxperm on line 283 of policies/test-neverallow/policy_minus_self.conf.std (or line 283 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allowxperm test25_a test25_a:file ioctl { 0x9511 };", + "neverallowxperm on line 295 of policies/test-neverallow/policy_minus_self.conf.std (or line 295 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allowxperm test26_1_a test26_2_a:file ioctl { 0x9511 };", + "neverallowxperm on line 295 of policies/test-neverallow/policy_minus_self.conf.std (or line 295 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allowxperm test26_1_a test26_2_a:file ioctl { 0x9511 };", + "neverallowxperm on line 295 of policies/test-neverallow/policy_minus_self.conf.std (or line 295 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allowxperm test26_1_a test26_2_a:file ioctl { 0x9511 };", + "neverallowxperm on line 295 of policies/test-neverallow/policy_minus_self.conf.std (or line 295 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allowxperm test26_1_a test26_2_a:file ioctl { 0x9511 };", + "neverallowxperm on line 317 of policies/test-neverallow/policy_minus_self.conf.std (or line 317 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allow test28_2_t test28_1_t:file { ioctl };", + "neverallowxperm on line 317 of policies/test-neverallow/policy_minus_self.conf.std (or line 317 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allowxperm test28_1_t test28_2_t:file ioctl { 0x9521 };", + "neverallowxperm on line 327 of policies/test-neverallow/policy_minus_self.conf.std (or line 327 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allow test29_2_t test29_1_t:file { ioctl };", + "neverallowxperm on line 327 of policies/test-neverallow/policy_minus_self.conf.std (or line 327 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allowxperm test29_1_t test29_a:file ioctl { 0x9521 };", + "neverallowxperm on line 337 of policies/test-neverallow/policy_minus_self.conf.std (or line 337 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allowxperm test30_a test30_a:file ioctl { 0x9521 };", + "neverallowxperm on line 337 of policies/test-neverallow/policy_minus_self.conf.std (or line 337 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allowxperm test30_a test30_a:file ioctl { 0x9521 };", + "neverallowxperm on line 348 of policies/test-neverallow/policy_minus_self.conf.std (or line 348 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allowxperm test31_1_a test31_2_a:file ioctl { 0x9521 };", + "neverallowxperm on line 348 of policies/test-neverallow/policy_minus_self.conf.std (or line 348 of policies/test-neverallow/policy_minus_self.conf.std) violated by\n allowxperm test31_1_a test31_2_a:file ioctl { 0x9521 };", }; if (policydb_init(&base_expanded)) @@ -244,25 +244,25 @@ static void test_neverallow_not_self(void) "neverallow on line 185 of policies/test-neverallow/policy_not_self.conf.std (or line 185 of policies/test-neverallow/policy_not_self.conf.std) violated by allow test13_1_t test13_2_t:file { read };", "neverallow on line 194 of policies/test-neverallow/policy_not_self.conf.std (or line 194 of policies/test-neverallow/policy_not_self.conf.std) violated by allow test16_2_t test16_1_t:file { read };", "neverallow on line 194 of policies/test-neverallow/policy_not_self.conf.std (or line 194 of policies/test-neverallow/policy_not_self.conf.std) violated by allow test16_1_t test16_2_t:file { read };", - "neverallowxperm on line 202 of policies/test-neverallow/policy_not_self.conf.std (or line 202 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallow test17_1_t test17_2_t:class17 { ioctl };", - "neverallowxperm on line 220 of policies/test-neverallow/policy_not_self.conf.std (or line 220 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallowxperm test19_2_t test19_1_t:file ioctl { 0x101-0x102 };", - "neverallowxperm on line 232 of policies/test-neverallow/policy_not_self.conf.std (or line 232 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallowxperm test20_2_t test20_1_t:file ioctl { 0x103 };", - "neverallowxperm on line 232 of policies/test-neverallow/policy_not_self.conf.std (or line 232 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallowxperm test20_1_t test20_2_t:file ioctl { 0x102 };", - "neverallowxperm on line 262 of policies/test-neverallow/policy_not_self.conf.std (or line 262 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallowxperm test23_1_t test23_2_t:file ioctl { 0x9511 };", - "neverallowxperm on line 273 of policies/test-neverallow/policy_not_self.conf.std (or line 273 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallowxperm test24_1_t test24_a:file ioctl { 0x9511 };", - "neverallowxperm on line 284 of policies/test-neverallow/policy_not_self.conf.std (or line 284 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallowxperm test25_a test25_a:file ioctl { 0x9511 };", - "neverallowxperm on line 296 of policies/test-neverallow/policy_not_self.conf.std (or line 296 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallowxperm test26_1_a test26_2_a:file ioctl { 0x9511 };", - "neverallowxperm on line 296 of policies/test-neverallow/policy_not_self.conf.std (or line 296 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallowxperm test26_1_a test26_2_a:file ioctl { 0x9511 };", - "neverallowxperm on line 296 of policies/test-neverallow/policy_not_self.conf.std (or line 296 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallowxperm test26_1_a test26_2_a:file ioctl { 0x9511 };", - "neverallowxperm on line 296 of policies/test-neverallow/policy_not_self.conf.std (or line 296 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallowxperm test26_1_a test26_2_a:file ioctl { 0x9511 };", - "neverallowxperm on line 318 of policies/test-neverallow/policy_not_self.conf.std (or line 318 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallow test28_2_t test28_1_t:file { ioctl };", - "neverallowxperm on line 318 of policies/test-neverallow/policy_not_self.conf.std (or line 318 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallowxperm test28_1_t test28_2_t:file ioctl { 0x9521 };", - "neverallowxperm on line 328 of policies/test-neverallow/policy_not_self.conf.std (or line 328 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallow test29_2_t test29_1_t:file { ioctl };", - "neverallowxperm on line 328 of policies/test-neverallow/policy_not_self.conf.std (or line 328 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallowxperm test29_1_t test29_a:file ioctl { 0x9521 };", - "neverallowxperm on line 338 of policies/test-neverallow/policy_not_self.conf.std (or line 338 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallowxperm test30_a test30_a:file ioctl { 0x9521 };", - "neverallowxperm on line 338 of policies/test-neverallow/policy_not_self.conf.std (or line 338 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallowxperm test30_a test30_a:file ioctl { 0x9521 };", - "neverallowxperm on line 349 of policies/test-neverallow/policy_not_self.conf.std (or line 349 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallowxperm test31_1_a test31_2_a:file ioctl { 0x9521 };", - "neverallowxperm on line 349 of policies/test-neverallow/policy_not_self.conf.std (or line 349 of policies/test-neverallow/policy_not_self.conf.std) violated by\nallowxperm test31_1_a test31_2_a:file ioctl { 0x9521 };", + "neverallowxperm on line 202 of policies/test-neverallow/policy_not_self.conf.std (or line 202 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allow test17_1_t test17_2_t:class17 { ioctl };", + "neverallowxperm on line 220 of policies/test-neverallow/policy_not_self.conf.std (or line 220 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allowxperm test19_2_t test19_1_t:file ioctl { 0x101-0x102 };", + "neverallowxperm on line 232 of policies/test-neverallow/policy_not_self.conf.std (or line 232 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allowxperm test20_2_t test20_1_t:file ioctl { 0x103 };", + "neverallowxperm on line 232 of policies/test-neverallow/policy_not_self.conf.std (or line 232 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allowxperm test20_1_t test20_2_t:file ioctl { 0x102 };", + "neverallowxperm on line 262 of policies/test-neverallow/policy_not_self.conf.std (or line 262 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allowxperm test23_1_t test23_2_t:file ioctl { 0x9511 };", + "neverallowxperm on line 273 of policies/test-neverallow/policy_not_self.conf.std (or line 273 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allowxperm test24_1_t test24_a:file ioctl { 0x9511 };", + "neverallowxperm on line 284 of policies/test-neverallow/policy_not_self.conf.std (or line 284 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allowxperm test25_a test25_a:file ioctl { 0x9511 };", + "neverallowxperm on line 296 of policies/test-neverallow/policy_not_self.conf.std (or line 296 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allowxperm test26_1_a test26_2_a:file ioctl { 0x9511 };", + "neverallowxperm on line 296 of policies/test-neverallow/policy_not_self.conf.std (or line 296 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allowxperm test26_1_a test26_2_a:file ioctl { 0x9511 };", + "neverallowxperm on line 296 of policies/test-neverallow/policy_not_self.conf.std (or line 296 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allowxperm test26_1_a test26_2_a:file ioctl { 0x9511 };", + "neverallowxperm on line 296 of policies/test-neverallow/policy_not_self.conf.std (or line 296 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allowxperm test26_1_a test26_2_a:file ioctl { 0x9511 };", + "neverallowxperm on line 318 of policies/test-neverallow/policy_not_self.conf.std (or line 318 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allow test28_2_t test28_1_t:file { ioctl };", + "neverallowxperm on line 318 of policies/test-neverallow/policy_not_self.conf.std (or line 318 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allowxperm test28_1_t test28_2_t:file ioctl { 0x9521 };", + "neverallowxperm on line 328 of policies/test-neverallow/policy_not_self.conf.std (or line 328 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allow test29_2_t test29_1_t:file { ioctl };", + "neverallowxperm on line 328 of policies/test-neverallow/policy_not_self.conf.std (or line 328 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allowxperm test29_1_t test29_a:file ioctl { 0x9521 };", + "neverallowxperm on line 338 of policies/test-neverallow/policy_not_self.conf.std (or line 338 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allowxperm test30_a test30_a:file ioctl { 0x9521 };", + "neverallowxperm on line 338 of policies/test-neverallow/policy_not_self.conf.std (or line 338 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allowxperm test30_a test30_a:file ioctl { 0x9521 };", + "neverallowxperm on line 349 of policies/test-neverallow/policy_not_self.conf.std (or line 349 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allowxperm test31_1_a test31_2_a:file ioctl { 0x9521 };", + "neverallowxperm on line 349 of policies/test-neverallow/policy_not_self.conf.std (or line 349 of policies/test-neverallow/policy_not_self.conf.std) violated by\n allowxperm test31_1_a test31_2_a:file ioctl { 0x9521 };", }; if (policydb_init(&base_expanded)) From 30ba551434fea0e2d265c758455973865068e093 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Fri, 25 Oct 2024 17:45:32 +0200 Subject: [PATCH 6/6] libsepol/tests: add cond xperm neverallow tests MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Add some tests to verify assertion checking works for extended permissions in conditional policies. Signed-off-by: Christian Göttsche --- v3: add patch --- libsepol/tests/helpers.c | 1 + .../policies/test-neverallow/policy_cond.conf | 251 ++++++++++++++++++ libsepol/tests/test-neverallow.c | 57 ++++ 3 files changed, 309 insertions(+) create mode 100644 libsepol/tests/policies/test-neverallow/policy_cond.conf diff --git a/libsepol/tests/helpers.c b/libsepol/tests/helpers.c index 1192734b9..97ddfe8e7 100644 --- a/libsepol/tests/helpers.c +++ b/libsepol/tests/helpers.c @@ -53,6 +53,7 @@ int test_load_policy(policydb_t * p, int policy_type, int mls, const char *test_ p->policy_type = policy_type; p->mls = mls; + p->policyvers = MOD_POLICYDB_VERSION_MAX; if (read_source_policy(p, filename, test_name)) { fprintf(stderr, "failed to read policy %s\n", filename); diff --git a/libsepol/tests/policies/test-neverallow/policy_cond.conf b/libsepol/tests/policies/test-neverallow/policy_cond.conf new file mode 100644 index 000000000..c81fc01d6 --- /dev/null +++ b/libsepol/tests/policies/test-neverallow/policy_cond.conf @@ -0,0 +1,251 @@ +class process +class blk_file +class chr_file +class dir +class fifo_file +class file +class lnk_file +class sock_file + +sid kernel +sid security +sid unlabeled +sid file +sid port +sid netif +sid netmsg +sid node +sid devnull + +class process { dyntransition transition } +class file { getattr ioctl open read write } + +bool boolean1 false; +bool boolean2 true; + +ifdef(`enable_mls',` +sensitivity s0; +dominance { s0 } +category c0; category c1; category c2; category c3; +category c4; category c5; category c6; category c7; +category c8; category c9; category c10; category c11; +category c12; category c13; category c14; category c15; +category c16; category c17; category c18; category c19; +category c20; category c21; category c22; category c23; + +level s0:c0.c23; + +mlsconstrain file { write } ( h1 dom h2 ); +') + + +######################################## +# +# Test start +# +######################################## + + +## Test 1 (basic - fail) + +type test1_t; +if boolean1 { + allow test1_t self : file read; +} +neverallow test1_t * : file *; + + +## Test 2 (basic - fail) + +attribute test2_a; +type test2_1_t, test2_a; +type test2_2_t; +if !boolean1 { + allow test2_1_t test2_1_t : file write; + allow test2_2_t test2_2_t : file write; +} +neverallow test2_a * : file *; + + +## Test 3 (xperm - no xperm in one branch - fail) + +type test3_t; +if boolean1 { + allow test3_t self : file ioctl; +} else { + allowxperm test3_t self : file ioctl 0x1; +} +neverallowxperm test3_t self : file ioctl 0x4; + + +## Test 4 (xperm - xperm in neither branch - fail) + +type test4_t; +allow test4_t self : file ioctl; +if boolean1 { + allow test4_t self : file read; +} else { + allow test4_t self : file write; +} +neverallowxperm test4_t self : file ioctl 0x4; + + +## Test 5 (xperm - xperm in both branches - no failure) + +type test5_t; +allow test5_t self : file ioctl; +if boolean1 { + allowxperm test5_t self : file ioctl 0x1; +} else { + allowxperm test5_t self : file ioctl 0x2; +} +neverallowxperm test5_t self : file ioctl 0x4; # nofail + + +## Test 6 (xperm - failure in one branch - fail) + +type test6_t; +if boolean1 { + allow test6_t self : file ioctl; + allowxperm test6_t self : file ioctl 0x1; +} else { + allow test6_t self : file write; +} +neverallowxperm test6_t self : file ioctl 0x1; + + +## Test 7 (xperm - failure in both branches - fail) + +type test7_t; +if boolean1 { + allow test7_t self : file ioctl; + allowxperm test7_t self : file ioctl 0x1; +} else { + allow test7_t self : file ioctl; + allowxperm test7_t self : file ioctl 0x2; +} +neverallowxperm test7_t self : file ioctl { 0x1-0x2 }; + + +## Test 8 (xperm - different xperm in both branches - no failure) + +type test8_t; +allow test8_t self : file ioctl; +if boolean1 { + allowxperm test8_t self : file ioctl 0x1; +} else { + allowxperm test8_t self : file ioctl 0x2; +} +neverallowxperm test8_t self : file ioctl 0x3; # nofail + + +## Test 9 (xperm - rules split into two booleans - no failure) + +type test9_t; +allow test9_t self : file ioctl; +if boolean1 { + allowxperm test9_t self : file ioctl 0x1; +} +if !boolean2 { + allowxperm test9_t self : file ioctl 0x1; +} +neverallowxperm test9_t self : file ioctl 0x4; + + +## Test 10 (xperm - valid usage in one branch - no failure) + +type test10_t; +if boolean1 { + allow test10_t self : file ioctl; + allowxperm test10_t self : file ioctl 0x1; +} else { + allow test10_t self : file write; +} +neverallowxperm test10_t self : file ioctl 0x2; # nofail + + +## Test 11 (xperm - valid usage in both branches - no failure) + +type test11_t; +if boolean1 { + allow test11_t self : file ioctl; + allowxperm test11_t self : file ioctl 0x1; +} else { + allow test11_t self : file ioctl; + allowxperm test11_t self : file ioctl 0x2; +} +neverallowxperm test11_t self : file ioctl 0x3; # nofail + + +## Test 12 (xperm - base allow in one branch - fail) + +type test12_t; +if boolean1 { + allow test12_t self : file ioctl; +} else { + allow test12_t self : file write; +} +neverallowxperm test12_t self : file ioctl 0x1; + + +## Test 13 (xperm - invalid second branch - fail) + +type test13_t; +allow test13_t self : file ioctl; +if boolean1 { + allow test13_t self : file ioctl; + allowxperm test13_t self : file ioctl 0x1; +} else { + allow test13_t self : file write; +} +neverallowxperm test13_t self : file ioctl 0x1; + + +## Test 14 (xperm - invalid second branch - fail) + +type test14_t; +allow test14_t self : file ioctl; +if boolean1 { + allow test14_t self : file ioctl; + allowxperm test14_t self : file ioctl 0x1; +} else { + allow test14_t self : file write; +} +neverallowxperm test14_t self : file ioctl 0x2; + + +## Test 15 (xperm - base uncond in one branch - fail) + +type test15_t; +allow test15_t self : file ioctl; +allowxperm test15_t self : file ioctl 0x1; +if boolean1 { + allow test15_t self : file ioctl; +} else { + allow test15_t self : file write; +} +neverallowxperm test15_t self : file ioctl 0x2; + + +######################################## +# +# Test End +# +######################################## + + +type sys_isid; +role sys_role; +role sys_role types sys_isid; +gen_user(sys_user,, sys_role, s0, s0 - s0:c0.c23) +sid kernel gen_context(sys_user:sys_role:sys_isid, s0) +sid security gen_context(sys_user:sys_role:sys_isid, s0) +sid unlabeled gen_context(sys_user:sys_role:sys_isid, s0) +sid file gen_context(sys_user:sys_role:sys_isid, s0) +sid port gen_context(sys_user:sys_role:sys_isid, s0) +sid netif gen_context(sys_user:sys_role:sys_isid, s0) +sid netmsg gen_context(sys_user:sys_role:sys_isid, s0) +sid node gen_context(sys_user:sys_role:sys_isid, s0) +sid devnull gen_context(sys_user:sys_role:sys_isid, s0) +fs_use_trans devpts gen_context(sys_user:sys_role:sys_isid, s0); +fs_use_trans devtmpfs gen_context(sys_user:sys_role:sys_isid, s0); diff --git a/libsepol/tests/test-neverallow.c b/libsepol/tests/test-neverallow.c index 80f91bf58..9c3001c4f 100644 --- a/libsepol/tests/test-neverallow.c +++ b/libsepol/tests/test-neverallow.c @@ -293,6 +293,58 @@ static void test_neverallow_not_self(void) policydb_destroy(&base_expanded); } +static void test_neverallow_cond(void) +{ + policydb_t basemod, base_expanded; + sepol_handle_t *handle; + static const char *const expected_messages[] = { + "16 neverallow failures occurred", + "neverallow on line 58 of policies/test-neverallow/policy_cond.conf.std (or line 58 of policies/test-neverallow/policy_cond.conf.std) violated by allow test1_t test1_t:file { read };", + "neverallow on line 70 of policies/test-neverallow/policy_cond.conf.std (or line 70 of policies/test-neverallow/policy_cond.conf.std) violated by allow test2_1_t test2_1_t:file { write };", + "neverallowxperm on line 81 of policies/test-neverallow/policy_cond.conf.std (or line 81 of policies/test-neverallow/policy_cond.conf.std) violated by\n allow test3_t test3_t:file { ioctl };", + "neverallowxperm on line 93 of policies/test-neverallow/policy_cond.conf.std (or line 93 of policies/test-neverallow/policy_cond.conf.std) violated by\n allow test4_t test4_t:file { ioctl };", + "neverallowxperm on line 117 of policies/test-neverallow/policy_cond.conf.std (or line 117 of policies/test-neverallow/policy_cond.conf.std) violated by\n allowxperm test6_t test6_t:file ioctl { 0x1 };", + "neverallowxperm on line 130 of policies/test-neverallow/policy_cond.conf.std (or line 130 of policies/test-neverallow/policy_cond.conf.std) violated by\n allowxperm test7_t test7_t:file ioctl { 0x2 };", + "neverallowxperm on line 130 of policies/test-neverallow/policy_cond.conf.std (or line 130 of policies/test-neverallow/policy_cond.conf.std) violated by\n allowxperm test7_t test7_t:file ioctl { 0x1 };", + "neverallowxperm on line 130 of policies/test-neverallow/policy_cond.conf.std (or line 130 of policies/test-neverallow/policy_cond.conf.std) violated by\n allowxperm test7_t test7_t:file ioctl { 0x2 };", + "neverallowxperm on line 130 of policies/test-neverallow/policy_cond.conf.std (or line 130 of policies/test-neverallow/policy_cond.conf.std) violated by\n allowxperm test7_t test7_t:file ioctl { 0x1 };", + "neverallowxperm on line 155 of policies/test-neverallow/policy_cond.conf.std (or line 155 of policies/test-neverallow/policy_cond.conf.std) violated by\n allow test9_t test9_t:file { ioctl };", + "neverallowxperm on line 191 of policies/test-neverallow/policy_cond.conf.std (or line 191 of policies/test-neverallow/policy_cond.conf.std) violated by\n allow test12_t test12_t:file { ioctl };", + "neverallowxperm on line 204 of policies/test-neverallow/policy_cond.conf.std (or line 204 of policies/test-neverallow/policy_cond.conf.std) violated by\n allowxperm test13_t test13_t:file ioctl { 0x1 };", + "neverallowxperm on line 204 of policies/test-neverallow/policy_cond.conf.std (or line 204 of policies/test-neverallow/policy_cond.conf.std) violated by\n allow test13_t test13_t:file { ioctl };", + "neverallowxperm on line 204 of policies/test-neverallow/policy_cond.conf.std (or line 204 of policies/test-neverallow/policy_cond.conf.std) violated by\n allowxperm test13_t test13_t:file ioctl { 0x1 };", + "neverallowxperm on line 217 of policies/test-neverallow/policy_cond.conf.std (or line 217 of policies/test-neverallow/policy_cond.conf.std) violated by\n allow test14_t test14_t:file { ioctl };", + "neverallowxperm on line 230 of policies/test-neverallow/policy_cond.conf.std (or line 230 of policies/test-neverallow/policy_cond.conf.std) violated by\n allow test15_t test15_t:file { ioctl };", + }; + + if (policydb_init(&base_expanded)) + CU_FAIL_FATAL("Failed to initialize policy"); + + if (test_load_policy(&basemod, POLICY_BASE, mls, "test-neverallow", "policy_cond.conf")) + CU_FAIL_FATAL("Failed to load policy"); + + if (link_modules(NULL, &basemod, NULL, 0, 0)) + CU_FAIL_FATAL("Failed to link base module"); + + if (expand_module(NULL, &basemod, &base_expanded, 0, 0)) + CU_FAIL_FATAL("Failed to expand policy"); + + if ((handle = sepol_handle_create()) == NULL) + CU_FAIL_FATAL("Failed to initialize handle"); + + sepol_msg_set_callback(handle, msg_handler, NULL); + + if (check_assertions(handle, &base_expanded, base_expanded.global->branch_list->avrules) != -1) + CU_FAIL("Assertions did not trigger"); + + messages_check(ARRAY_SIZE(expected_messages), expected_messages); + + sepol_handle_destroy(handle); + messages_clean(); + policydb_destroy(&basemod); + policydb_destroy(&base_expanded); +} + int neverallow_add_tests(CU_pSuite suite) { /* @@ -317,5 +369,10 @@ int neverallow_add_tests(CU_pSuite suite) return CU_get_error(); } + if (NULL == CU_add_test(suite, "neverallow_cond", test_neverallow_cond)) { + CU_cleanup_registry(); + return CU_get_error(); + } + return 0; }