From patchwork Thu Oct 24 16:01:37 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Christian_G=C3=B6ttsche?= X-Patchwork-Id: 13849358 X-Patchwork-Delegate: plautrba@redhat.com Received: from server02.seltendoof.de (server02.seltendoof.de [168.119.48.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 0CE801EBA11 for ; Thu, 24 Oct 2024 16:01:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=168.119.48.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729785719; cv=none; b=idUtg61R5szzLZZEgfWXZnHVD3Gx9OmS0Gg3oRlwwNdKADOtPoTdwBHcXtVpDqrmvZ+bfs90EnWeSAwCGm/Ounlw/WhEnqKYy9F/H1R1JJOyNDjtyutgitAMRJjy59VNhu9qcoQuT79wXunChJT3TSoqMa/3qEZRnkPmXX+ppik= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729785719; c=relaxed/simple; bh=PqqVgtul1m4AJmGVZ8zsXyDSgFXmfI1tB+DLozJI45E=; h=From:To:Cc:Subject:Date:Message-ID:MIME-Version:Content-Type; b=lcjNdXI0Cu0RQ2FGA6ZSUkw1meHI4YyEeKrvJFwFh2zLhqPisagi78emjyidLeLPNgK8Vw9x6kY8uYMePE6WVv4yhwhgjyYUUXI6APQAy3k9bKxIbnRQdJbG4iHlNKvvi2gC9ipgHi3CoJzyiSb3wPiKa+2dUvaHuOPcJ77/Jxg= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=seltendoof.de; spf=pass smtp.mailfrom=seltendoof.de; dkim=pass (2048-bit key) header.d=seltendoof.de header.i=@seltendoof.de header.b=erD0ZYHl; arc=none smtp.client-ip=168.119.48.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=seltendoof.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=seltendoof.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=seltendoof.de header.i=@seltendoof.de header.b="erD0ZYHl" From: =?utf-8?q?Christian_G=C3=B6ttsche?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=seltendoof.de; s=2023072701; t=1729785705; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding; bh=yZeDc1JaGiTaZcUeesphhCM0rR3jHGBHnelyOXa4wiI=; b=erD0ZYHlkSOQd7MhJh7gmiYhSaGeD4D+gr8Z+i3fXpbQkIHKJkii0M4mvLvlCEJZfw1wig 0vmyQZx5QQEqx2dRg9PLYlpW9M0ILiBfPUmu7mWuIL5BXmz1HTLtbhateIbmqDDnbtbgUL BaFUY+hmzsvRM/qmxDCgOisx8EgUVEGOZTlOLjx3RY04lP9LxZ/pBWtL2wgdpoRVs3rKv9 Sz9iZ2/uknhHmxZyygN4inM71uFI0x+IVFpFa8EEtA/dj3YsPK6mA+eAfkffWE0/4kBz7s wJNYtGo9A9eZ0ZfBl+j756mwc+CL9B8DRjhb3Jgyh1Kgo13r/13oMzbl0YgdHA== To: selinux@vger.kernel.org Cc: =?utf-8?q?Christian_G=C3=B6ttsche?= Subject: [PATCH v2 1/4] libsepol: misc assertion cleanup Date: Thu, 24 Oct 2024 18:01:37 +0200 Message-ID: <20241024160140.71347-1-cgoettsche@seltendoof.de> Reply-To: cgzones@googlemail.com Precedence: bulk X-Mailing-List: selinux@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christian Göttsche 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 --- Note: this patch (and the whole patchset) is based onto the proposed patch "libsepol: Support nlmsg xperms in assertions" by Thiébaud Weksteen. v2: add patch --- libsepol/include/sepol/policydb/policydb.h | 4 +- libsepol/src/assertion.c | 155 ++++++++++----------- 2 files changed, 76 insertions(+), 83 deletions(-) diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h index f73e21fc..88fb3672 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 5e129883..71faa3b2 100644 --- a/libsepol/src/assertion.c +++ b/libsepol/src/assertion.c @@ -31,7 +31,7 @@ struct avtab_match_args { sepol_handle_t *handle; policydb_t *p; - avrule_t *avrule; + const avrule_t *narule; avtab_t *avtab; unsigned long errors; }; @@ -74,7 +74,7 @@ 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 int 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)) @@ -84,7 +84,7 @@ static int match_any_class_permissions(class_perm_node_t *cp, uint32_t class, ui return 0; } -static int extended_permissions_and(uint32_t *perms1, uint32_t *perms2) { +static int 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]) @@ -94,7 +94,7 @@ static int extended_permissions_and(uint32_t *perms1, uint32_t *perms2) { return 0; } -static int check_extended_permissions(av_extended_perms_t *neverallow, avtab_extended_perms_t *allow) +static int check_extended_permissions(const av_extended_perms_t *neverallow, const avtab_extended_perms_t *allow) { int rc = 0; if ((neverallow->specified == AVRULE_XPERMS_IOCTLFUNCTION) @@ -121,8 +121,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) @@ -160,14 +160,14 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle, policydb_t *p, const avrule_t *avrule, 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; @@ -240,26 +240,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 int is_narule_self = (narule->flags & RULE_SELF) != 0; + const int 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 +267,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 +298,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 +307,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,14 +330,14 @@ exit: 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.narule = narule; args.errors = 0; args.avtab = &p->te_avtab; @@ -360,16 +360,16 @@ oom: * 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 int 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; @@ -416,21 +416,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 int is_narule_self = (narule->flags & RULE_SELF) != 0; + const int 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 +440,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 +475,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 +496,7 @@ exit: 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 +505,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 +551,7 @@ nomatch: 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 +560,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 +582,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 +615,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,16 +631,16 @@ oom: 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; - - args.handle = NULL; - args.p = p; - args.avrule = avrule; - args.errors = 0; - args.avtab = &p->te_avtab; + struct avtab_match_args args = { + .handle = NULL, + .p = p, + .narule = narule, + .errors = 0, + .avtab = &p->te_avtab, + }; rc = avtab_map(&p->te_avtab, check_assertion_avtab_match, &args); @@ -653,20 +653,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 patchwork Thu Oct 24 16:01:38 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Christian_G=C3=B6ttsche?= X-Patchwork-Id: 13849359 X-Patchwork-Delegate: plautrba@redhat.com Received: from server02.seltendoof.de (server02.seltendoof.de [168.119.48.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6F3A21F5825 for ; Thu, 24 Oct 2024 16:01:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=168.119.48.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729785719; cv=none; b=Wmk3T6Pj2S9NzB0USMq85gDApxgEljHUvLeOiUcywH5i9J20J877nS4m5qpvFUK0Z/Tt2BVPEnY9LD9AgLTNZTQPJIQzmI+QBuyfL4qCYoja5KvhjBDPcgAdZJonwKtagFtowQpgQywscj/VoQ3nNerLgy8p41shtgveoXddItU= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729785719; c=relaxed/simple; bh=kpIQ9Gb0c7H3a5XR6JymLNYBRvtTXA30vXK29SyDxqo=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=CJXfmyDQmwa6pHZ2iODPbC541rAMU110hm1BlN1BDimV+wd8XDg4tRbk/66IDSYB1RrDGptfOXRLWAZyYgy/LSkHLzPDAwgnuJ0kml59MzCrAs2V207PgCBJng1+EIhcMzkGgYthTUd2wQZJIIbqVb4FfJd2I1nQ7r4oO96QwxY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=seltendoof.de; spf=pass smtp.mailfrom=seltendoof.de; dkim=pass (2048-bit key) header.d=seltendoof.de header.i=@seltendoof.de header.b=JvtPEMGp; arc=none smtp.client-ip=168.119.48.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=seltendoof.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=seltendoof.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=seltendoof.de header.i=@seltendoof.de header.b="JvtPEMGp" From: =?utf-8?q?Christian_G=C3=B6ttsche?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=seltendoof.de; s=2023072701; t=1729785705; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=lYG7zp9zwiTBa684nCHqahlH37KYzi3e8sRQ5vEmWaA=; b=JvtPEMGpB07Er6OUUEO7LRlM0GHg4L2FoyuuOQCD/CXcmPuFuss8CDpQe6YhxcAmbdmVCb vg7dXu4yBYCcWJqnHM213RXZPOGY8IQ/ZMQNl6e6ZilvShfZMFjizQ5QYzVDrs0HbmM4ZZ j1f2tsg1HPWdRWAuy6Xj+CUQY+ZCnoE+aNhajejls2CLPhOfyqympBzPEQu2iTc915GKnk gWQULjdaPj/cVJFBNxYNxrMa8Wvm4CtDvbuf8CrQRVD/PugD27hQa0Mz21cno0paZ5VUxm Ac3PiJ20oahG9zUlNanZaZeE4CpwK80SrPnn4oTuToL+Ur8/4959HbEVoMd4OA== To: selinux@vger.kernel.org Cc: =?utf-8?q?Christian_G=C3=B6ttsche?= Subject: [PATCH v2 2/4] libsepol: add support for xperms in conditional policies Date: Thu, 24 Oct 2024 18:01:38 +0200 Message-ID: <20241024160140.71347-2-cgoettsche@seltendoof.de> In-Reply-To: <20241024160140.71347-1-cgoettsche@seltendoof.de> References: <20241024160140.71347-1-cgoettsche@seltendoof.de> Reply-To: cgzones@googlemail.com Precedence: bulk X-Mailing-List: selinux@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christian Göttsche 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 --- 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 | 86 +++++++++++++++++----- libsepol/src/policydb.c | 21 ++++++ libsepol/src/policydb_validate.c | 4 +- libsepol/src/write.c | 46 ++++++++---- 5 files changed, 131 insertions(+), 38 deletions(-) diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h index 88fb3672..f833354b 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 71faa3b2..5765d9e5 100644 --- a/libsepol/src/assertion.c +++ b/libsepol/src/assertion.c @@ -32,7 +32,6 @@ struct avtab_match_args { sepol_handle_t *handle; policydb_t *p; const avrule_t *narule; - avtab_t *avtab; unsigned long errors; }; @@ -160,7 +159,7 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle, policydb_t *p, const avrule_t *avrule, 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) { avtab_ptr_t node; avtab_key_t tmp_key; @@ -171,7 +170,7 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle, ebitmap_node_t *snode, *tnode; unsigned int i, j; int rc; - int found_xperm = 0; + int found_xperm = 0, found_enabled_xperm = 0, found_disabled_xperm = 0; int errors = 0; memcpy(&tmp_key, k, sizeof(avtab_key_t)); @@ -181,7 +180,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; @@ -210,11 +209,45 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle, errors++; } } + + for (node = avtab_search_node(&p->te_cond_avtab, &tmp_key); + node; + node = avtab_search_node_next(node, tmp_key.specified)) { + xperms = node->datum.xperms; + if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) + && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER) + && (xperms->specified != AVTAB_XPERMS_NLMSG)) + continue; + if (node->key.specified & AVTAB_ENABLED) { + found_enabled_xperm = 1; + } else { + found_disabled_xperm = 1; + } + rc = check_extended_permissions(avrule->xperms, xperms); + /* failure on the extended permission check_extended_permissions */ + if (rc) { + char *permstring; + + extended_permissions_violated(&error, avrule->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), + 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++; + } + } } } /* failure on the regular permissions */ - if (!found_xperm) { + if (!found_xperm && (!found_enabled_xperm || !found_disabled_xperm)) { 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" @@ -239,7 +272,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; @@ -313,7 +345,7 @@ 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); } else { a->errors++; report_failure(handle, p, narule, i, j, cp, perms); @@ -340,12 +372,10 @@ static int report_assertion_failures(sepol_handle_t *handle, policydb_t *p, cons args.narule = narule; args.errors = 0; - 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; rc = avtab_map(&p->te_cond_avtab, report_assertion_avtab_matches, &args); if (rc < 0) goto oom; @@ -360,7 +390,7 @@ oom: * Look up the extended permissions in avtab and verify that neverallowed * permissions are not granted. */ -static int check_assertion_extended_permissions_avtab(const avrule_t *narule, avtab_t *avtab, +static int check_assertion_extended_permissions_avtab(const avrule_t *narule, unsigned int stype, unsigned int ttype, const avtab_key_t *k, policydb_t *p) { @@ -372,7 +402,8 @@ static int check_assertion_extended_permissions_avtab(const avrule_t *narule, av const ebitmap_t *tattr = &p->type_attr_map[ttype]; ebitmap_node_t *snode, *tnode; unsigned int i, j; - int rc = 1; + int found_xperm = 0, found_enabled_xperm = 0, found_disabled_xperm = 0; + int rc; memcpy(&tmp_key, k, sizeof(avtab_key_t)); tmp_key.specified = AVTAB_XPERMS_ALLOWED; @@ -381,7 +412,22 @@ static int check_assertion_extended_permissions_avtab(const avrule_t *narule, av 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; + + if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) + && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER) + && (xperms->specified != AVTAB_XPERMS_NLMSG)) + continue; + found_xperm = 1; + rc = check_extended_permissions(neverallow_xperms, xperms); + if (rc) + return rc; + } + + for (node = avtab_search_node(&p->te_cond_avtab, &tmp_key); node; node = avtab_search_node_next(node, tmp_key.specified)) { xperms = node->datum.xperms; @@ -390,6 +436,11 @@ static int check_assertion_extended_permissions_avtab(const avrule_t *narule, av && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER) && (xperms->specified != AVTAB_XPERMS_NLMSG)) continue; + if (node->key.specified & AVTAB_ENABLED) { + found_enabled_xperm = 1; + } else { + found_disabled_xperm = 1; + } rc = check_extended_permissions(neverallow_xperms, xperms); if (rc) return rc; @@ -397,7 +448,7 @@ static int check_assertion_extended_permissions_avtab(const avrule_t *narule, av } } - return rc; + return !found_xperm && (!found_enabled_xperm || !found_disabled_xperm); } /* @@ -416,7 +467,7 @@ static int check_assertion_extended_permissions_avtab(const avrule_t *narule, av * 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, +static int check_assertion_extended_permissions(const avrule_t *narule, const avtab_key_t *k, policydb_t *p) { ebitmap_t src_matches, tgt_matches, self_matches; @@ -479,7 +530,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)) { rc = 1; goto exit; } @@ -583,7 +634,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; @@ -616,7 +666,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); if (rc < 0) goto oom; if (rc == 0) @@ -639,13 +689,11 @@ int check_assertion(policydb_t *p, const avrule_t *narule) .p = p, .narule = narule, .errors = 0, - .avtab = &p->te_avtab, }; rc = avtab_map(&p->te_avtab, check_assertion_avtab_match, &args); if (rc == 0) { - args.avtab = &p->te_cond_avtab; 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 e90ccca1..0747e789 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 5035313b..e021e025 100644 --- a/libsepol/src/policydb_validate.c +++ b/libsepol/src/policydb_validate.c @@ -903,7 +903,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: @@ -1046,7 +1046,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: diff --git a/libsepol/src/write.c b/libsepol/src/write.c index a52e2e82..4ef98449 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 patchwork Thu Oct 24 16:01:39 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Christian_G=C3=B6ttsche?= X-Patchwork-Id: 13849357 X-Patchwork-Delegate: plautrba@redhat.com Received: from server02.seltendoof.de (server02.seltendoof.de [168.119.48.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6F34F1F4FBB for ; Thu, 24 Oct 2024 16:01:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=168.119.48.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729785718; cv=none; b=btVDn5QQcB3pX7Dh59+xisz8TVFGB9sH1RKO8LrOeIiHcYx9NulDkkS/VzZZpf1Bat2M1CUEf0/eQJDhhF8H8XziwTvwL1VYrvX0I+HKAHAoFAi6h1hekhbfgI7ZkfpG6KtXX3Qu1dLNONVawhG1egEBLyMCfBRn0C1v2nSUWas= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729785718; c=relaxed/simple; bh=2szgeLc+hQM2nnJUYtT3j1jQiSzO9R/DS7ofKgqZS+I=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=t/ACbsQWWzpz8Dp4oR7+Ac2cA9l95sk3s20oDK1BBJXNC1UUTOYsmahK+kO+41TTHpvV+JciLg1ojg6SYon8+Y2UKpZJr3LdoUiTaliqxWEeoTjJ+EgSxzBiAavty8FkuVdYUubSbrsfn1Iida88my9buAXAr0OFHj7dqdtktfQ= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=seltendoof.de; spf=pass smtp.mailfrom=seltendoof.de; dkim=pass (2048-bit key) header.d=seltendoof.de header.i=@seltendoof.de header.b=rJCSraJq; arc=none smtp.client-ip=168.119.48.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=seltendoof.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=seltendoof.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=seltendoof.de header.i=@seltendoof.de header.b="rJCSraJq" From: =?utf-8?q?Christian_G=C3=B6ttsche?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=seltendoof.de; s=2023072701; t=1729785705; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=qaeeQA7K/iuG60eRkcy8CHziIgSvIjZnAaaZJCP/ucw=; b=rJCSraJqcU8nCi5JyEse/lYdKgSYQsMDBq1zkRdKHEFObFIpUxTOGFzO1MfSFaGOxm0AyU jCqXTzYgwbdRMJ8hE9qgkku3+qPGmnQltvaMQjcNzrTA2TzxhZatXuTxTLvvRwM3AyN8zO x3vcpKJUmeMfNjvYakrUmLhU8M3LsWoOvsPJE3gvXZzR3dTMkncv+JTwgBw1LEDFdSkSyA oi0UsaMoSNSlmx61KloLyHURuZGPdBhKKYGAD/fMAI/m5WtaYbn40jGkBmxLd569kY3Jkd JGroCfhGinaPH+LzTf89Lz8rsey9SSNgPVAhg7GdrtaUZbf1M8FMhWHt7jeFXg== To: selinux@vger.kernel.org Cc: =?utf-8?q?Christian_G=C3=B6ttsche?= Subject: [PATCH v2 3/4] checkpolicy: add support for xperms in conditional policies Date: Thu, 24 Oct 2024 18:01:39 +0200 Message-ID: <20241024160140.71347-3-cgoettsche@seltendoof.de> In-Reply-To: <20241024160140.71347-1-cgoettsche@seltendoof.de> References: <20241024160140.71347-1-cgoettsche@seltendoof.de> Reply-To: cgzones@googlemail.com Precedence: bulk X-Mailing-List: selinux@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christian Göttsche 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 f8a10154..3c5def9e 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 @@ done: 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 @@ done: 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 ef74f616..216da3ad 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 ed1786d8..7e117222 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 2cfbb772..51a8c40a 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 26d56438..355d9991 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 769be2b3..74eec4ba 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 patchwork Thu Oct 24 16:01:40 2024 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Patchwork-Submitter: =?utf-8?q?Christian_G=C3=B6ttsche?= X-Patchwork-Id: 13849356 X-Patchwork-Delegate: plautrba@redhat.com Received: from server02.seltendoof.de (server02.seltendoof.de [168.119.48.163]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 6F2EF1EF0BC for ; Thu, 24 Oct 2024 16:01:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=168.119.48.163 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729785718; cv=none; b=ixmXMXWFFzSjHv65Moy8QXnAuaiC6MrJiQ2/UI1luMhsbYBy4SqnUsMYbZ3f3Wfhb/5B8sdg2rpyWlIWxQp7OXWlZtIy8vs3Uy3C21SQotM+/6CQFFhou1ddMe6nWrruNFgZoh98sxrUulA4ArDwNmQU1gWLGF7pBytTi4+FoxM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1729785718; c=relaxed/simple; bh=0JIOAjyOEQNbEhmQZOh29vwBk0n6aEVViLgvdpSHUKg=; h=From:To:Cc:Subject:Date:Message-ID:In-Reply-To:References: MIME-Version:Content-Type; b=A5Bv0LfyiUvSvHNcOklp9tAvj1aE9wlDfZ/Edqo4AT9ooMcQ+qj/0iYpEoLptRoZMRKRx+tRHTNucSIIdUmBnA6OArZIHqsNmU2R+uTjcly7ckTBVYKGwAO5q/81laCUvf0+9HGS3hTUv5hz2d1MqYNb+4Qtpdkz23Bmon4EVUE= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=seltendoof.de; spf=pass smtp.mailfrom=seltendoof.de; dkim=pass (2048-bit key) header.d=seltendoof.de header.i=@seltendoof.de header.b=HQgCWnQo; arc=none smtp.client-ip=168.119.48.163 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=seltendoof.de Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=seltendoof.de Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=seltendoof.de header.i=@seltendoof.de header.b="HQgCWnQo" From: =?utf-8?q?Christian_G=C3=B6ttsche?= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=seltendoof.de; s=2023072701; t=1729785706; h=from:from:reply-to:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=39OPNVDchujWuEL87gpmzT5zwucc2N64bDAnMQ+HMyc=; b=HQgCWnQoEh7x1+fhMzH1sJKOLiUxDWmMBSkFM5sAUg1Aw67wqdGlv5m95/rUrD2xoR15fb 3l2lJxNKelJP9dVqTzJIq+wjFpihTAWHxzOhI8Fkju4xLd5AmewOSqYOZo4DlvFsUGoQz1 Q7QzDcvBDM55pbCR5zZHG8n+VBkWwGd5Bd8RpAxICKNtxsrMjJlW/ArsTbhffYB5XEPVQ4 zDpnmPD0gcNiJJkxDgxlu3QZcY3JpPJaA8jc132FIYvSfHOnlck8dOfngC0JkLgaZRH3wU qhsKFI04Rg1MNCMGoPmsGRq6C6XTfBZ4m3Yd/S0cEIch9yvKcW03TZQyE7s0Fg== To: selinux@vger.kernel.org Cc: =?utf-8?q?Christian_G=C3=B6ttsche?= Subject: [PATCH v2 4/4] libsepol/cil: add support for xperms in conditional policies Date: Thu, 24 Oct 2024 18:01:40 +0200 Message-ID: <20241024160140.71347-4-cgoettsche@seltendoof.de> In-Reply-To: <20241024160140.71347-1-cgoettsche@seltendoof.de> References: <20241024160140.71347-1-cgoettsche@seltendoof.de> Reply-To: cgzones@googlemail.com Precedence: bulk X-Mailing-List: selinux@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 From: Christian Göttsche 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 3dec1883..086dccb0 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); @@ -1762,7 +1772,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; @@ -1772,7 +1785,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]; @@ -1793,7 +1805,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; } @@ -1876,7 +1893,7 @@ exit: 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; @@ -1899,11 +1916,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: @@ -1920,7 +1937,7 @@ exit: 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; @@ -1946,7 +1963,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; @@ -1964,7 +1981,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; @@ -1984,7 +2001,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; @@ -1998,7 +2015,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; } @@ -2019,7 +2036,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); @@ -2038,7 +2055,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; @@ -2054,7 +2071,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; @@ -2123,6 +2140,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; @@ -2429,6 +2461,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) { @@ -2497,26 +2531,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); @@ -4091,7 +4196,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; @@ -5162,6 +5267,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; @@ -5226,10 +5332,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; @@ -5248,12 +5359,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 19fbb04e..8cc3f9b2 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 da8863c4..a8fa89df 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 9621a247..550b4542 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 e6b78618..d0d52d0d 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))) ) )