diff mbox series

[RFC,v2,2/4] libsepol: add not-self neverallow support

Message ID 20211124190815.12757-2-cgzones@googlemail.com (mailing list archive)
State Superseded
Headers show
Series [RFC,v2,1/4] libsepol: introduce ebitmap_subtract() | expand

Commit Message

Christian Göttsche Nov. 24, 2021, 7:08 p.m. UTC
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@googlemail.com>
---
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(-)

Comments

James Carter Dec. 3, 2021, 10:06 p.m. UTC | #1
On Thu, Nov 25, 2021 at 3:03 PM Christian Göttsche
<cgzones@googlemail.com> wrote:
>
> 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@googlemail.com>
> ---
> 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;
>

Something is not right with how it is working with extended permissions.

I am using these types rules with the following examples.
type TYPE1;
type TYPE2;
type TYPE3;
typeattribute TYPE1 TATTR1, TATTR2;
typeattribute TYPE2 TATTR1, TATTR2;
typeattribute TYPE3 TATTR1;


For normal extended permissions.

These rules give an assertion failure as expected.
allow TATTR1 TATTR1 : CLASS4 ioctl;
neverallowxperm TYPE1 self : CLASS4 ioctl 0x9411;

These rules do not, again, as expected.
allow TATTR1 TATTR1 : CLASS4 ioctl;
allowxperm TATTR1 TATTR1 : CLASS4 ioctl 0x9401;
neverallowxperm TYPE1 self : CLASS4 ioctl 0x9411;

For the not-self extended permissions.

These rules give an assertion failure, but they shouldn't.
allow TATTR1 TATTR1 : CLASS5 ioctl;
allowxperm TATTR1 TATTR1 : CLASS5 ioctl 0x9501;
neverallowxperm TYPE1 ~self : CLASS5 ioctl 0x9511;

libsepol.report_assertion_extended_permissions: neverallowxperm on
line 153 of policy.conf (or line 153 of policy.conf) violated by
allow TYPE1 TYPE2:CLASS5 { ioctl };
libsepol.report_assertion_extended_permissions: neverallowxperm on
line 153 of policy.conf (or line 153 of policy.conf) violated by
allow TYPE1 TYPE3:CLASS5 { ioctl };


Thanks,
Jim


> @@ -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
>
diff mbox series

Patch

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)