All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH userspace 0/4] Remove redundant rules when building policydb
@ 2019-05-23 10:24 Ondrej Mosnacek
  2019-05-23 10:24 ` [PATCH userspace 1/4] libsepol: add a function to optimize kernel policy Ondrej Mosnacek
                   ` (5 more replies)
  0 siblings, 6 replies; 15+ messages in thread
From: Ondrej Mosnacek @ 2019-05-23 10:24 UTC (permalink / raw)
  To: selinux

This series implements an optional optimization step when building
a policydb via semodule or secilc, which identifies and removes rules
that are redundant -- i.e. they are already covered by a more general
rule based on attribute inheritance.

Since the performance penalty of this additional step is very small
(it adds about 1 s to the current running time of ~20-30 s [1]) and
it can have a big positive effect on the number of rules in policy
(it manages to remove ~40% AV rules from Fedora 29 policy), the
optimization is enabled by default and can be turned off using a
command-line option (--no-optimize) in secilc and semodule [2].

The optimization routine eliminates:
 * all allow/neverallow/dontaudit/auditallow rules (including xperm
   variants) that are covered by another more general rule,
 * all conditional versions of the above rules that are covered by a
   more general rule either in the unconditional table or in the same
   branch of the same conditional.

The optimization doesn't process other rules, since they currently
do not support attributes. There is some room left for more precise
optimization of conditional rules, but it would likely bring only
little additional benefit.

When the policy is mostly or fully expanded, the optimization should
be turned off. If it isn't, the policy build time will increase a lot
for no benefit. However, the complexity of optimization will be only
linear w.r.t. the number of rules and so the impact should not be
catastrophic. (When testing with secilc on a subset of Fedora policy
with -X 100000 the build time was 1.7 s with optimization vs. 1 s
without it.)

Tested live on my Fedora 29 devel machine under normal use. No unusual
AVCs were observed with optimized policy loaded.

Travis build passed: https://travis-ci.org/WOnder93/selinux/builds/536157427

NOTE: The xperm rule support wasn't tested -- I would welcome some
      peer review/testing of this part.

[1] As measured on my machine (Fedora 29 policy, x86_64).
[2] I have no problem with switching it to opt-in if that is preferred.

Ondrej Mosnacek (4):
  libsepol: add a function to optimize kernel policy
  secilc: optimize policy before writing
  libsemanage: optimize policy on rebuild
  semodule: add flag to disable policy optimization

 libsemanage/include/semanage/handle.h      |   4 +
 libsemanage/src/direct_api.c               |   7 +
 libsemanage/src/handle.c                   |  13 +
 libsemanage/src/handle.h                   |   1 +
 libsemanage/src/libsemanage.map            |   5 +
 libsepol/include/sepol/policydb.h          |   5 +
 libsepol/include/sepol/policydb/policydb.h |   2 +
 libsepol/src/libsepol.map.in               |   5 +
 libsepol/src/optimize.c                    | 370 +++++++++++++++++++++
 libsepol/src/policydb_public.c             |   5 +
 policycoreutils/semodule/semodule.c        |  12 +-
 secilc/secilc.c                            |  16 +-
 12 files changed, 442 insertions(+), 3 deletions(-)
 create mode 100644 libsepol/src/optimize.c

-- 
2.20.1


^ permalink raw reply	[flat|nested] 15+ messages in thread

* [PATCH userspace 1/4] libsepol: add a function to optimize kernel policy
  2019-05-23 10:24 [PATCH userspace 0/4] Remove redundant rules when building policydb Ondrej Mosnacek
@ 2019-05-23 10:24 ` Ondrej Mosnacek
  2019-05-23 10:24 ` [PATCH userspace 2/4] secilc: optimize policy before writing Ondrej Mosnacek
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Ondrej Mosnacek @ 2019-05-23 10:24 UTC (permalink / raw)
  To: selinux

Add sepol_policydb_optimize(), which checks a kernel policy for
redundant rules (i.e. those that are covered by an existing more general
rule) and removes them.

Results on Fedora 29 policy:

WITHOUT OPTIMIZATION:
    # time semodule -B --no-optimize
    real    0m20,190s
    user    0m18,003s
    sys     0m2,075s

    $ wc -c /sys/fs/selinux/policy
    8689631 /sys/fs/selinux/policy

    $ seinfo (edited)
      Allow:            113152
      Dontaudit:         10294
      Total:            123146

WITH OPTIMIZATION ENABLED:
    # time semodule -B
    real    0m21,406s
    user    0m19,061s
    sys     0m2,227s

    $ wc -c /sys/fs/selinux/policy
    8089575 /sys/fs/selinux/policy

    $ seinfo (edited)
      Allow:             66328
      Dontaudit:          7138
      Total:             73466

Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
---
 libsepol/include/sepol/policydb.h          |   5 +
 libsepol/include/sepol/policydb/policydb.h |   2 +
 libsepol/src/libsepol.map.in               |   5 +
 libsepol/src/optimize.c                    | 370 +++++++++++++++++++++
 libsepol/src/policydb_public.c             |   5 +
 5 files changed, 387 insertions(+)
 create mode 100644 libsepol/src/optimize.c

diff --git a/libsepol/include/sepol/policydb.h b/libsepol/include/sepol/policydb.h
index 6769b913..792913dd 100644
--- a/libsepol/include/sepol/policydb.h
+++ b/libsepol/include/sepol/policydb.h
@@ -100,6 +100,11 @@ extern int sepol_policydb_set_handle_unknown(sepol_policydb_t * p,
 extern int sepol_policydb_set_target_platform(sepol_policydb_t * p,
 					     int target_platform);
 
+/*
+ * Optimize the policy by removing redundant rules.
+ */
+extern int sepol_policydb_optimize(sepol_policydb_t * p);
+
 /* 
  * Read a policydb from a policy file.
  * This automatically sets the type and version based on the 
diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h
index 591ce6e0..a279382e 100644
--- a/libsepol/include/sepol/policydb/policydb.h
+++ b/libsepol/include/sepol/policydb/policydb.h
@@ -636,6 +636,8 @@ extern int policydb_user_cache(hashtab_key_t key,
 
 extern int policydb_reindex_users(policydb_t * p);
 
+extern int policydb_optimize(policydb_t * p);
+
 extern void policydb_destroy(policydb_t * p);
 
 extern int policydb_load_isids(policydb_t * p, sidtab_t * s);
diff --git a/libsepol/src/libsepol.map.in b/libsepol/src/libsepol.map.in
index d879016c..6358e51f 100644
--- a/libsepol/src/libsepol.map.in
+++ b/libsepol/src/libsepol.map.in
@@ -59,3 +59,8 @@ LIBSEPOL_1.1 {
 	sepol_polcap_getnum;
 	sepol_polcap_getname;
 } LIBSEPOL_1.0;
+
+LIBSEPOL_1.2 {
+  global:
+	sepol_optimize_policy;
+} LIBSEPOL_1.1;
diff --git a/libsepol/src/optimize.c b/libsepol/src/optimize.c
new file mode 100644
index 00000000..1fa1495c
--- /dev/null
+++ b/libsepol/src/optimize.c
@@ -0,0 +1,370 @@
+/*
+ * Author: Ondrej Mosnacek <omosnacek@gmail.com>
+ *
+ * Copyright (C) 2019 Red Hat Inc.
+ *
+ *  This library is free software; you can redistribute it and/or
+ *  modify it under the terms of the GNU Lesser General Public
+ *  License as published by the Free Software Foundation; either
+ *  version 2.1 of the License, or (at your option) any later version.
+ *
+ *  This library is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ *  Lesser General Public License for more details.
+ *
+ *  You should have received a copy of the GNU Lesser General Public
+ *  License along with this library; if not, write to the Free Software
+ *  Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+/*
+ * Binary policy optimization.
+ *
+ * Defines the policydb_optimize() function, which finds and removes
+ * redundant rules from the binary policy to reduce its size and potentially
+ * improve rule matching times. Only rules that are already covered by a
+ * more general rule are removed. The resulting policy is functionally
+ * equivalent to the original one.
+ */
+
+#include <sepol/policydb/policydb.h>
+#include <sepol/policydb/conditional.h>
+
+/* builds map: type/attribute -> {all attributes that are a superset of it} */
+static ebitmap_t *build_type_map(const policydb_t *p)
+{
+	unsigned int i, k;
+	ebitmap_t *map = malloc(p->p_types.nprim * sizeof(ebitmap_t));
+	if (!map)
+		return NULL;
+
+	for (i = 0; i < p->p_types.nprim; i++) {
+		if (p->type_val_to_struct[i] &&
+		    p->type_val_to_struct[i]->flavor != TYPE_ATTRIB) {
+			if (ebitmap_cpy(&map[i], &p->type_attr_map[i]))
+				goto err;
+		} else {
+			ebitmap_t *types_i = &p->attr_type_map[i];
+
+			ebitmap_init(&map[i]);
+			for (k = 0; k < p->p_types.nprim; k++) {
+				ebitmap_t *types_k = &p->attr_type_map[k];
+
+				if (ebitmap_contains(types_k, types_i)) {
+					if (ebitmap_set_bit(&map[i], k, 1))
+						goto err;
+				}
+			}
+		}
+	}
+	return map;
+err:
+	for (k = 0; k < i; k++)
+		ebitmap_destroy(&map[i]);
+	return NULL;
+}
+
+static void destroy_type_map(const policydb_t *p, ebitmap_t *type_map)
+{
+	unsigned int i;
+	for (i = 0; i < p->p_types.nprim; i++)
+		ebitmap_destroy(&type_map[i]);
+	free(type_map);
+}
+
+static int match_xperms(const uint32_t *p1, const uint32_t *p2)
+{
+	size_t i;
+
+	for (i = 0; i < EXTENDED_PERMS_LEN; i++) {
+		if ((p2[i] & p1[i]) != p1[i])
+			return 0;
+	}
+	return 1;
+}
+
+static int match_avtab_datum(uint16_t specified,
+			     const avtab_datum_t *d1, const avtab_datum_t *d2)
+{
+	if (specified & AVTAB_AV)
+		return (d2->data & d1->data) == d1->data;
+
+	if (specified & AVTAB_XPERMS) {
+		const avtab_extended_perms_t *x1 = d1->xperms;
+		const avtab_extended_perms_t *x2 = d2->xperms;
+
+		if (x1->specified == AVTAB_XPERMS_IOCTLFUNCTION) {
+			if (x2->specified == AVTAB_XPERMS_IOCTLFUNCTION) {
+				if (x1->driver != x2->driver)
+					return 0;
+				return match_xperms(x1->perms, x2->perms);
+			}
+			if (x2->specified == AVTAB_XPERMS_IOCTLDRIVER)
+				return xperm_test(x1->driver, x2->perms);
+		} else if (x1->specified == AVTAB_XPERMS_IOCTLDRIVER) {
+			if (x2->specified == AVTAB_XPERMS_IOCTLFUNCTION)
+				return 0;
+
+			if (x2->specified == AVTAB_XPERMS_IOCTLDRIVER)
+				return match_xperms(x1->perms, x2->perms);
+		}
+		return 0;
+	}
+	return 0;
+}
+
+/* checks if avtab contains a rule that covers the given rule */
+static int is_avrule_redundant(avtab_ptr_t entry, avtab_t *tab,
+			       const ebitmap_t *type_map)
+{
+	unsigned int i, k, s_idx, t_idx;
+	ebitmap_node_t *snode, *tnode;
+	avtab_datum_t *d1, *d2;
+	avtab_key_t key;
+
+	/* we only care about AV rules */
+	if (!(entry->key.specified & (AVTAB_AV|AVTAB_XPERMS)))
+		return 0;
+
+	s_idx = entry->key.source_type - 1;
+	t_idx = entry->key.target_type - 1;
+
+	key.target_class = entry->key.target_class;
+	key.specified    = entry->key.specified;
+
+	d1 = &entry->datum;
+
+	ebitmap_for_each_positive_bit(&type_map[s_idx], snode, i) {
+		key.source_type = i + 1;
+
+		ebitmap_for_each_positive_bit(&type_map[t_idx], tnode, k) {
+			if (s_idx == i && t_idx == k)
+				continue;
+
+			key.target_type = k + 1;
+
+			d2 = avtab_search(tab, &key);
+			if (!d2)
+				continue;
+
+			if (match_avtab_datum(key.specified, d1, d2))
+				return 1;
+		}
+	}
+	return 0;
+}
+
+static int is_type_attr(policydb_t *p, unsigned int id)
+{
+	return p->type_val_to_struct[id]->flavor == TYPE_ATTRIB;
+}
+
+static int is_avrule_with_attr(avtab_ptr_t entry, policydb_t *p)
+{
+	unsigned int s_idx = entry->key.source_type - 1;
+	unsigned int t_idx = entry->key.target_type - 1;
+
+	return is_type_attr(p, s_idx) || is_type_attr(p, t_idx);
+}
+
+/* checks if conditional list contains a rule that covers the given rule */
+static int is_cond_rule_redundant(avtab_ptr_t e1, cond_av_list_t *list,
+				  const ebitmap_t *type_map)
+{
+	unsigned int s1, t1, c1, k1, s2, t2, c2, k2;
+
+	/* we only care about AV rules */
+	if (!(e1->key.specified & (AVTAB_AV|AVTAB_XPERMS)))
+		return 0;
+
+	s1 = e1->key.source_type - 1;
+	t1 = e1->key.target_type - 1;
+	c1 = e1->key.target_class;
+	k1 = e1->key.specified;
+
+	for (; list; list = list->next) {
+		avtab_ptr_t e2 = list->node;
+
+		s2 = e2->key.source_type - 1;
+		t2 = e2->key.target_type - 1;
+		c2 = e2->key.target_class;
+		k2 = e2->key.specified;
+
+		if (k1 != k2 || c1 != c2)
+			continue;
+
+		if (s1 == s2 && t1 == t2)
+			continue;
+		if (!ebitmap_get_bit(&type_map[s1], s2))
+			continue;
+		if (!ebitmap_get_bit(&type_map[t1], t2))
+			continue;
+
+		if (match_avtab_datum(k1, &e1->datum, &e2->datum))
+			return 1;
+	}
+	return 0;
+}
+
+static void optimize_avtab(policydb_t *p, const ebitmap_t *type_map)
+{
+	avtab_t *tab = &p->te_avtab;
+	unsigned int i;
+	avtab_ptr_t *cur;
+
+	for (i = 0; i < tab->nslot; i++) {
+		cur = &tab->htable[i];
+		while (*cur) {
+			if (is_avrule_redundant(*cur, tab, type_map)) {
+				/* redundant rule -> remove it */
+				avtab_ptr_t tmp = *cur;
+
+				*cur = tmp->next;
+				if (tmp->key.specified & AVTAB_XPERMS)
+					free(tmp->datum.xperms);
+				free(tmp);
+
+				tab->nel--;
+			} else {
+				/* rule not redundant -> move to next rule */
+				cur = &(*cur)->next;
+			}
+		}
+	}
+}
+
+/* find redundant rules in (*cond) and put them into (*del) */
+static void optimize_cond_av_list(cond_av_list_t **cond, cond_av_list_t **del,
+				  policydb_t *p, const ebitmap_t *type_map)
+{
+	cond_av_list_t **listp = cond;
+	cond_av_list_t *pcov = NULL;
+	cond_av_list_t **pcov_cur = &pcov;
+
+	/*
+	 * Separate out all "potentially covering" rules (src or tgt is an attr)
+	 * and move them to the end of the list. This is needed to avoid
+	 * polynomial complexity when almost all rules are expanded.
+	 */
+	while (*cond) {
+		if (is_avrule_with_attr((*cond)->node, p)) {
+			cond_av_list_t *tmp = *cond;
+
+			*cond = tmp->next;
+			tmp->next = pcov;
+			pcov = tmp;
+		} else {
+			cond = &(*cond)->next;
+		}
+	}
+	/* link the "potentially covering" rules to the end of the list */
+	*cond = pcov;
+
+	/* now go through the list and find the redundant rules */
+	cond = listp;
+	pcov_cur = &pcov;
+	while (*cond) {
+		/* needed because pcov itself may get deleted */
+		if (*cond == pcov)
+			pcov_cur = cond;
+		/*
+		 * First check if covered by an unconditional rule, then also
+		 * check if covered by another rule in the same list.
+		 */
+		if (is_avrule_redundant((*cond)->node, &p->te_avtab, type_map) ||
+		    is_cond_rule_redundant((*cond)->node, *pcov_cur, type_map)) {
+			cond_av_list_t *tmp = *cond;
+
+			*cond = tmp->next;
+			tmp->next = *del;
+			*del = tmp;
+		} else {
+			cond = &(*cond)->next;
+		}
+	}
+}
+
+static void optimize_cond_avtab(policydb_t *p, const ebitmap_t *type_map)
+{
+	avtab_t *tab = &p->te_cond_avtab;
+	unsigned int i;
+	avtab_ptr_t *cur;
+	cond_node_t **cond;
+	cond_av_list_t **avcond, *del = NULL;
+
+	/* First go through all conditionals and collect redundant rules. */
+	cond = &p->cond_list;
+	while (*cond) {
+		optimize_cond_av_list(&(*cond)->true_list,  &del, p, type_map);
+		optimize_cond_av_list(&(*cond)->false_list, &del, p, type_map);
+		/* TODO: maybe also check for rules present in both lists */
+
+		/* nothing left in both lists -> remove the whole conditional */
+		if (!(*cond)->true_list && !(*cond)->false_list) {
+			cond_node_t *cond_tmp = *cond;
+
+			*cond = cond_tmp->next;
+			cond_node_destroy(cond_tmp);
+		} else {
+			cond = &(*cond)->next;
+		}
+	}
+
+	if (!del)
+		return;
+
+	/*
+	 * Now go through the whole cond_avtab and remove all rules that are
+	 * found in the 'del' list.
+	 */
+	for (i = 0; i < tab->nslot; i++) {
+		cur = &tab->htable[i];
+		while (*cur) {
+			int redundant = 0;
+			avcond = &del;
+			while (*avcond) {
+				if ((*avcond)->node == *cur) {
+					cond_av_list_t *cond_tmp = *avcond;
+
+					*avcond = cond_tmp->next;
+					free(cond_tmp);
+					redundant = 1;
+					break;
+				} else {
+					avcond = &(*avcond)->next;
+				}
+			}
+			if (redundant) {
+				avtab_ptr_t tmp = *cur;
+
+				*cur = tmp->next;
+				if (tmp->key.specified & AVTAB_XPERMS)
+					free(tmp->datum.xperms);
+				free(tmp);
+
+				tab->nel--;
+			} else {
+				cur = &(*cur)->next;
+			}
+		}
+	}
+}
+
+int policydb_optimize(policydb_t *p)
+{
+	ebitmap_t *type_map;
+
+	if (p->policy_type != POLICY_KERN)
+		return -1;
+
+	type_map = build_type_map(p);
+	if (!type_map)
+		return -1;
+
+	optimize_avtab(p, type_map);
+	optimize_cond_avtab(p, type_map);
+
+	destroy_type_map(p, type_map);
+	return 0;
+}
diff --git a/libsepol/src/policydb_public.c b/libsepol/src/policydb_public.c
index e7218423..747a43ff 100644
--- a/libsepol/src/policydb_public.c
+++ b/libsepol/src/policydb_public.c
@@ -169,6 +169,11 @@ int sepol_policydb_set_target_platform(sepol_policydb_t * sp,
 	return 0;
 }
 
+int sepol_policydb_optimize(sepol_policydb_t * p)
+{
+	return policydb_optimize(&p->p);
+}
+
 int sepol_policydb_read(sepol_policydb_t * p, sepol_policy_file_t * pf)
 {
 	return policydb_read(&p->p, &pf->pf, 0);
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH userspace 2/4] secilc: optimize policy before writing
  2019-05-23 10:24 [PATCH userspace 0/4] Remove redundant rules when building policydb Ondrej Mosnacek
  2019-05-23 10:24 ` [PATCH userspace 1/4] libsepol: add a function to optimize kernel policy Ondrej Mosnacek
@ 2019-05-23 10:24 ` Ondrej Mosnacek
  2019-05-23 10:24 ` [PATCH userspace 3/4] libsemanage: optimize policy on rebuild Ondrej Mosnacek
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Ondrej Mosnacek @ 2019-05-23 10:24 UTC (permalink / raw)
  To: selinux

Call sepol_policydb_optimize() on the final policydb before writing it
out. Also add a command-line flag to optionally skip this step.

Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
---
 secilc/secilc.c | 16 +++++++++++++++-
 1 file changed, 15 insertions(+), 1 deletion(-)

diff --git a/secilc/secilc.c b/secilc/secilc.c
index ad6862ba..26996ef9 100644
--- a/secilc/secilc.c
+++ b/secilc/secilc.c
@@ -68,6 +68,7 @@ static __attribute__((__noreturn__)) void usage(const char *prog)
 	printf("  -G, --expand-generated         Expand and remove auto-generated attributes\n");
 	printf("  -X, --expand-size <SIZE>       Expand type attributes with fewer than <SIZE>\n");
 	printf("                                 members.\n");
+	printf("  -n, --no-optimize              do not optimize final policy\n");
 	printf("  -v, --verbose                  increment verbosity level\n");
 	printf("  -h, --help                     display usage information\n");
 	exit(1);
@@ -97,6 +98,7 @@ int main(int argc, char *argv[])
 	int policyvers = POLICYDB_VERSION_MAX;
 	int attrs_expand_generated = 0;
 	int attrs_expand_size = -1;
+	int optimize_policy = 1;
 	int opt_char;
 	int opt_index = 0;
 	char *fc_buf = NULL;
@@ -117,12 +119,13 @@ int main(int argc, char *argv[])
 		{"filecontexts", required_argument, 0, 'f'},
 		{"expand-generated", no_argument, 0, 'G'},
 		{"expand-size", required_argument, 0, 'X'},
+		{"no-optimize", no_argument, 0, 'n'},
 		{0, 0, 0, 0}
 	};
 	int i;
 
 	while (1) {
-		opt_char = getopt_long(argc, argv, "o:f:U:hvt:M:PDmNc:GX:", long_opts, &opt_index);
+		opt_char = getopt_long(argc, argv, "o:f:U:hvt:M:PDmNc:GX:n", long_opts, &opt_index);
 		if (opt_char == -1) {
 			break;
 		}
@@ -211,6 +214,9 @@ int main(int argc, char *argv[])
 				}
 				break;
 			}
+			case 'n':
+				optimize_policy = 0;
+				break;
 			case 'h':
 				usage(argv[0]);
 			case '?':
@@ -294,6 +300,14 @@ int main(int argc, char *argv[])
 		goto exit;
 	}
 
+	if (optimize_policy) {
+		rc = sepol_policydb_optimize(pdb);
+		if (rc != SEPOL_OK) {
+			fprintf(stderr, "Failed to optimize policydb\n");
+			goto exit;
+		}
+	}
+
 	if (output == NULL) {
 		int size = snprintf(NULL, 0, "policy.%d", policyvers);
 		output = malloc((size + 1) * sizeof(char));
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH userspace 3/4] libsemanage: optimize policy on rebuild
  2019-05-23 10:24 [PATCH userspace 0/4] Remove redundant rules when building policydb Ondrej Mosnacek
  2019-05-23 10:24 ` [PATCH userspace 1/4] libsepol: add a function to optimize kernel policy Ondrej Mosnacek
  2019-05-23 10:24 ` [PATCH userspace 2/4] secilc: optimize policy before writing Ondrej Mosnacek
@ 2019-05-23 10:24 ` Ondrej Mosnacek
  2019-05-23 10:24 ` [PATCH userspace 4/4] semodule: add flag to disable policy optimization Ondrej Mosnacek
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 15+ messages in thread
From: Ondrej Mosnacek @ 2019-05-23 10:24 UTC (permalink / raw)
  To: selinux

When building binary policy, run it through sepol_policydb_optimize()
just before writing the final policy to disk.

Also add a semanage_set_optimize() function to allow skipping the
optimization step.

Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
---
 libsemanage/include/semanage/handle.h |  4 ++++
 libsemanage/src/direct_api.c          |  7 +++++++
 libsemanage/src/handle.c              | 13 +++++++++++++
 libsemanage/src/handle.h              |  1 +
 libsemanage/src/libsemanage.map       |  5 +++++
 5 files changed, 30 insertions(+)

diff --git a/libsemanage/include/semanage/handle.h b/libsemanage/include/semanage/handle.h
index c8165900..418c2c72 100644
--- a/libsemanage/include/semanage/handle.h
+++ b/libsemanage/include/semanage/handle.h
@@ -66,6 +66,10 @@ void semanage_set_reload(semanage_handle_t * handle, int do_reload);
  * 1 for yes, 0 for no (default) */
 void semanage_set_rebuild(semanage_handle_t * handle, int do_rebuild);
 
+/* set whether to optimize the policy (remove redundancies) when built.
+ * 1 for yes (default), 0 for no */
+void semanage_set_optimize(semanage_handle_t * handle, int do_optimize);
+
 /* Fills *compiler_path with the location of the hll compiler sh->conf->compiler_directory_path
  * corresponding to lang_ext.
  * Upon success returns 0, -1 on error. */
diff --git a/libsemanage/src/direct_api.c b/libsemanage/src/direct_api.c
index c58961be..95cbee81 100644
--- a/libsemanage/src/direct_api.c
+++ b/libsemanage/src/direct_api.c
@@ -1461,6 +1461,13 @@ rebuild:
 
 		cil_db_destroy(&cildb);
 
+		/* Remove redundancies in binary policy if requested. */
+		if (sh->do_optimize) {
+			retval = sepol_policydb_optimize(out);
+			if (retval < 0)
+				goto cleanup;
+		}
+
 		/* Write the linked policy before merging local changes. */
 		retval = semanage_write_policydb(sh, out,
 						 SEMANAGE_LINKED);
diff --git a/libsemanage/src/handle.c b/libsemanage/src/handle.c
index e5109aef..0160ba18 100644
--- a/libsemanage/src/handle.c
+++ b/libsemanage/src/handle.c
@@ -88,6 +88,10 @@ semanage_handle_t *semanage_handle_create(void)
 	 * If any changes are made, this flag is ignored */
 	sh->do_rebuild = 0;
 
+	/* Optimize policy by default. If the policy is not
+	 * being rebuilt, this flag is ignored. */
+	sh->do_optimize = 1;
+
 	sh->commit_err = 0;
 
 	/* By default always reload policy after commit if SELinux is enabled. */
@@ -125,6 +129,15 @@ void semanage_set_rebuild(semanage_handle_t * sh, int do_rebuild)
 	return;
 }
 
+void semanage_set_optimize(semanage_handle_t * sh, int do_optimize)
+{
+
+	assert(sh != NULL);
+
+	sh->do_optimize = do_optimize;
+	return;
+}
+
 void semanage_set_reload(semanage_handle_t * sh, int do_reload)
 {
 
diff --git a/libsemanage/src/handle.h b/libsemanage/src/handle.h
index a91907b0..b8fbf120 100644
--- a/libsemanage/src/handle.h
+++ b/libsemanage/src/handle.h
@@ -62,6 +62,7 @@ struct semanage_handle {
 	int is_in_transaction;
 	int do_reload;		/* whether to reload policy after commit */
 	int do_rebuild;		/* whether to rebuild policy if there were no changes */
+	int do_optimize;	/* whether to optimize the built policy */
 	int commit_err;		/* set by semanage_direct_commit() if there are
 				 * any errors when building or committing the
 				 * sandbox to kernel policy at /etc/selinux
diff --git a/libsemanage/src/libsemanage.map b/libsemanage/src/libsemanage.map
index 02036696..535bd9b5 100644
--- a/libsemanage/src/libsemanage.map
+++ b/libsemanage/src/libsemanage.map
@@ -63,3 +63,8 @@ LIBSEMANAGE_1.1 {
 	  semanage_module_remove_key;
 	  semanage_set_store_root;
 } LIBSEMANAGE_1.0;
+
+LIBSEMANAGE_1.2 {
+  global:
+	  semanage_set_optimize;
+} LIBSEMANAGE_1.1;
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* [PATCH userspace 4/4] semodule: add flag to disable policy optimization
  2019-05-23 10:24 [PATCH userspace 0/4] Remove redundant rules when building policydb Ondrej Mosnacek
                   ` (2 preceding siblings ...)
  2019-05-23 10:24 ` [PATCH userspace 3/4] libsemanage: optimize policy on rebuild Ondrej Mosnacek
@ 2019-05-23 10:24 ` Ondrej Mosnacek
  2019-05-23 13:14 ` [PATCH userspace 0/4] Remove redundant rules when building policydb Dominick Grift
  2019-05-23 20:39 ` [Non-DoD Source] " jwcart2
  5 siblings, 0 replies; 15+ messages in thread
From: Ondrej Mosnacek @ 2019-05-23 10:24 UTC (permalink / raw)
  To: selinux

Skip binary policy optimization on rebuild when the --no-optimize
command-line flag is given.

Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>
---
 policycoreutils/semodule/semodule.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/policycoreutils/semodule/semodule.c b/policycoreutils/semodule/semodule.c
index a76797f5..f490ca2e 100644
--- a/policycoreutils/semodule/semodule.c
+++ b/policycoreutils/semodule/semodule.c
@@ -46,6 +46,7 @@ static int verbose;
 static int reload;
 static int no_reload;
 static int build;
+static int no_optimize;
 static int disable_dontaudit;
 static int preserve_tunables;
 static int ignore_module_cache;
@@ -123,8 +124,9 @@ static void usage(char *progname)
 	printf("usage:  %s [option]... MODE...\n", progname);
 	printf("Manage SELinux policy modules.\n");
 	printf("MODES:\n");
-	printf("  -R, --reload		    reload policy\n");
-	printf("  -B, --build		    build and reload policy\n");
+	printf("  -R,--reload		    reload policy\n");
+	printf("  -B,--build		    build and reload policy\n");
+	printf("     --no-optimize	    do not optimize built policy\n");
 	printf("  -D,--disable_dontaudit    Remove dontaudits from policy\n");
 	printf("  -i,--install=MODULE_PKG   install a new module\n");
 	printf("  -r,--remove=MODULE_NAME   remove existing module at desired priority\n");
@@ -191,6 +193,7 @@ static void parse_command_line(int argc, char **argv)
 		{"reload", 0, NULL, 'R'},
 		{"noreload", 0, NULL, 'n'},
 		{"build", 0, NULL, 'B'},
+		{"no-optimize", 0, NULL, 'O'},
 		{"disable_dontaudit", 0, NULL, 'D'},
 		{"preserve_tunables", 0, NULL, 'P'},
 		{"ignore-module-cache", 0, NULL, 'C'},
@@ -268,6 +271,9 @@ static void parse_command_line(int argc, char **argv)
 		case 'B':
 			build = 1;
 			break;
+		case 'O':
+			no_optimize = 1;
+			break;
 		case 'D':
 			disable_dontaudit = 1;
 			break;
@@ -738,6 +744,8 @@ cleanup_disable:
 			semanage_set_reload(sh, 0);
 		if (build)
 			semanage_set_rebuild(sh, 1);
+		if (no_optimize)
+			semanage_set_optimize(sh, 0);
 		if (disable_dontaudit)
 			semanage_set_disable_dontaudit(sh, 1);
 		else if (build)
-- 
2.20.1


^ permalink raw reply related	[flat|nested] 15+ messages in thread

* Re: [PATCH userspace 0/4] Remove redundant rules when building policydb
  2019-05-23 10:24 [PATCH userspace 0/4] Remove redundant rules when building policydb Ondrej Mosnacek
                   ` (3 preceding siblings ...)
  2019-05-23 10:24 ` [PATCH userspace 4/4] semodule: add flag to disable policy optimization Ondrej Mosnacek
@ 2019-05-23 13:14 ` Dominick Grift
  2019-05-23 13:39   ` Dominick Grift
  2019-05-23 20:39 ` [Non-DoD Source] " jwcart2
  5 siblings, 1 reply; 15+ messages in thread
From: Dominick Grift @ 2019-05-23 13:14 UTC (permalink / raw)
  To: Ondrej Mosnacek; +Cc: selinux

[-- Attachment #1: Type: text/plain, Size: 4051 bytes --]

On Thu, May 23, 2019 at 12:24:45PM +0200, Ondrej Mosnacek wrote:
> This series implements an optional optimization step when building
> a policydb via semodule or secilc, which identifies and removes rules
> that are redundant -- i.e. they are already covered by a more general
> rule based on attribute inheritance.

Some stats with dssp2-standard:

[kcinimod@myguest dssp2-standard]$ time secilc -n `find . -name *.cil` -o policy.31.noopt

real    0m9.278s
user    0m7.036s
sys     0m2.017s
[kcinimod@myguest dssp2-standard]$ time secilc `find . -name *.cil` -o policy.31.opt

real    0m19.343s
user    0m16.939s
sys     0m2.027s
[kcinimod@myguest dssp2-standard]$ ls -lh policy.*
-rw-rw-r--. 1 kcinimod kcinimod 2.4M May 23 15:11 policy.31.noopt
-rw-rw-r--. 1 kcinimod kcinimod 2.3M May 23 15:12 policy.31.opt

Was unable to see the actual diff as sediff got oom-killed on me

> 
> Since the performance penalty of this additional step is very small
> (it adds about 1 s to the current running time of ~20-30 s [1]) and
> it can have a big positive effect on the number of rules in policy
> (it manages to remove ~40% AV rules from Fedora 29 policy), the
> optimization is enabled by default and can be turned off using a
> command-line option (--no-optimize) in secilc and semodule [2].
> 
> The optimization routine eliminates:
>  * all allow/neverallow/dontaudit/auditallow rules (including xperm
>    variants) that are covered by another more general rule,
>  * all conditional versions of the above rules that are covered by a
>    more general rule either in the unconditional table or in the same
>    branch of the same conditional.
> 
> The optimization doesn't process other rules, since they currently
> do not support attributes. There is some room left for more precise
> optimization of conditional rules, but it would likely bring only
> little additional benefit.
> 
> When the policy is mostly or fully expanded, the optimization should
> be turned off. If it isn't, the policy build time will increase a lot
> for no benefit. However, the complexity of optimization will be only
> linear w.r.t. the number of rules and so the impact should not be
> catastrophic. (When testing with secilc on a subset of Fedora policy
> with -X 100000 the build time was 1.7 s with optimization vs. 1 s
> without it.)
> 
> Tested live on my Fedora 29 devel machine under normal use. No unusual
> AVCs were observed with optimized policy loaded.
> 
> Travis build passed: https://travis-ci.org/WOnder93/selinux/builds/536157427
> 
> NOTE: The xperm rule support wasn't tested -- I would welcome some
>       peer review/testing of this part.
> 
> [1] As measured on my machine (Fedora 29 policy, x86_64).
> [2] I have no problem with switching it to opt-in if that is preferred.
> 
> Ondrej Mosnacek (4):
>   libsepol: add a function to optimize kernel policy
>   secilc: optimize policy before writing
>   libsemanage: optimize policy on rebuild
>   semodule: add flag to disable policy optimization
> 
>  libsemanage/include/semanage/handle.h      |   4 +
>  libsemanage/src/direct_api.c               |   7 +
>  libsemanage/src/handle.c                   |  13 +
>  libsemanage/src/handle.h                   |   1 +
>  libsemanage/src/libsemanage.map            |   5 +
>  libsepol/include/sepol/policydb.h          |   5 +
>  libsepol/include/sepol/policydb/policydb.h |   2 +
>  libsepol/src/libsepol.map.in               |   5 +
>  libsepol/src/optimize.c                    | 370 +++++++++++++++++++++
>  libsepol/src/policydb_public.c             |   5 +
>  policycoreutils/semodule/semodule.c        |  12 +-
>  secilc/secilc.c                            |  16 +-
>  12 files changed, 442 insertions(+), 3 deletions(-)
>  create mode 100644 libsepol/src/optimize.c
> 
> -- 
> 2.20.1
> 

-- 
Key fingerprint = 5F4D 3CDB D3F8 3652 FBD8 02D5 3B6C 5F1D 2C7B 6B02
https://sks-keyservers.net/pks/lookup?op=get&search=0x3B6C5F1D2C7B6B02
Dominick Grift

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH userspace 0/4] Remove redundant rules when building policydb
  2019-05-23 13:14 ` [PATCH userspace 0/4] Remove redundant rules when building policydb Dominick Grift
@ 2019-05-23 13:39   ` Dominick Grift
  2019-05-23 14:08     ` Ondrej Mosnacek
  0 siblings, 1 reply; 15+ messages in thread
From: Dominick Grift @ 2019-05-23 13:39 UTC (permalink / raw)
  To: Ondrej Mosnacek, selinux

[-- Attachment #1: Type: text/plain, Size: 4643 bytes --]

On Thu, May 23, 2019 at 03:14:55PM +0200, Dominick Grift wrote:
> On Thu, May 23, 2019 at 12:24:45PM +0200, Ondrej Mosnacek wrote:
> > This series implements an optional optimization step when building
> > a policydb via semodule or secilc, which identifies and removes rules
> > that are redundant -- i.e. they are already covered by a more general
> > rule based on attribute inheritance.
> 
> Some stats with dssp2-standard:
> 
> [kcinimod@myguest dssp2-standard]$ time secilc -n `find . -name *.cil` -o policy.31.noopt
> 
> real    0m9.278s
> user    0m7.036s
> sys     0m2.017s
> [kcinimod@myguest dssp2-standard]$ time secilc `find . -name *.cil` -o policy.31.opt
> 
> real    0m19.343s
> user    0m16.939s
> sys     0m2.027s
> [kcinimod@myguest dssp2-standard]$ ls -lh policy.*
> -rw-rw-r--. 1 kcinimod kcinimod 2.4M May 23 15:11 policy.31.noopt
> -rw-rw-r--. 1 kcinimod kcinimod 2.3M May 23 15:12 policy.31.opt
> 
> Was unable to see the actual diff as sediff got oom-killed on me

According to percentage calculator thats roughly a 4 percent gain size-wise at a 47 percent performance penalty.
Looks like dssp2-standard is pretty efficient as it is.

> 
> > 
> > Since the performance penalty of this additional step is very small
> > (it adds about 1 s to the current running time of ~20-30 s [1]) and
> > it can have a big positive effect on the number of rules in policy
> > (it manages to remove ~40% AV rules from Fedora 29 policy), the
> > optimization is enabled by default and can be turned off using a
> > command-line option (--no-optimize) in secilc and semodule [2].
> > 
> > The optimization routine eliminates:
> >  * all allow/neverallow/dontaudit/auditallow rules (including xperm
> >    variants) that are covered by another more general rule,
> >  * all conditional versions of the above rules that are covered by a
> >    more general rule either in the unconditional table or in the same
> >    branch of the same conditional.
> > 
> > The optimization doesn't process other rules, since they currently
> > do not support attributes. There is some room left for more precise
> > optimization of conditional rules, but it would likely bring only
> > little additional benefit.
> > 
> > When the policy is mostly or fully expanded, the optimization should
> > be turned off. If it isn't, the policy build time will increase a lot
> > for no benefit. However, the complexity of optimization will be only
> > linear w.r.t. the number of rules and so the impact should not be
> > catastrophic. (When testing with secilc on a subset of Fedora policy
> > with -X 100000 the build time was 1.7 s with optimization vs. 1 s
> > without it.)
> > 
> > Tested live on my Fedora 29 devel machine under normal use. No unusual
> > AVCs were observed with optimized policy loaded.
> > 
> > Travis build passed: https://travis-ci.org/WOnder93/selinux/builds/536157427
> > 
> > NOTE: The xperm rule support wasn't tested -- I would welcome some
> >       peer review/testing of this part.
> > 
> > [1] As measured on my machine (Fedora 29 policy, x86_64).
> > [2] I have no problem with switching it to opt-in if that is preferred.
> > 
> > Ondrej Mosnacek (4):
> >   libsepol: add a function to optimize kernel policy
> >   secilc: optimize policy before writing
> >   libsemanage: optimize policy on rebuild
> >   semodule: add flag to disable policy optimization
> > 
> >  libsemanage/include/semanage/handle.h      |   4 +
> >  libsemanage/src/direct_api.c               |   7 +
> >  libsemanage/src/handle.c                   |  13 +
> >  libsemanage/src/handle.h                   |   1 +
> >  libsemanage/src/libsemanage.map            |   5 +
> >  libsepol/include/sepol/policydb.h          |   5 +
> >  libsepol/include/sepol/policydb/policydb.h |   2 +
> >  libsepol/src/libsepol.map.in               |   5 +
> >  libsepol/src/optimize.c                    | 370 +++++++++++++++++++++
> >  libsepol/src/policydb_public.c             |   5 +
> >  policycoreutils/semodule/semodule.c        |  12 +-
> >  secilc/secilc.c                            |  16 +-
> >  12 files changed, 442 insertions(+), 3 deletions(-)
> >  create mode 100644 libsepol/src/optimize.c
> > 
> > -- 
> > 2.20.1
> > 
> 
> -- 
> Key fingerprint = 5F4D 3CDB D3F8 3652 FBD8 02D5 3B6C 5F1D 2C7B 6B02
> https://sks-keyservers.net/pks/lookup?op=get&search=0x3B6C5F1D2C7B6B02
> Dominick Grift



-- 
Key fingerprint = 5F4D 3CDB D3F8 3652 FBD8 02D5 3B6C 5F1D 2C7B 6B02
https://sks-keyservers.net/pks/lookup?op=get&search=0x3B6C5F1D2C7B6B02
Dominick Grift

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 659 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [PATCH userspace 0/4] Remove redundant rules when building policydb
  2019-05-23 13:39   ` Dominick Grift
@ 2019-05-23 14:08     ` Ondrej Mosnacek
  2019-05-24 16:02       ` [Non-DoD Source] " jwcart2
  0 siblings, 1 reply; 15+ messages in thread
From: Ondrej Mosnacek @ 2019-05-23 14:08 UTC (permalink / raw)
  To: Dominick Grift; +Cc: selinux

On Thu, May 23, 2019 at 3:40 PM Dominick Grift <dac.override@gmail.com> wrote:
> On Thu, May 23, 2019 at 03:14:55PM +0200, Dominick Grift wrote:
> > On Thu, May 23, 2019 at 12:24:45PM +0200, Ondrej Mosnacek wrote:
> > > This series implements an optional optimization step when building
> > > a policydb via semodule or secilc, which identifies and removes rules
> > > that are redundant -- i.e. they are already covered by a more general
> > > rule based on attribute inheritance.
> >
> > Some stats with dssp2-standard:
> >
> > [kcinimod@myguest dssp2-standard]$ time secilc -n `find . -name *.cil` -o policy.31.noopt
> >
> > real    0m9.278s
> > user    0m7.036s
> > sys     0m2.017s
> > [kcinimod@myguest dssp2-standard]$ time secilc `find . -name *.cil` -o policy.31.opt
> >
> > real    0m19.343s
> > user    0m16.939s
> > sys     0m2.027s
> > [kcinimod@myguest dssp2-standard]$ ls -lh policy.*
> > -rw-rw-r--. 1 kcinimod kcinimod 2.4M May 23 15:11 policy.31.noopt
> > -rw-rw-r--. 1 kcinimod kcinimod 2.3M May 23 15:12 policy.31.opt
> >
> > Was unable to see the actual diff as sediff got oom-killed on me
>
> According to percentage calculator thats roughly a 4 percent gain size-wise at a 47 percent performance penalty.
> Looks like dssp2-standard is pretty efficient as it is.

Hmm, yeah, looks like I'll have to make it opt-in after all... or add
some heuristic to decide if running the optimization is really worth
it.

>
> >
> > >
> > > Since the performance penalty of this additional step is very small
> > > (it adds about 1 s to the current running time of ~20-30 s [1]) and
> > > it can have a big positive effect on the number of rules in policy
> > > (it manages to remove ~40% AV rules from Fedora 29 policy), the
> > > optimization is enabled by default and can be turned off using a
> > > command-line option (--no-optimize) in secilc and semodule [2].
> > >
> > > The optimization routine eliminates:
> > >  * all allow/neverallow/dontaudit/auditallow rules (including xperm
> > >    variants) that are covered by another more general rule,
> > >  * all conditional versions of the above rules that are covered by a
> > >    more general rule either in the unconditional table or in the same
> > >    branch of the same conditional.
> > >
> > > The optimization doesn't process other rules, since they currently
> > > do not support attributes. There is some room left for more precise
> > > optimization of conditional rules, but it would likely bring only
> > > little additional benefit.
> > >
> > > When the policy is mostly or fully expanded, the optimization should
> > > be turned off. If it isn't, the policy build time will increase a lot
> > > for no benefit. However, the complexity of optimization will be only
> > > linear w.r.t. the number of rules and so the impact should not be
> > > catastrophic. (When testing with secilc on a subset of Fedora policy
> > > with -X 100000 the build time was 1.7 s with optimization vs. 1 s
> > > without it.)
> > >
> > > Tested live on my Fedora 29 devel machine under normal use. No unusual
> > > AVCs were observed with optimized policy loaded.
> > >
> > > Travis build passed: https://travis-ci.org/WOnder93/selinux/builds/536157427
> > >
> > > NOTE: The xperm rule support wasn't tested -- I would welcome some
> > >       peer review/testing of this part.
> > >
> > > [1] As measured on my machine (Fedora 29 policy, x86_64).
> > > [2] I have no problem with switching it to opt-in if that is preferred.
> > >
> > > Ondrej Mosnacek (4):
> > >   libsepol: add a function to optimize kernel policy
> > >   secilc: optimize policy before writing
> > >   libsemanage: optimize policy on rebuild
> > >   semodule: add flag to disable policy optimization
> > >
> > >  libsemanage/include/semanage/handle.h      |   4 +
> > >  libsemanage/src/direct_api.c               |   7 +
> > >  libsemanage/src/handle.c                   |  13 +
> > >  libsemanage/src/handle.h                   |   1 +
> > >  libsemanage/src/libsemanage.map            |   5 +
> > >  libsepol/include/sepol/policydb.h          |   5 +
> > >  libsepol/include/sepol/policydb/policydb.h |   2 +
> > >  libsepol/src/libsepol.map.in               |   5 +
> > >  libsepol/src/optimize.c                    | 370 +++++++++++++++++++++
> > >  libsepol/src/policydb_public.c             |   5 +
> > >  policycoreutils/semodule/semodule.c        |  12 +-
> > >  secilc/secilc.c                            |  16 +-
> > >  12 files changed, 442 insertions(+), 3 deletions(-)
> > >  create mode 100644 libsepol/src/optimize.c
> > >
> > > --
> > > 2.20.1
> > >
> >
> > --
> > Key fingerprint = 5F4D 3CDB D3F8 3652 FBD8 02D5 3B6C 5F1D 2C7B 6B02
> > https://sks-keyservers.net/pks/lookup?op=get&search=0x3B6C5F1D2C7B6B02
> > Dominick Grift
>
>
>
> --
> Key fingerprint = 5F4D 3CDB D3F8 3652 FBD8 02D5 3B6C 5F1D 2C7B 6B02
> https://sks-keyservers.net/pks/lookup?op=get&search=0x3B6C5F1D2C7B6B02
> Dominick Grift



-- 
Ondrej Mosnacek <omosnace at redhat dot com>
Software Engineer, Security Technologies
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Non-DoD Source] [PATCH userspace 0/4] Remove redundant rules when building policydb
  2019-05-23 10:24 [PATCH userspace 0/4] Remove redundant rules when building policydb Ondrej Mosnacek
                   ` (4 preceding siblings ...)
  2019-05-23 13:14 ` [PATCH userspace 0/4] Remove redundant rules when building policydb Dominick Grift
@ 2019-05-23 20:39 ` jwcart2
  2019-05-24  8:54   ` Ondrej Mosnacek
  2019-05-27 17:11   ` Chris PeBenito
  5 siblings, 2 replies; 15+ messages in thread
From: jwcart2 @ 2019-05-23 20:39 UTC (permalink / raw)
  To: Ondrej Mosnacek, selinux

On 5/23/19 6:24 AM, Ondrej Mosnacek wrote:
> This series implements an optional optimization step when building
> a policydb via semodule or secilc, which identifies and removes rules
> that are redundant -- i.e. they are already covered by a more general
> rule based on attribute inheritance.
> 
> Since the performance penalty of this additional step is very small
> (it adds about 1 s to the current running time of ~20-30 s [1]) and
> it can have a big positive effect on the number of rules in policy
> (it manages to remove ~40% AV rules from Fedora 29 policy), the
> optimization is enabled by default and can be turned off using a
> command-line option (--no-optimize) in secilc and semodule [2].
> 
> The optimization routine eliminates:
>   * all allow/neverallow/dontaudit/auditallow rules (including xperm
>     variants) that are covered by another more general rule,
>   * all conditional versions of the above rules that are covered by a
>     more general rule either in the unconditional table or in the same
>     branch of the same conditional.
> 
> The optimization doesn't process other rules, since they currently
> do not support attributes. There is some room left for more precise
> optimization of conditional rules, but it would likely bring only
> little additional benefit.
> 
> When the policy is mostly or fully expanded, the optimization should
> be turned off. If it isn't, the policy build time will increase a lot
> for no benefit. However, the complexity of optimization will be only
> linear w.r.t. the number of rules and so the impact should not be
> catastrophic. (When testing with secilc on a subset of Fedora policy
> with -X 100000 the build time was 1.7 s with optimization vs. 1 s
> without it.)
> 
> Tested live on my Fedora 29 devel machine under normal use. No unusual
> AVCs were observed with optimized policy loaded.
> 
> Travis build passed: https://travis-ci.org/WOnder93/selinux/builds/536157427
> 
> NOTE: The xperm rule support wasn't tested -- I would welcome some
>        peer review/testing of this part.
> 
> [1] As measured on my machine (Fedora 29 policy, x86_64).
> [2] I have no problem with switching it to opt-in if that is preferred.
> 
> Ondrej Mosnacek (4):
>    libsepol: add a function to optimize kernel policy
>    secilc: optimize policy before writing
>    libsemanage: optimize policy on rebuild
>    semodule: add flag to disable policy optimization
> 
>   libsemanage/include/semanage/handle.h      |   4 +
>   libsemanage/src/direct_api.c               |   7 +
>   libsemanage/src/handle.c                   |  13 +
>   libsemanage/src/handle.h                   |   1 +
>   libsemanage/src/libsemanage.map            |   5 +
>   libsepol/include/sepol/policydb.h          |   5 +
>   libsepol/include/sepol/policydb/policydb.h |   2 +
>   libsepol/src/libsepol.map.in               |   5 +
>   libsepol/src/optimize.c                    | 370 +++++++++++++++++++++
>   libsepol/src/policydb_public.c             |   5 +
>   policycoreutils/semodule/semodule.c        |  12 +-
>   secilc/secilc.c                            |  16 +-
>   12 files changed, 442 insertions(+), 3 deletions(-)
>   create mode 100644 libsepol/src/optimize.c
> 

It would be nice to have checkpolicy support this as well. It shouldn't be too 
hard to do that.

I need to do some more testing, but I think something is not working correctly.

I am starting from conf files here because I have both Fedora and Android ones 
that I have used for testing and it is easier to run them through checkpolicy to 
convert to CIL.

With these rules:

# Redundant 1
allow tp01 tpr1:cl01 { p01a p11a p01b p11b };
allow tp02 tpr1:cl01 { p01a p11a };
allow at02 tpr1:cl01 { p01a p11a p01b };

# Redundant 2
dontaudit tp01 tpr2:cl01 { p01a p11a p01b p11b };
dontaudit tp02 tpr2:cl01 { p01a p11a };
dontaudit at02 tpr2:cl01 { p01a p11a p01b };

# Redundant 3
allow at02 tpr3:cl01 { p01a p11a p01b };
if (b01) {
   allow tp01 tpr3:cl01 { p01a p11a p01b p11b };
   allow tp02 tpr3:cl01 { p01a p11a };
}

# Redundant 4
dontaudit at02 tpr4:cl01 { p01a p11a p01b };
if (b01) {
   dontaudit tp01 tpr4:cl01 { p01a p11a p01b p11b };
   dontaudit tp02 tpr4:cl01 { p01a p11a };
}


I see the following from sediff:

Allow Rules (0 Added, 1 Removed, 0 Modified)
    Removed Allow Rules: 1
       - allow tp02 tpr3:cl01 { p01a p11a }; [ b01 ]:True

Dontaudit Rules (0 Added, 1 Removed, 1 Modified)
    Removed Dontaudit Rules: 1
       - dontaudit tp01 tpr4:cl01 { p01a p01b p11a p11b }; [ b01 ]:True
    Modified Dontaudit Rules: 1
       * dontaudit tp01 tpr2:cl01 { p01b p11a p01a -p11b };

So it handles Redundant 1 just fine, but has problems with Redundant 2 which 
should be the same.

I don't remember what to expect from sediff for boolean rules. I had played 
around with removing rules with some of my earlier lua tools and I thought that 
sediff handled removing redundant rules from booleans, but I could be wrong.

I will look at this more maybe tomorrow, but most likely after the Memorial day 
weekend.

Jim

-- 
James Carter <jwcart2@tycho.nsa.gov>
National Security Agency

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Non-DoD Source] [PATCH userspace 0/4] Remove redundant rules when building policydb
  2019-05-23 20:39 ` [Non-DoD Source] " jwcart2
@ 2019-05-24  8:54   ` Ondrej Mosnacek
  2019-05-24 16:01     ` jwcart2
  2019-05-27 17:11   ` Chris PeBenito
  1 sibling, 1 reply; 15+ messages in thread
From: Ondrej Mosnacek @ 2019-05-24  8:54 UTC (permalink / raw)
  To: jwcart2; +Cc: selinux

On Thu, May 23, 2019 at 10:39 PM jwcart2 <jwcart2@tycho.nsa.gov> wrote:
> On 5/23/19 6:24 AM, Ondrej Mosnacek wrote:
> > This series implements an optional optimization step when building
> > a policydb via semodule or secilc, which identifies and removes rules
> > that are redundant -- i.e. they are already covered by a more general
> > rule based on attribute inheritance.
> >
> > Since the performance penalty of this additional step is very small
> > (it adds about 1 s to the current running time of ~20-30 s [1]) and
> > it can have a big positive effect on the number of rules in policy
> > (it manages to remove ~40% AV rules from Fedora 29 policy), the
> > optimization is enabled by default and can be turned off using a
> > command-line option (--no-optimize) in secilc and semodule [2].
> >
> > The optimization routine eliminates:
> >   * all allow/neverallow/dontaudit/auditallow rules (including xperm
> >     variants) that are covered by another more general rule,
> >   * all conditional versions of the above rules that are covered by a
> >     more general rule either in the unconditional table or in the same
> >     branch of the same conditional.
> >
> > The optimization doesn't process other rules, since they currently
> > do not support attributes. There is some room left for more precise
> > optimization of conditional rules, but it would likely bring only
> > little additional benefit.
> >
> > When the policy is mostly or fully expanded, the optimization should
> > be turned off. If it isn't, the policy build time will increase a lot
> > for no benefit. However, the complexity of optimization will be only
> > linear w.r.t. the number of rules and so the impact should not be
> > catastrophic. (When testing with secilc on a subset of Fedora policy
> > with -X 100000 the build time was 1.7 s with optimization vs. 1 s
> > without it.)
> >
> > Tested live on my Fedora 29 devel machine under normal use. No unusual
> > AVCs were observed with optimized policy loaded.
> >
> > Travis build passed: https://travis-ci.org/WOnder93/selinux/builds/536157427
> >
> > NOTE: The xperm rule support wasn't tested -- I would welcome some
> >        peer review/testing of this part.
> >
> > [1] As measured on my machine (Fedora 29 policy, x86_64).
> > [2] I have no problem with switching it to opt-in if that is preferred.
> >
> > Ondrej Mosnacek (4):
> >    libsepol: add a function to optimize kernel policy
> >    secilc: optimize policy before writing
> >    libsemanage: optimize policy on rebuild
> >    semodule: add flag to disable policy optimization
> >
> >   libsemanage/include/semanage/handle.h      |   4 +
> >   libsemanage/src/direct_api.c               |   7 +
> >   libsemanage/src/handle.c                   |  13 +
> >   libsemanage/src/handle.h                   |   1 +
> >   libsemanage/src/libsemanage.map            |   5 +
> >   libsepol/include/sepol/policydb.h          |   5 +
> >   libsepol/include/sepol/policydb/policydb.h |   2 +
> >   libsepol/src/libsepol.map.in               |   5 +
> >   libsepol/src/optimize.c                    | 370 +++++++++++++++++++++
> >   libsepol/src/policydb_public.c             |   5 +
> >   policycoreutils/semodule/semodule.c        |  12 +-
> >   secilc/secilc.c                            |  16 +-
> >   12 files changed, 442 insertions(+), 3 deletions(-)
> >   create mode 100644 libsepol/src/optimize.c
> >
>
> It would be nice to have checkpolicy support this as well. It shouldn't be too
> hard to do that.

Looking at checkpolicy.c, it looks like it only generates POLICY_BASE
or POLICY_MODULE policy types. I currently limit the optimization only
to POLICY_KERN type, because from comments in policydb.h I got the
impression that other policy types have different structure and I'm
not sure if they need some special handling. I don't have that much
knowledge about SELinux userspace code yet... if you can give me some
hints about the difference between the various POLICY_* types, then I
will be happy to make some adjustments if they make sense.

>
> I need to do some more testing, but I think something is not working correctly.
>
> I am starting from conf files here because I have both Fedora and Android ones
> that I have used for testing and it is easier to run them through checkpolicy to
> convert to CIL.
>
> With these rules:
>
> # Redundant 1
> allow tp01 tpr1:cl01 { p01a p11a p01b p11b };
> allow tp02 tpr1:cl01 { p01a p11a };
> allow at02 tpr1:cl01 { p01a p11a p01b };
>
> # Redundant 2
> dontaudit tp01 tpr2:cl01 { p01a p11a p01b p11b };
> dontaudit tp02 tpr2:cl01 { p01a p11a };
> dontaudit at02 tpr2:cl01 { p01a p11a p01b };
>
> # Redundant 3
> allow at02 tpr3:cl01 { p01a p11a p01b };
> if (b01) {
>    allow tp01 tpr3:cl01 { p01a p11a p01b p11b };
>    allow tp02 tpr3:cl01 { p01a p11a };
> }
>
> # Redundant 4
> dontaudit at02 tpr4:cl01 { p01a p11a p01b };
> if (b01) {
>    dontaudit tp01 tpr4:cl01 { p01a p11a p01b p11b };
>    dontaudit tp02 tpr4:cl01 { p01a p11a };
> }
>
>
> I see the following from sediff:
>
> Allow Rules (0 Added, 1 Removed, 0 Modified)
>     Removed Allow Rules: 1
>        - allow tp02 tpr3:cl01 { p01a p11a }; [ b01 ]:True
>
> Dontaudit Rules (0 Added, 1 Removed, 1 Modified)
>     Removed Dontaudit Rules: 1
>        - dontaudit tp01 tpr4:cl01 { p01a p01b p11a p11b }; [ b01 ]:True
>     Modified Dontaudit Rules: 1
>        * dontaudit tp01 tpr2:cl01 { p01b p11a p01a -p11b };
>
> So it handles Redundant 1 just fine, but has problems with Redundant 2 which
> should be the same.

Yes, I think I'm handling the dontaudit rules incorrectly... For some
(historical?) reason they actually specify the permissions that *are*
audited, although the semantic of combining multiple rules is still
that a permission is dontaudited if there is at least one dontaudit
rule for it, so the logic of handling the raw perms data has to be
inverted for AVTAB_AUDITDENY entries. I had noticed earlier that
AVTAB_AUDITDENY rules are handled differently but somehow I concluded
that the perms values should still bitwise-or together...

Can you please try it with adding:

if (specified & AVTAB_AUDITDENY)
    return (d1->data & d2->data) == d2->data;

to the beginning of match_avtab_datum() in optimize.c? (patch form
here: https://github.com/WOnder93/selinux/commit/17c77e4bb8857ebfff9b32e2e0bc800e206aba1e.patch)

>
> I don't remember what to expect from sediff for boolean rules. I had played
> around with removing rules with some of my earlier lua tools and I thought that
> sediff handled removing redundant rules from booleans, but I could be wrong.
>
> I will look at this more maybe tomorrow, but most likely after the Memorial day
> weekend.
>
> Jim
>
> --
> James Carter <jwcart2@tycho.nsa.gov>
> National Security Agency
--
Ondrej Mosnacek <omosnace at redhat dot com>
Software Engineer, Security Technologies
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Non-DoD Source] [PATCH userspace 0/4] Remove redundant rules when building policydb
  2019-05-24  8:54   ` Ondrej Mosnacek
@ 2019-05-24 16:01     ` jwcart2
  2019-05-24 20:00       ` Ondrej Mosnacek
  0 siblings, 1 reply; 15+ messages in thread
From: jwcart2 @ 2019-05-24 16:01 UTC (permalink / raw)
  To: Ondrej Mosnacek; +Cc: selinux

[-- Attachment #1: Type: text/plain, Size: 7424 bytes --]

On 5/24/19 4:54 AM, Ondrej Mosnacek wrote:
> On Thu, May 23, 2019 at 10:39 PM jwcart2 <jwcart2@tycho.nsa.gov> wrote:
>> On 5/23/19 6:24 AM, Ondrej Mosnacek wrote:
>>> This series implements an optional optimization step when building
>>> a policydb via semodule or secilc, which identifies and removes rules
>>> that are redundant -- i.e. they are already covered by a more general
>>> rule based on attribute inheritance.
>>>
>>> Since the performance penalty of this additional step is very small
>>> (it adds about 1 s to the current running time of ~20-30 s [1]) and
>>> it can have a big positive effect on the number of rules in policy
>>> (it manages to remove ~40% AV rules from Fedora 29 policy), the
>>> optimization is enabled by default and can be turned off using a
>>> command-line option (--no-optimize) in secilc and semodule [2].
>>>
>>> The optimization routine eliminates:
>>>    * all allow/neverallow/dontaudit/auditallow rules (including xperm
>>>      variants) that are covered by another more general rule,
>>>    * all conditional versions of the above rules that are covered by a
>>>      more general rule either in the unconditional table or in the same
>>>      branch of the same conditional.
>>>
>>> The optimization doesn't process other rules, since they currently
>>> do not support attributes. There is some room left for more precise
>>> optimization of conditional rules, but it would likely bring only
>>> little additional benefit.
>>>
>>> When the policy is mostly or fully expanded, the optimization should
>>> be turned off. If it isn't, the policy build time will increase a lot
>>> for no benefit. However, the complexity of optimization will be only
>>> linear w.r.t. the number of rules and so the impact should not be
>>> catastrophic. (When testing with secilc on a subset of Fedora policy
>>> with -X 100000 the build time was 1.7 s with optimization vs. 1 s
>>> without it.)
>>>
>>> Tested live on my Fedora 29 devel machine under normal use. No unusual
>>> AVCs were observed with optimized policy loaded.
>>>
>>> Travis build passed: https://travis-ci.org/WOnder93/selinux/builds/536157427
>>>
>>> NOTE: The xperm rule support wasn't tested -- I would welcome some
>>>         peer review/testing of this part.
>>>
>>> [1] As measured on my machine (Fedora 29 policy, x86_64).
>>> [2] I have no problem with switching it to opt-in if that is preferred.
>>>
>>> Ondrej Mosnacek (4):
>>>     libsepol: add a function to optimize kernel policy
>>>     secilc: optimize policy before writing
>>>     libsemanage: optimize policy on rebuild
>>>     semodule: add flag to disable policy optimization
>>>
>>>    libsemanage/include/semanage/handle.h      |   4 +
>>>    libsemanage/src/direct_api.c               |   7 +
>>>    libsemanage/src/handle.c                   |  13 +
>>>    libsemanage/src/handle.h                   |   1 +
>>>    libsemanage/src/libsemanage.map            |   5 +
>>>    libsepol/include/sepol/policydb.h          |   5 +
>>>    libsepol/include/sepol/policydb/policydb.h |   2 +
>>>    libsepol/src/libsepol.map.in               |   5 +
>>>    libsepol/src/optimize.c                    | 370 +++++++++++++++++++++
>>>    libsepol/src/policydb_public.c             |   5 +
>>>    policycoreutils/semodule/semodule.c        |  12 +-
>>>    secilc/secilc.c                            |  16 +-
>>>    12 files changed, 442 insertions(+), 3 deletions(-)
>>>    create mode 100644 libsepol/src/optimize.c
>>>
>>
>> It would be nice to have checkpolicy support this as well. It shouldn't be too
>> hard to do that.
> 
> Looking at checkpolicy.c, it looks like it only generates POLICY_BASE
> or POLICY_MODULE policy types. I currently limit the optimization only
> to POLICY_KERN type, because from comments in policydb.h I got the
> impression that other policy types have different structure and I'm
> not sure if they need some special handling. I don't have that much
> knowledge about SELinux userspace code yet... if you can give me some
> hints about the difference between the various POLICY_* types, then I
> will be happy to make some adjustments if they make sense.
> 

It is kind of confusing. I sent a patch to the list. You can incorporate that 
into your patch series or I can just do it after.

I've attached the test policy that I used and a test script. I haven't had a 
chance to dig more into what may be going on.

Jim


>>
>> I need to do some more testing, but I think something is not working correctly.
>>
>> I am starting from conf files here because I have both Fedora and Android ones
>> that I have used for testing and it is easier to run them through checkpolicy to
>> convert to CIL.
>>
>> With these rules:
>>
>> # Redundant 1
>> allow tp01 tpr1:cl01 { p01a p11a p01b p11b };
>> allow tp02 tpr1:cl01 { p01a p11a };
>> allow at02 tpr1:cl01 { p01a p11a p01b };
>>
>> # Redundant 2
>> dontaudit tp01 tpr2:cl01 { p01a p11a p01b p11b };
>> dontaudit tp02 tpr2:cl01 { p01a p11a };
>> dontaudit at02 tpr2:cl01 { p01a p11a p01b };
>>
>> # Redundant 3
>> allow at02 tpr3:cl01 { p01a p11a p01b };
>> if (b01) {
>>     allow tp01 tpr3:cl01 { p01a p11a p01b p11b };
>>     allow tp02 tpr3:cl01 { p01a p11a };
>> }
>>
>> # Redundant 4
>> dontaudit at02 tpr4:cl01 { p01a p11a p01b };
>> if (b01) {
>>     dontaudit tp01 tpr4:cl01 { p01a p11a p01b p11b };
>>     dontaudit tp02 tpr4:cl01 { p01a p11a };
>> }
>>
>>
>> I see the following from sediff:
>>
>> Allow Rules (0 Added, 1 Removed, 0 Modified)
>>      Removed Allow Rules: 1
>>         - allow tp02 tpr3:cl01 { p01a p11a }; [ b01 ]:True
>>
>> Dontaudit Rules (0 Added, 1 Removed, 1 Modified)
>>      Removed Dontaudit Rules: 1
>>         - dontaudit tp01 tpr4:cl01 { p01a p01b p11a p11b }; [ b01 ]:True
>>      Modified Dontaudit Rules: 1
>>         * dontaudit tp01 tpr2:cl01 { p01b p11a p01a -p11b };
>>
>> So it handles Redundant 1 just fine, but has problems with Redundant 2 which
>> should be the same.
> 
> Yes, I think I'm handling the dontaudit rules incorrectly... For some
> (historical?) reason they actually specify the permissions that *are*
> audited, although the semantic of combining multiple rules is still
> that a permission is dontaudited if there is at least one dontaudit
> rule for it, so the logic of handling the raw perms data has to be
> inverted for AVTAB_AUDITDENY entries. I had noticed earlier that
> AVTAB_AUDITDENY rules are handled differently but somehow I concluded
> that the perms values should still bitwise-or together...
> 
> Can you please try it with adding:
> 
> if (specified & AVTAB_AUDITDENY)
>      return (d1->data & d2->data) == d2->data;
> 
> to the beginning of match_avtab_datum() in optimize.c? (patch form
> here: https://github.com/WOnder93/selinux/commit/17c77e4bb8857ebfff9b32e2e0bc800e206aba1e.patch)
> 
>>
>> I don't remember what to expect from sediff for boolean rules. I had played
>> around with removing rules with some of my earlier lua tools and I thought that
>> sediff handled removing redundant rules from booleans, but I could be wrong.
>>
>> I will look at this more maybe tomorrow, but most likely after the Memorial day
>> weekend.
>>
>> Jim
>>
>> --
>> James Carter <jwcart2@tycho.nsa.gov>
>> National Security Agency
> --
> Ondrej Mosnacek <omosnace at redhat dot com>
> Software Engineer, Security Technologies
> Red Hat, Inc.
> 


-- 
James Carter <jwcart2@tycho.nsa.gov>
National Security Agency

[-- Attachment #2: test_01.conf --]
[-- Type: text/plain, Size: 4295 bytes --]

# All policy.conf rules
# Called test_02.conf in expected_pass/conf
# Added redundantallow rules that are covered by attribute

class cl01
class cl02
class cl03
class cl04
class clx

sid kernel
sid security
sid unlabeled

common cm01 { p11a p11b }
common cm02 { p22a p22b }

class cl01 inherits cm01 { p01a p01b }
class cl02 inherits cm02
class cl03 { p03a p03b }
class cl04 { p04a p04b }
class clx { ioctl }

default_user { cl01 cl02 cl03 } source;
default_role { cl01 } source;
default_type { cl02 } target;
default_range { cl03 } target low-high;

sensitivity s01 alias syslow;
sensitivity s02;
sensitivity s03 alias { syshigh maxsens };

dominance { s01 s02 s03 }

category c01 alias cat01;
category c02 alias { cat02a cat02b };
category c03;

level s01;
level s02:c01,c03;
level s03:c01.c03;

mlsconstrain cl01 { p01a } ((h1 dom h2) and (l1 domby h1));
mlsvalidatetrans cl02 ((l1 eq l2) or (l1 incomp l2));
mlsvalidatetrans cl02 ((l1 eq l2) or (t3 eq tpo));

policycap network_peer_controls;
policycap open_perms;

attribute at01;
attribute at02;

attribute_role ar01;
attribute_role ar02;

bool b01 false;
bool b02 true;

type tpo;
type tpx;
type tp01;
type tp02;
type tp03p;
type tp03c;
type tp04;
type tpr1;
type tpr2;
type tpr3;
type tpr4;
type tpr5;

typealias tp01 alias { ta01a ta01b };
typealias tp02 alias ta02;

typebounds tp03p tp03c;

typeattribute tp01 at01, at02;
typeattribute tp02 at02;

permissive tp01;

allow tp01 self:cl01 { p01a p11a };
allow tp01 ta01a:cl01 p01b;
allow tp01 at01:cl01 p11b;
allow tp01 tpo:cl02 p22a;
allow at02 tpo:cl02 p22b;
allow tp03p tpo:cl03 { p03a p03b };
allow tp03c tpo:cl03 p03a;
allow tp04 tpx:clx ioctl;
auditallow tp01 tpo:cl01 p01a;
dontaudit tp01 tpo:cl01 p01b;
neverallow tp01 tpo:cl01 p11a;

# Redundant 1
allow tp01 tpr1:cl01 { p01a p11a p01b p11b };
allow tp02 tpr1:cl01 { p01a p11a };
allow at02 tpr1:cl01 { p01a p11a p01b };

# Redundant 2
dontaudit tp01 tpr2:cl01 { p01a p11a p01b p11b };
dontaudit tp02 tpr2:cl01 { p01a p11a };
dontaudit at02 tpr2:cl01 { p01a p11a p01b };

# Redundant 3
allow at02 tpr3:cl01 { p01a p11a p01b };
if (b01) {
  allow tp01 tpr3:cl01 { p01a p11a p01b p11b };
  allow tp02 tpr3:cl01 { p01a p11a };
}

# Redundant 4
dontaudit at02 tpr4:cl01 { p01a p11a p01b };
if (b01) {
  dontaudit tp01 tpr4:cl01 { p01a p11a p01b p11b };
  dontaudit tp02 tpr4:cl01 { p01a p11a };
}

# Redundant 5

if (b01) {
  allow tp01 tpr5:cl01 { p01a p11a p01b p11b };
  allow tp02 tpr5:cl01 { p01a p11a };
} else {
  allow at02 tpr5:cl01 { p01a p11a p01b };
}

allowxperm tp04 tpx:clx ioctl 0x1234;
auditallowxperm tp04 tpx:clx ioctl 0x9911;
dontauditxperm tp04 tpx:clx ioctl 0x9922;
neverallowxperm tp04 tpx:clx ioctl 0x9933;

type_transition tp01 tpo:cl01 tp02;
type_member tp01 tpo:cl02 tp02;
type_change tp01 tpo:cl03 tp02;
type_transition tp01 tpo:cl04 tp02 "file01";

range_transition tp01 tpo:cl01 s02;  
range_transition tp01 tpo:cl02 s02 - s03:c01,cat02a;  

role rl01;
role rl02;
role rl03p;
role rl03c;

role rl01 types { tp01 tp02 };
role rl02 types { tp02 };
role rl03p types tp03p;
role rl03c types tp03c;

roleattribute rl01 ar01, ar02;
roleattribute rl02 ar02;

allow rl01 rl02;

role_transition rl01 tpo:cl01 rl02;

user us01 roles rl01 level s01 range s01 - s03:c01.c03;

constrain cl01 { p01b } not ((t1 == tpo) and (u1 != u2));
validatetrans cl02 ((u1 == u2) or (r1 == r2));
validatetrans cl02 ((u1 == u2) or (t3 == tpo));

sid kernel us01:rl01:tp01:syslow - syshigh:c01,cat02b,c03
sid security us01:rl01:tp01:s01 - s02
sid unlabeled us01:rl01:tp01:s02:c01,c03 - maxsens:cat01,c03

fs_use_xattr fs01 us01:rl01:tp01:s01;
fs_use_task fs02 us01:rl01:tp01:s01;
fs_use_trans fs03 us01:rl01:tp01:s01;
genfscon fs04 / us01:rl01:tp01:s01
portcon udp 1000 us01:rl01:tp01:s01
portcon udp 1001-1009 us01:rl01:tp01:s01
portcon tcp 2000 us01:rl01:tp01:s01
portcon tcp 2001-2009 us01:rl01:tp01:s01
portcon dccp 3000 us01:rl01:tp01:s01
portcon dccp 3001-3009 us01:rl01:tp01:s01
netifcon if01 us01:rl01:tp01:s01 us01:rl01:tp02:s01
nodecon 10.0.0.1 255.255.255.0 us01:rl01:tp01:s01
nodecon fc00::1 fc00::ffff us01:rl01:tp01:s01

# XEN
#pirqcon 65535 us01:rl01:tp01:s01
#iomemcon 0-99999 us01:rl01:tp01:s01
#ioportcon 0-99999 us01:rl01:tp01:s01
#pcidevicecon 99999 us01:rl01:tp01:s01
#devicetreecon "/PATH" us01:rl01:tp01:s01

[-- Attachment #3: test.sh --]
[-- Type: application/x-shellscript, Size: 990 bytes --]

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Non-DoD Source] Re: [PATCH userspace 0/4] Remove redundant rules when building policydb
  2019-05-23 14:08     ` Ondrej Mosnacek
@ 2019-05-24 16:02       ` jwcart2
  2019-05-24 20:04         ` Ondrej Mosnacek
  0 siblings, 1 reply; 15+ messages in thread
From: jwcart2 @ 2019-05-24 16:02 UTC (permalink / raw)
  To: Ondrej Mosnacek, Dominick Grift; +Cc: selinux

On 5/23/19 10:08 AM, Ondrej Mosnacek wrote:
> On Thu, May 23, 2019 at 3:40 PM Dominick Grift <dac.override@gmail.com> wrote:
>> On Thu, May 23, 2019 at 03:14:55PM +0200, Dominick Grift wrote:
>>> On Thu, May 23, 2019 at 12:24:45PM +0200, Ondrej Mosnacek wrote:
>>>> This series implements an optional optimization step when building
>>>> a policydb via semodule or secilc, which identifies and removes rules
>>>> that are redundant -- i.e. they are already covered by a more general
>>>> rule based on attribute inheritance.
>>>
>>> Some stats with dssp2-standard:
>>>
>>> [kcinimod@myguest dssp2-standard]$ time secilc -n `find . -name *.cil` -o policy.31.noopt
>>>
>>> real    0m9.278s
>>> user    0m7.036s
>>> sys     0m2.017s
>>> [kcinimod@myguest dssp2-standard]$ time secilc `find . -name *.cil` -o policy.31.opt
>>>
>>> real    0m19.343s
>>> user    0m16.939s
>>> sys     0m2.027s
>>> [kcinimod@myguest dssp2-standard]$ ls -lh policy.*
>>> -rw-rw-r--. 1 kcinimod kcinimod 2.4M May 23 15:11 policy.31.noopt
>>> -rw-rw-r--. 1 kcinimod kcinimod 2.3M May 23 15:12 policy.31.opt
>>>
>>> Was unable to see the actual diff as sediff got oom-killed on me
>>
>> According to percentage calculator thats roughly a 4 percent gain size-wise at a 47 percent performance penalty.
>> Looks like dssp2-standard is pretty efficient as it is.
> 
> Hmm, yeah, looks like I'll have to make it opt-in after all... or add
> some heuristic to decide if running the optimization is really worth
> it.
> 

Opt-in makes sense. How about just using 'O' for the option?

Jim

>>
>>>
>>>>
>>>> Since the performance penalty of this additional step is very small
>>>> (it adds about 1 s to the current running time of ~20-30 s [1]) and
>>>> it can have a big positive effect on the number of rules in policy
>>>> (it manages to remove ~40% AV rules from Fedora 29 policy), the
>>>> optimization is enabled by default and can be turned off using a
>>>> command-line option (--no-optimize) in secilc and semodule [2].
>>>>
>>>> The optimization routine eliminates:
>>>>   * all allow/neverallow/dontaudit/auditallow rules (including xperm
>>>>     variants) that are covered by another more general rule,
>>>>   * all conditional versions of the above rules that are covered by a
>>>>     more general rule either in the unconditional table or in the same
>>>>     branch of the same conditional.
>>>>
>>>> The optimization doesn't process other rules, since they currently
>>>> do not support attributes. There is some room left for more precise
>>>> optimization of conditional rules, but it would likely bring only
>>>> little additional benefit.
>>>>
>>>> When the policy is mostly or fully expanded, the optimization should
>>>> be turned off. If it isn't, the policy build time will increase a lot
>>>> for no benefit. However, the complexity of optimization will be only
>>>> linear w.r.t. the number of rules and so the impact should not be
>>>> catastrophic. (When testing with secilc on a subset of Fedora policy
>>>> with -X 100000 the build time was 1.7 s with optimization vs. 1 s
>>>> without it.)
>>>>
>>>> Tested live on my Fedora 29 devel machine under normal use. No unusual
>>>> AVCs were observed with optimized policy loaded.
>>>>
>>>> Travis build passed: https://travis-ci.org/WOnder93/selinux/builds/536157427
>>>>
>>>> NOTE: The xperm rule support wasn't tested -- I would welcome some
>>>>        peer review/testing of this part.
>>>>
>>>> [1] As measured on my machine (Fedora 29 policy, x86_64).
>>>> [2] I have no problem with switching it to opt-in if that is preferred.
>>>>
>>>> Ondrej Mosnacek (4):
>>>>    libsepol: add a function to optimize kernel policy
>>>>    secilc: optimize policy before writing
>>>>    libsemanage: optimize policy on rebuild
>>>>    semodule: add flag to disable policy optimization
>>>>
>>>>   libsemanage/include/semanage/handle.h      |   4 +
>>>>   libsemanage/src/direct_api.c               |   7 +
>>>>   libsemanage/src/handle.c                   |  13 +
>>>>   libsemanage/src/handle.h                   |   1 +
>>>>   libsemanage/src/libsemanage.map            |   5 +
>>>>   libsepol/include/sepol/policydb.h          |   5 +
>>>>   libsepol/include/sepol/policydb/policydb.h |   2 +
>>>>   libsepol/src/libsepol.map.in               |   5 +
>>>>   libsepol/src/optimize.c                    | 370 +++++++++++++++++++++
>>>>   libsepol/src/policydb_public.c             |   5 +
>>>>   policycoreutils/semodule/semodule.c        |  12 +-
>>>>   secilc/secilc.c                            |  16 +-
>>>>   12 files changed, 442 insertions(+), 3 deletions(-)
>>>>   create mode 100644 libsepol/src/optimize.c
>>>>
>>>> --
>>>> 2.20.1
>>>>
>>>
>>> --
>>> Key fingerprint = 5F4D 3CDB D3F8 3652 FBD8 02D5 3B6C 5F1D 2C7B 6B02
>>> https://sks-keyservers.net/pks/lookup?op=get&search=0x3B6C5F1D2C7B6B02
>>> Dominick Grift
>>
>>
>>
>> --
>> Key fingerprint = 5F4D 3CDB D3F8 3652 FBD8 02D5 3B6C 5F1D 2C7B 6B02
>> https://sks-keyservers.net/pks/lookup?op=get&search=0x3B6C5F1D2C7B6B02
>> Dominick Grift
> 
> 
> 


-- 
James Carter <jwcart2@tycho.nsa.gov>
National Security Agency

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Non-DoD Source] [PATCH userspace 0/4] Remove redundant rules when building policydb
  2019-05-24 16:01     ` jwcart2
@ 2019-05-24 20:00       ` Ondrej Mosnacek
  0 siblings, 0 replies; 15+ messages in thread
From: Ondrej Mosnacek @ 2019-05-24 20:00 UTC (permalink / raw)
  To: jwcart2; +Cc: selinux

On Fri, May 24, 2019 at 6:01 PM jwcart2 <jwcart2@tycho.nsa.gov> wrote:
> On 5/24/19 4:54 AM, Ondrej Mosnacek wrote:
> > On Thu, May 23, 2019 at 10:39 PM jwcart2 <jwcart2@tycho.nsa.gov> wrote:
> >> On 5/23/19 6:24 AM, Ondrej Mosnacek wrote:
> >>> This series implements an optional optimization step when building
> >>> a policydb via semodule or secilc, which identifies and removes rules
> >>> that are redundant -- i.e. they are already covered by a more general
> >>> rule based on attribute inheritance.
> >>>
> >>> Since the performance penalty of this additional step is very small
> >>> (it adds about 1 s to the current running time of ~20-30 s [1]) and
> >>> it can have a big positive effect on the number of rules in policy
> >>> (it manages to remove ~40% AV rules from Fedora 29 policy), the
> >>> optimization is enabled by default and can be turned off using a
> >>> command-line option (--no-optimize) in secilc and semodule [2].
> >>>
> >>> The optimization routine eliminates:
> >>>    * all allow/neverallow/dontaudit/auditallow rules (including xperm
> >>>      variants) that are covered by another more general rule,
> >>>    * all conditional versions of the above rules that are covered by a
> >>>      more general rule either in the unconditional table or in the same
> >>>      branch of the same conditional.
> >>>
> >>> The optimization doesn't process other rules, since they currently
> >>> do not support attributes. There is some room left for more precise
> >>> optimization of conditional rules, but it would likely bring only
> >>> little additional benefit.
> >>>
> >>> When the policy is mostly or fully expanded, the optimization should
> >>> be turned off. If it isn't, the policy build time will increase a lot
> >>> for no benefit. However, the complexity of optimization will be only
> >>> linear w.r.t. the number of rules and so the impact should not be
> >>> catastrophic. (When testing with secilc on a subset of Fedora policy
> >>> with -X 100000 the build time was 1.7 s with optimization vs. 1 s
> >>> without it.)
> >>>
> >>> Tested live on my Fedora 29 devel machine under normal use. No unusual
> >>> AVCs were observed with optimized policy loaded.
> >>>
> >>> Travis build passed: https://travis-ci.org/WOnder93/selinux/builds/536157427
> >>>
> >>> NOTE: The xperm rule support wasn't tested -- I would welcome some
> >>>         peer review/testing of this part.
> >>>
> >>> [1] As measured on my machine (Fedora 29 policy, x86_64).
> >>> [2] I have no problem with switching it to opt-in if that is preferred.
> >>>
> >>> Ondrej Mosnacek (4):
> >>>     libsepol: add a function to optimize kernel policy
> >>>     secilc: optimize policy before writing
> >>>     libsemanage: optimize policy on rebuild
> >>>     semodule: add flag to disable policy optimization
> >>>
> >>>    libsemanage/include/semanage/handle.h      |   4 +
> >>>    libsemanage/src/direct_api.c               |   7 +
> >>>    libsemanage/src/handle.c                   |  13 +
> >>>    libsemanage/src/handle.h                   |   1 +
> >>>    libsemanage/src/libsemanage.map            |   5 +
> >>>    libsepol/include/sepol/policydb.h          |   5 +
> >>>    libsepol/include/sepol/policydb/policydb.h |   2 +
> >>>    libsepol/src/libsepol.map.in               |   5 +
> >>>    libsepol/src/optimize.c                    | 370 +++++++++++++++++++++
> >>>    libsepol/src/policydb_public.c             |   5 +
> >>>    policycoreutils/semodule/semodule.c        |  12 +-
> >>>    secilc/secilc.c                            |  16 +-
> >>>    12 files changed, 442 insertions(+), 3 deletions(-)
> >>>    create mode 100644 libsepol/src/optimize.c
> >>>
> >>
> >> It would be nice to have checkpolicy support this as well. It shouldn't be too
> >> hard to do that.
> >
> > Looking at checkpolicy.c, it looks like it only generates POLICY_BASE
> > or POLICY_MODULE policy types. I currently limit the optimization only
> > to POLICY_KERN type, because from comments in policydb.h I got the
> > impression that other policy types have different structure and I'm
> > not sure if they need some special handling. I don't have that much
> > knowledge about SELinux userspace code yet... if you can give me some
> > hints about the difference between the various POLICY_* types, then I
> > will be happy to make some adjustments if they make sense.
> >
>
> It is kind of confusing. I sent a patch to the list. You can incorporate that
> into your patch series or I can just do it after.

Thanks, I'll have a look at it and probably just include in v2.

>
> I've attached the test policy that I used and a test script. I haven't had a
> chance to dig more into what may be going on.

Cool, this test policy will also help me test the xperms support,
thanks! I will play with it tomorrow or on Monday.

I'm ~95% sure that my incremental patch will fix the dontaudit issue -
if I manage to verify it, then I'll squash it in and include in v2.

>
> Jim
>
>
> >>
> >> I need to do some more testing, but I think something is not working correctly.
> >>
> >> I am starting from conf files here because I have both Fedora and Android ones
> >> that I have used for testing and it is easier to run them through checkpolicy to
> >> convert to CIL.
> >>
> >> With these rules:
> >>
> >> # Redundant 1
> >> allow tp01 tpr1:cl01 { p01a p11a p01b p11b };
> >> allow tp02 tpr1:cl01 { p01a p11a };
> >> allow at02 tpr1:cl01 { p01a p11a p01b };
> >>
> >> # Redundant 2
> >> dontaudit tp01 tpr2:cl01 { p01a p11a p01b p11b };
> >> dontaudit tp02 tpr2:cl01 { p01a p11a };
> >> dontaudit at02 tpr2:cl01 { p01a p11a p01b };
> >>
> >> # Redundant 3
> >> allow at02 tpr3:cl01 { p01a p11a p01b };
> >> if (b01) {
> >>     allow tp01 tpr3:cl01 { p01a p11a p01b p11b };
> >>     allow tp02 tpr3:cl01 { p01a p11a };
> >> }
> >>
> >> # Redundant 4
> >> dontaudit at02 tpr4:cl01 { p01a p11a p01b };
> >> if (b01) {
> >>     dontaudit tp01 tpr4:cl01 { p01a p11a p01b p11b };
> >>     dontaudit tp02 tpr4:cl01 { p01a p11a };
> >> }
> >>
> >>
> >> I see the following from sediff:
> >>
> >> Allow Rules (0 Added, 1 Removed, 0 Modified)
> >>      Removed Allow Rules: 1
> >>         - allow tp02 tpr3:cl01 { p01a p11a }; [ b01 ]:True
> >>
> >> Dontaudit Rules (0 Added, 1 Removed, 1 Modified)
> >>      Removed Dontaudit Rules: 1
> >>         - dontaudit tp01 tpr4:cl01 { p01a p01b p11a p11b }; [ b01 ]:True
> >>      Modified Dontaudit Rules: 1
> >>         * dontaudit tp01 tpr2:cl01 { p01b p11a p01a -p11b };
> >>
> >> So it handles Redundant 1 just fine, but has problems with Redundant 2 which
> >> should be the same.
> >
> > Yes, I think I'm handling the dontaudit rules incorrectly... For some
> > (historical?) reason they actually specify the permissions that *are*
> > audited, although the semantic of combining multiple rules is still
> > that a permission is dontaudited if there is at least one dontaudit
> > rule for it, so the logic of handling the raw perms data has to be
> > inverted for AVTAB_AUDITDENY entries. I had noticed earlier that
> > AVTAB_AUDITDENY rules are handled differently but somehow I concluded
> > that the perms values should still bitwise-or together...
> >
> > Can you please try it with adding:
> >
> > if (specified & AVTAB_AUDITDENY)
> >      return (d1->data & d2->data) == d2->data;
> >
> > to the beginning of match_avtab_datum() in optimize.c? (patch form
> > here: https://github.com/WOnder93/selinux/commit/17c77e4bb8857ebfff9b32e2e0bc800e206aba1e.patch)
> >
> >>
> >> I don't remember what to expect from sediff for boolean rules. I had played
> >> around with removing rules with some of my earlier lua tools and I thought that
> >> sediff handled removing redundant rules from booleans, but I could be wrong.
> >>
> >> I will look at this more maybe tomorrow, but most likely after the Memorial day
> >> weekend.
> >>
> >> Jim
> >>
> >> --
> >> James Carter <jwcart2@tycho.nsa.gov>
> >> National Security Agency
> > --
> > Ondrej Mosnacek <omosnace at redhat dot com>
> > Software Engineer, Security Technologies
> > Red Hat, Inc.
> >
>
>
> --
> James Carter <jwcart2@tycho.nsa.gov>
> National Security Agency

-- 
Ondrej Mosnacek <omosnace at redhat dot com>
Software Engineer, Security Technologies
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Non-DoD Source] Re: [PATCH userspace 0/4] Remove redundant rules when building policydb
  2019-05-24 16:02       ` [Non-DoD Source] " jwcart2
@ 2019-05-24 20:04         ` Ondrej Mosnacek
  0 siblings, 0 replies; 15+ messages in thread
From: Ondrej Mosnacek @ 2019-05-24 20:04 UTC (permalink / raw)
  To: jwcart2; +Cc: Dominick Grift, selinux

On Fri, May 24, 2019 at 6:02 PM jwcart2 <jwcart2@tycho.nsa.gov> wrote:
> On 5/23/19 10:08 AM, Ondrej Mosnacek wrote:
> > On Thu, May 23, 2019 at 3:40 PM Dominick Grift <dac.override@gmail.com> wrote:
> >> On Thu, May 23, 2019 at 03:14:55PM +0200, Dominick Grift wrote:
> >>> On Thu, May 23, 2019 at 12:24:45PM +0200, Ondrej Mosnacek wrote:
> >>>> This series implements an optional optimization step when building
> >>>> a policydb via semodule or secilc, which identifies and removes rules
> >>>> that are redundant -- i.e. they are already covered by a more general
> >>>> rule based on attribute inheritance.
> >>>
> >>> Some stats with dssp2-standard:
> >>>
> >>> [kcinimod@myguest dssp2-standard]$ time secilc -n `find . -name *.cil` -o policy.31.noopt
> >>>
> >>> real    0m9.278s
> >>> user    0m7.036s
> >>> sys     0m2.017s
> >>> [kcinimod@myguest dssp2-standard]$ time secilc `find . -name *.cil` -o policy.31.opt
> >>>
> >>> real    0m19.343s
> >>> user    0m16.939s
> >>> sys     0m2.027s
> >>> [kcinimod@myguest dssp2-standard]$ ls -lh policy.*
> >>> -rw-rw-r--. 1 kcinimod kcinimod 2.4M May 23 15:11 policy.31.noopt
> >>> -rw-rw-r--. 1 kcinimod kcinimod 2.3M May 23 15:12 policy.31.opt
> >>>
> >>> Was unable to see the actual diff as sediff got oom-killed on me
> >>
> >> According to percentage calculator thats roughly a 4 percent gain size-wise at a 47 percent performance penalty.
> >> Looks like dssp2-standard is pretty efficient as it is.
> >
> > Hmm, yeah, looks like I'll have to make it opt-in after all... or add
> > some heuristic to decide if running the optimization is really worth
> > it.
> >
>
> Opt-in makes sense. How about just using 'O' for the option?

Sure, I already have patches to convert to opt-in ready in my devel
branch [1]. Expect them to be incorporated in v2 respin.

[1] https://github.com/WOnder93/selinux/compare/master...optimize-policy-v2

>
> Jim
>
> >>
> >>>
> >>>>
> >>>> Since the performance penalty of this additional step is very small
> >>>> (it adds about 1 s to the current running time of ~20-30 s [1]) and
> >>>> it can have a big positive effect on the number of rules in policy
> >>>> (it manages to remove ~40% AV rules from Fedora 29 policy), the
> >>>> optimization is enabled by default and can be turned off using a
> >>>> command-line option (--no-optimize) in secilc and semodule [2].
> >>>>
> >>>> The optimization routine eliminates:
> >>>>   * all allow/neverallow/dontaudit/auditallow rules (including xperm
> >>>>     variants) that are covered by another more general rule,
> >>>>   * all conditional versions of the above rules that are covered by a
> >>>>     more general rule either in the unconditional table or in the same
> >>>>     branch of the same conditional.
> >>>>
> >>>> The optimization doesn't process other rules, since they currently
> >>>> do not support attributes. There is some room left for more precise
> >>>> optimization of conditional rules, but it would likely bring only
> >>>> little additional benefit.
> >>>>
> >>>> When the policy is mostly or fully expanded, the optimization should
> >>>> be turned off. If it isn't, the policy build time will increase a lot
> >>>> for no benefit. However, the complexity of optimization will be only
> >>>> linear w.r.t. the number of rules and so the impact should not be
> >>>> catastrophic. (When testing with secilc on a subset of Fedora policy
> >>>> with -X 100000 the build time was 1.7 s with optimization vs. 1 s
> >>>> without it.)
> >>>>
> >>>> Tested live on my Fedora 29 devel machine under normal use. No unusual
> >>>> AVCs were observed with optimized policy loaded.
> >>>>
> >>>> Travis build passed: https://travis-ci.org/WOnder93/selinux/builds/536157427
> >>>>
> >>>> NOTE: The xperm rule support wasn't tested -- I would welcome some
> >>>>        peer review/testing of this part.
> >>>>
> >>>> [1] As measured on my machine (Fedora 29 policy, x86_64).
> >>>> [2] I have no problem with switching it to opt-in if that is preferred.
> >>>>
> >>>> Ondrej Mosnacek (4):
> >>>>    libsepol: add a function to optimize kernel policy
> >>>>    secilc: optimize policy before writing
> >>>>    libsemanage: optimize policy on rebuild
> >>>>    semodule: add flag to disable policy optimization
> >>>>
> >>>>   libsemanage/include/semanage/handle.h      |   4 +
> >>>>   libsemanage/src/direct_api.c               |   7 +
> >>>>   libsemanage/src/handle.c                   |  13 +
> >>>>   libsemanage/src/handle.h                   |   1 +
> >>>>   libsemanage/src/libsemanage.map            |   5 +
> >>>>   libsepol/include/sepol/policydb.h          |   5 +
> >>>>   libsepol/include/sepol/policydb/policydb.h |   2 +
> >>>>   libsepol/src/libsepol.map.in               |   5 +
> >>>>   libsepol/src/optimize.c                    | 370 +++++++++++++++++++++
> >>>>   libsepol/src/policydb_public.c             |   5 +
> >>>>   policycoreutils/semodule/semodule.c        |  12 +-
> >>>>   secilc/secilc.c                            |  16 +-
> >>>>   12 files changed, 442 insertions(+), 3 deletions(-)
> >>>>   create mode 100644 libsepol/src/optimize.c
> >>>>
> >>>> --
> >>>> 2.20.1
> >>>>
> >>>
> >>> --
> >>> Key fingerprint = 5F4D 3CDB D3F8 3652 FBD8 02D5 3B6C 5F1D 2C7B 6B02
> >>> https://sks-keyservers.net/pks/lookup?op=get&search=0x3B6C5F1D2C7B6B02
> >>> Dominick Grift
> >>
> >>
> >>
> >> --
> >> Key fingerprint = 5F4D 3CDB D3F8 3652 FBD8 02D5 3B6C 5F1D 2C7B 6B02
> >> https://sks-keyservers.net/pks/lookup?op=get&search=0x3B6C5F1D2C7B6B02
> >> Dominick Grift
> >
> >
> >
>
>
> --
> James Carter <jwcart2@tycho.nsa.gov>
> National Security Agency



-- 
Ondrej Mosnacek <omosnace at redhat dot com>
Software Engineer, Security Technologies
Red Hat, Inc.

^ permalink raw reply	[flat|nested] 15+ messages in thread

* Re: [Non-DoD Source] [PATCH userspace 0/4] Remove redundant rules when building policydb
  2019-05-23 20:39 ` [Non-DoD Source] " jwcart2
  2019-05-24  8:54   ` Ondrej Mosnacek
@ 2019-05-27 17:11   ` Chris PeBenito
  1 sibling, 0 replies; 15+ messages in thread
From: Chris PeBenito @ 2019-05-27 17:11 UTC (permalink / raw)
  To: jwcart2, Ondrej Mosnacek, selinux

On 5/23/19 4:39 PM, jwcart2 wrote:
> With these rules:
> 
> # Redundant 1
> allow tp01 tpr1:cl01 { p01a p11a p01b p11b };
> allow tp02 tpr1:cl01 { p01a p11a };
> allow at02 tpr1:cl01 { p01a p11a p01b };
> 
> # Redundant 2
> dontaudit tp01 tpr2:cl01 { p01a p11a p01b p11b };
> dontaudit tp02 tpr2:cl01 { p01a p11a };
> dontaudit at02 tpr2:cl01 { p01a p11a p01b };
> 
> # Redundant 3
> allow at02 tpr3:cl01 { p01a p11a p01b };
> if (b01) {
>    allow tp01 tpr3:cl01 { p01a p11a p01b p11b };
>    allow tp02 tpr3:cl01 { p01a p11a };
> }
> 
> # Redundant 4
> dontaudit at02 tpr4:cl01 { p01a p11a p01b };
> if (b01) {
>    dontaudit tp01 tpr4:cl01 { p01a p11a p01b p11b };
>    dontaudit tp02 tpr4:cl01 { p01a p11a };
> }
> 
> 
> I see the following from sediff:
> 
> Allow Rules (0 Added, 1 Removed, 0 Modified)
>     Removed Allow Rules: 1
>        - allow tp02 tpr3:cl01 { p01a p11a }; [ b01 ]:True
> 
> Dontaudit Rules (0 Added, 1 Removed, 1 Modified)
>     Removed Dontaudit Rules: 1
>        - dontaudit tp01 tpr4:cl01 { p01a p01b p11a p11b }; [ b01 ]:True
>     Modified Dontaudit Rules: 1
>        * dontaudit tp01 tpr2:cl01 { p01b p11a p01a -p11b };
> 
> So it handles Redundant 1 just fine, but has problems with Redundant 2 
> which should be the same.
> 
> I don't remember what to expect from sediff for boolean rules. I had 
> played around with removing rules with some of my earlier lua tools and 
> I thought that sediff handled removing redundant rules from booleans, 
> but I could be wrong.

Sediff doesn't do this optimization at this time. Rules inside a 
conditional block won't be considered redundant to unconditional rules.


-- 
Chris PeBenito

^ permalink raw reply	[flat|nested] 15+ messages in thread

end of thread, other threads:[~2019-05-27 17:11 UTC | newest]

Thread overview: 15+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-05-23 10:24 [PATCH userspace 0/4] Remove redundant rules when building policydb Ondrej Mosnacek
2019-05-23 10:24 ` [PATCH userspace 1/4] libsepol: add a function to optimize kernel policy Ondrej Mosnacek
2019-05-23 10:24 ` [PATCH userspace 2/4] secilc: optimize policy before writing Ondrej Mosnacek
2019-05-23 10:24 ` [PATCH userspace 3/4] libsemanage: optimize policy on rebuild Ondrej Mosnacek
2019-05-23 10:24 ` [PATCH userspace 4/4] semodule: add flag to disable policy optimization Ondrej Mosnacek
2019-05-23 13:14 ` [PATCH userspace 0/4] Remove redundant rules when building policydb Dominick Grift
2019-05-23 13:39   ` Dominick Grift
2019-05-23 14:08     ` Ondrej Mosnacek
2019-05-24 16:02       ` [Non-DoD Source] " jwcart2
2019-05-24 20:04         ` Ondrej Mosnacek
2019-05-23 20:39 ` [Non-DoD Source] " jwcart2
2019-05-24  8:54   ` Ondrej Mosnacek
2019-05-24 16:01     ` jwcart2
2019-05-24 20:00       ` Ondrej Mosnacek
2019-05-27 17:11   ` Chris PeBenito

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.