Add support for not-self neverallow rules. These do not trigger on allow rules where the source type is exactly equal to the target type. Signed-off-by: Christian Göttsche <cgzones@xxxxxxxxxxxxxx> --- v2: - do not change the value of RULE_SELF --- libsepol/include/sepol/policydb/policydb.h | 3 +- libsepol/src/assertion.c | 36 ++++++++++++++++++++-- 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h index 4bf9f05d..11637fe8 100644 --- a/libsepol/include/sepol/policydb/policydb.h +++ b/libsepol/include/sepol/policydb/policydb.h @@ -285,7 +285,8 @@ typedef struct avrule { #define AVRULE_XPERMS (AVRULE_XPERMS_ALLOWED | AVRULE_XPERMS_AUDITALLOW | \ AVRULE_XPERMS_DONTAUDIT | AVRULE_XPERMS_NEVERALLOW) uint32_t specified; -#define RULE_SELF 1 +#define RULE_SELF (1U << 0) +#define RULE_NOTSELF (1U << 1) uint32_t flags; type_set_t stypes; type_set_t ttypes; diff --git a/libsepol/src/assertion.c b/libsepol/src/assertion.c index dd2749a0..efa136c8 100644 --- a/libsepol/src/assertion.c +++ b/libsepol/src/assertion.c @@ -241,7 +241,7 @@ static int report_assertion_avtab_matches(avtab_key_t *k, avtab_datum_t *d, void if (rc) goto oom; - if (avrule->flags == RULE_SELF) { + if (avrule->flags & RULE_SELF) { rc = ebitmap_and(&matches, &p->attr_type_map[k->source_type - 1], &p->attr_type_map[k->target_type - 1]); if (rc) goto oom; @@ -268,6 +268,8 @@ 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 ((avrule->flags & RULE_NOTSELF) && i == j) + continue; if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) { a->errors += report_assertion_extended_permissions(handle,p, avrule, i, j, cp, perms, k, avtab); @@ -402,7 +404,7 @@ static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab if (rc) goto oom; - if (avrule->flags == RULE_SELF) { + if (avrule->flags & RULE_SELF) { rc = ebitmap_and(&matches, &p->attr_type_map[k->source_type - 1], &p->attr_type_map[k->target_type - 1]); if (rc) @@ -418,6 +420,18 @@ static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab } } + if (avrule->flags & RULE_NOTSELF) { + rc = ebitmap_and(&matches, &p->attr_type_map[k->source_type - 1], &p->attr_type_map[k->target_type - 1]); + if (rc) + goto oom; + rc = ebitmap_and(&self_matches, &avrule->ttypes.types, &matches); + if (rc) + goto oom; + rc = ebitmap_subtract(&tgt_matches, &self_matches); + if (rc) + goto oom; + } + if (ebitmap_is_empty(&tgt_matches)) goto exit; @@ -463,7 +477,7 @@ static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *a if (rc == 0) goto exit; - if (avrule->flags == RULE_SELF) { + if (avrule->flags & RULE_SELF) { /* If the neverallow uses SELF, then it is not enough that the * neverallow's source matches the src and tgt of the rule being checked. * It must match the same thing in the src and tgt, so AND the source @@ -479,6 +493,22 @@ static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *a ebitmap_destroy(&match); } + if (avrule->flags & RULE_NOTSELF) { + ebitmap_t match; + rc = ebitmap_cpy(&match, &p->attr_type_map[k->source_type - 1]); + if (rc) { + ebitmap_destroy(&match); + goto oom; + } + rc = ebitmap_subtract(&match, &p->attr_type_map[k->target_type - 1]); + if (rc) { + ebitmap_destroy(&match); + goto oom; + } + rc2 = ebitmap_match_any(&avrule->ttypes.types, &match); + ebitmap_destroy(&match); + } + /* neverallow may have tgts even if it uses SELF */ rc = ebitmap_match_any(&avrule->ttypes.types, &p->attr_type_map[k->target_type -1]); if (rc == 0 && rc2 == 0) -- 2.34.0