All the mail mirrored from lore.kernel.org
 help / color / mirror / Atom feed
From: James Carter <jwcart2@tycho.nsa.gov>
To: selinux@tycho.nsa.gov
Subject: [PATCH 05/10 v2] libsepol/cil: Add function to search the CIL AST for an AV rule.
Date: Wed, 17 Jun 2015 15:58:49 -0400	[thread overview]
Message-ID: <1434571134-31452-6-git-send-email-jwcart2@tycho.nsa.gov> (raw)
In-Reply-To: <1434571134-31452-1-git-send-email-jwcart2@tycho.nsa.gov>

The search will be considered a success if any rule is found that
at least partially matches all parts (src type, tgt type, and class-
perms) of the target rule.

For example, for a target of (allow domain file_type (file (read write)
the rule (allow init_t init_exec_t (file (read exec)) will match.

Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
---
 libsepol/cil/src/cil_find.c | 305 ++++++++++++++++++++++++++++++++++++++++++++
 libsepol/cil/src/cil_find.h |  39 ++++++
 2 files changed, 344 insertions(+)
 create mode 100644 libsepol/cil/src/cil_find.c
 create mode 100644 libsepol/cil/src/cil_find.h

diff --git a/libsepol/cil/src/cil_find.c b/libsepol/cil/src/cil_find.c
new file mode 100644
index 0000000..a76dc37
--- /dev/null
+++ b/libsepol/cil/src/cil_find.c
@@ -0,0 +1,305 @@
+/*
+ * Copyright 2011 Tresys Technology, LLC. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright notice,
+ *       this list of conditions and the following disclaimer in the documentation
+ *       and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those
+ * of the authors and should not be interpreted as representing official policies,
+ * either expressed or implied, of Tresys Technology, LLC.
+ */
+
+#include <sepol/policydb/ebitmap.h>
+
+#include "cil_internal.h"
+#include "cil_flavor.h"
+#include "cil_list.h"
+#include "cil_log.h"
+#include "cil_symtab.h"
+
+struct cil_args_find {
+	enum cil_flavor flavor;
+	void *target;
+	struct cil_list *matching;
+	int match_self;
+};
+
+static int cil_type_match_any(struct cil_symtab_datum *d1, struct cil_symtab_datum *d2)
+{
+	enum cil_flavor f1 = ((struct cil_tree_node*)d1->nodes->head->data)->flavor;
+	enum cil_flavor f2 = ((struct cil_tree_node*)d2->nodes->head->data)->flavor;
+
+	if (f1 != CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
+		struct cil_type *t1 = (struct cil_type *)d1;
+		struct cil_type *t2 = (struct cil_type *)d2;
+		if (t1->value == t2->value) {
+			return CIL_TRUE;
+		}
+	} else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
+		struct cil_typeattribute *a = (struct cil_typeattribute *)d1;
+		struct cil_type *t = (struct cil_type *)d2;
+		if (ebitmap_get_bit(a->types, t->value)) {
+			return CIL_TRUE;
+		}
+	} else if (f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) {
+		struct cil_type *t = (struct cil_type *)d1;
+		struct cil_typeattribute *a = (struct cil_typeattribute *)d2;
+		if (ebitmap_get_bit(a->types, t->value)) {
+			return CIL_TRUE;
+		}
+	} else {
+		/* Both are attributes */
+		struct cil_typeattribute *a1 = (struct cil_typeattribute *)d1;
+		struct cil_typeattribute *a2 = (struct cil_typeattribute *)d2;
+		return ebitmap_match_any(a1->types, a2->types);
+	}
+	return CIL_FALSE;
+}
+
+static int cil_type_matches(ebitmap_t *matches, struct cil_symtab_datum *d1, struct cil_symtab_datum *d2)
+{
+	int rc = SEPOL_OK;
+	enum cil_flavor f1 = ((struct cil_tree_node*)d1->nodes->head->data)->flavor;
+	enum cil_flavor f2 = ((struct cil_tree_node*)d2->nodes->head->data)->flavor;
+
+	if (f1 != CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
+		struct cil_type *t1 = (struct cil_type *)d1;
+		struct cil_type *t2 = (struct cil_type *)d2;
+		if (t1->value == t2->value) {
+			ebitmap_set_bit(matches, t1->value, 1);
+		}
+	} else if (f1 == CIL_TYPEATTRIBUTE && f2 != CIL_TYPEATTRIBUTE) {
+		struct cil_typeattribute *a = (struct cil_typeattribute *)d1;
+		struct cil_type *t = (struct cil_type *)d2;
+		if (ebitmap_get_bit(a->types, t->value)) {
+			ebitmap_set_bit(matches, t->value, 1);
+		}
+	} else if (f1 != CIL_TYPEATTRIBUTE && f2 == CIL_TYPEATTRIBUTE) {
+		struct cil_type *t = (struct cil_type *)d1;
+		struct cil_typeattribute *a = (struct cil_typeattribute *)d2;
+		if (ebitmap_get_bit(a->types, t->value)) {
+			ebitmap_set_bit(matches, t->value, 1);
+		}
+	} else {
+		/* Both are attributes */
+		struct cil_typeattribute *a1 = (struct cil_typeattribute *)d1;
+		struct cil_typeattribute *a2 = (struct cil_typeattribute *)d2;
+		rc = ebitmap_and(matches, a1->types, a2->types);
+	}
+
+	return rc;
+}
+
+/* s1 is the src type that is matched with a self
+ * s2, and t2 are the source and type of the other rule
+ */
+static int cil_self_match_any(struct cil_symtab_datum *s1, struct cil_symtab_datum *s2, struct cil_symtab_datum *t2)
+{
+	int rc;
+	struct cil_tree_node *n1 = s1->nodes->head->data;
+	if (n1->flavor != CIL_TYPEATTRIBUTE) {
+		rc = cil_type_match_any(s1, t2);
+	} else {
+		struct cil_typeattribute *a = (struct cil_typeattribute *)s1;
+		ebitmap_t map;
+		ebitmap_init(&map);
+		rc = cil_type_matches(&map, s2, t2);
+		if (rc < 0) {
+			ebitmap_destroy(&map);
+			goto exit;
+		}
+		if (map.node == NULL) {
+			rc = CIL_FALSE;
+			goto exit;
+		}
+		rc = ebitmap_match_any(&map, a->types);
+		ebitmap_destroy(&map);
+	}
+
+exit:
+	return rc;
+}
+
+static int cil_classperms_match_any(struct cil_classperms *cp1, struct cil_classperms *cp2)
+{
+	struct cil_class *c1 = cp1->class;
+	struct cil_class *c2 = cp2->class;
+	struct cil_list_item *i1, *i2;
+
+	if (&c1->datum != &c2->datum) return CIL_FALSE;
+
+	cil_list_for_each(i1, cp1->perms) {
+		struct cil_perm *p1 = i1->data;
+		cil_list_for_each(i2, cp2->perms) {
+			struct cil_perm *p2 = i2->data;
+			if (&p1->datum == &p2->datum) return CIL_TRUE;
+		}
+	}
+	return CIL_FALSE;
+}
+
+static int __cil_classperms_list_match_any(struct cil_classperms *cp1, struct cil_list *cpl2)
+{
+	int rc;
+	struct cil_list_item *curr;
+
+	cil_list_for_each(curr, cpl2) {
+		if (curr->flavor == CIL_CLASSPERMS) {
+			struct cil_classperms *cp = curr->data;
+			if (FLAVOR(cp->class) == CIL_CLASS) {
+				rc = cil_classperms_match_any(cp1, cp);
+				if (rc == CIL_TRUE) return CIL_TRUE;
+			} else { /* MAP */
+				struct cil_list_item *i = NULL;
+				cil_list_for_each(i, cp->perms) {
+					struct cil_perm *cmp = i->data;
+					rc = __cil_classperms_list_match_any(cp1, cmp->classperms);
+					if (rc == CIL_TRUE) return CIL_TRUE;
+				}
+			}
+		} else { /* SET */
+			struct cil_classperms_set *cp_set = curr->data;
+			struct cil_classpermission *cp = cp_set->set;
+			rc = __cil_classperms_list_match_any(cp1, cp->classperms);
+			if (rc == CIL_TRUE) return CIL_TRUE;
+		}
+	}
+	return CIL_FALSE;
+}
+
+static int cil_classperms_list_match_any(struct cil_list *cpl1, struct cil_list *cpl2)
+{
+	int rc;
+	struct cil_list_item *curr;
+
+	cil_list_for_each(curr, cpl1) {
+		if (curr->flavor == CIL_CLASSPERMS) {
+			struct cil_classperms *cp = curr->data;
+			if (FLAVOR(cp->class) == CIL_CLASS) {
+				rc = __cil_classperms_list_match_any(cp, cpl2);
+				if (rc == CIL_TRUE) return CIL_TRUE;
+			} else { /* MAP */
+				struct cil_list_item *i = NULL;
+				cil_list_for_each(i, cp->perms) {
+					struct cil_perm *cmp = i->data;
+					rc = cil_classperms_list_match_any(cmp->classperms, cpl2);
+					if (rc == CIL_TRUE) return CIL_TRUE;
+				}
+			}
+		} else { /* SET */
+			struct cil_classperms_set *cp_set = curr->data;
+			struct cil_classpermission *cp = cp_set->set;
+			rc = cil_classperms_list_match_any(cp->classperms, cpl2);
+			if (rc == CIL_TRUE) return CIL_TRUE;
+		}
+	}
+	return CIL_FALSE;
+}
+
+int cil_find_matching_avrule(struct cil_tree_node *node, struct cil_avrule *avrule, struct cil_avrule *target, struct cil_list *matching, int match_self)
+{
+	int rc = SEPOL_OK;
+	struct cil_symtab_datum *s1 = avrule->src;
+	struct cil_symtab_datum *t1 = avrule->tgt;
+	struct cil_list *cp1 = avrule->classperms;
+	struct cil_symtab_datum *s2 = target->src;
+	struct cil_symtab_datum *t2 = target->tgt;
+	struct cil_list *cp2 = target->classperms;
+
+	if (match_self != CIL_TRUE && avrule == target) goto exit;
+
+	if (avrule->rule_kind != target->rule_kind) goto exit;
+
+	if (!cil_type_match_any(s1, s2)) goto exit;
+
+	if (t1->fqn != CIL_KEY_SELF && t2->fqn != CIL_KEY_SELF) {
+		if (!cil_type_match_any(t1, t2)) goto exit;
+	} else {
+		if (t1->fqn == CIL_KEY_SELF && t2->fqn == CIL_KEY_SELF) {
+			/* The earlier check whether s1 and s2 matches is all that is needed */
+		} else if (t1->fqn == CIL_KEY_SELF) {
+			rc = cil_self_match_any(s1, s2, t2);
+			if (rc < 0) {
+				goto exit;
+			} else if (rc == CIL_FALSE) {
+				rc = SEPOL_OK;
+				goto exit;
+			}
+		} else if (t2->fqn == CIL_KEY_SELF) {
+			rc = cil_self_match_any(s2, s1, t1);
+			if (rc < 0) {
+				goto exit;
+			} else if (rc == CIL_FALSE) {
+				rc = SEPOL_OK;
+				goto exit;
+			}
+		}
+	}
+
+	if (cil_classperms_list_match_any(cp1, cp2)) {
+		cil_list_append(matching, CIL_NODE, node);
+	}
+
+	rc = SEPOL_OK;
+
+exit:
+	return rc;
+}
+
+static int __cil_find_matching_avrule_in_ast(struct cil_tree_node *node,  __attribute__((unused)) uint32_t *finished, void *extra_args)
+{
+	int rc = SEPOL_OK;
+	struct cil_args_find *args = extra_args;
+
+	if (node->flavor == CIL_BLOCK) {
+		struct cil_block *blk = node->data;
+		if (blk->is_abstract == CIL_TRUE) {
+			*finished = CIL_TREE_SKIP_HEAD;
+			goto exit;
+		}
+	} else if (node->flavor == CIL_MACRO) {
+		*finished = CIL_TREE_SKIP_HEAD;
+		goto exit;
+	} else if (node->flavor == CIL_AVRULE) {
+		rc = cil_find_matching_avrule(node, node->data, args->target, args->matching, args->match_self);
+	}
+
+exit:
+	return rc;
+}
+
+int cil_find_matching_avrule_in_ast(struct cil_tree_node *current, enum cil_flavor flavor, void *target, struct cil_list *matching, int match_self)
+{
+	int rc;
+	struct cil_args_find args;
+
+	args.flavor = flavor;
+	args.target = target;
+	args.matching = matching;
+	args.match_self = match_self;
+
+	rc = cil_tree_walk(current, __cil_find_matching_avrule_in_ast, NULL, NULL, &args);
+	if (rc) {
+		cil_log(CIL_ERR, "An error occured while searching for avrule in AST\n");
+	}
+
+	return rc;
+}
diff --git a/libsepol/cil/src/cil_find.h b/libsepol/cil/src/cil_find.h
new file mode 100644
index 0000000..c8ca2d2
--- /dev/null
+++ b/libsepol/cil/src/cil_find.h
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2011 Tresys Technology, LLC. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *
+ *    1. Redistributions of source code must retain the above copyright notice,
+ *       this list of conditions and the following disclaimer.
+ *
+ *    2. Redistributions in binary form must reproduce the above copyright notice,
+ *       this list of conditions and the following disclaimer in the documentation
+ *       and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY TRESYS TECHNOLOGY, LLC ``AS IS'' AND ANY EXPRESS
+ * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
+ * EVENT SHALL TRESYS TECHNOLOGY, LLC OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
+ * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
+ * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ * The views and conclusions contained in the software and documentation are those
+ * of the authors and should not be interpreted as representing official policies,
+ * either expressed or implied, of Tresys Technology, LLC.
+ */
+
+#include "cil_flavor.h"
+#include "cil_tree.h"
+#include "cil_list.h"
+
+#ifndef CIL_FIND_H_
+#define CIL_FIND_H_
+
+int cil_find_matching_avrule_in_ast(struct cil_tree_node *current, enum cil_flavor flavor, void *target, struct cil_list *matching, int match_self);
+
+#endif
-- 
1.9.3

  parent reply	other threads:[~2015-06-17 19:58 UTC|newest]

Thread overview: 21+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2015-06-17 19:58 [PATCH 00/10 v2] Improve libsepol and CIL neverallow and bounds checking James Carter
2015-06-17 19:58 ` [PATCH 01/10 v2] libsepol: Add new ebitmap function named ebitmap_match_any() James Carter
2015-06-18 13:23   ` Stephen Smalley
2015-06-17 19:58 ` [PATCH 02/10 v2] libsepol: Treat types like an attribute in the attr_type_map James Carter
2015-06-18 13:41   ` Stephen Smalley
2015-06-18 13:52     ` Stephen Smalley
2015-06-18 20:16     ` James Carter
2015-06-18 20:21       ` Stephen Smalley
2015-06-18 20:23         ` Stephen Smalley
2015-06-17 19:58 ` [PATCH 03/10 v2] libsepol: Refactored neverallow checking James Carter
2015-06-17 19:58 ` [PATCH 04/10 v2] libsepol: Refactored bounds (hierarchy) checking code James Carter
2015-06-18 13:56   ` Stephen Smalley
2015-06-18 20:26     ` James Carter
2015-06-18 20:29       ` Stephen Smalley
2015-06-18 20:35         ` James Carter
2015-06-17 19:58 ` James Carter [this message]
2015-06-17 19:58 ` [PATCH 06/10 v2] libsepol/cil: Refactored CIL neverallow checking and reporting James Carter
2015-06-17 19:58 ` [PATCH 07/10 v2] libsepol/cil: Track number of classes and number of types and attributes James Carter
2015-06-17 19:58 ` [PATCH 08/10 v2] libsepol/cil: Add CIL bounds checking and reporting James Carter
2015-06-17 19:58 ` [PATCH 09/10 v2] secilc: Add a CIL policy file to test neverallow checking James Carter
2015-06-17 19:58 ` [PATCH 10/10 v2] secilc: Add a CIL policy file to test bounds checking James Carter

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1434571134-31452-6-git-send-email-jwcart2@tycho.nsa.gov \
    --to=jwcart2@tycho.nsa.gov \
    --cc=selinux@tycho.nsa.gov \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.