summaryrefslogtreecommitdiff
path: root/pcr
diff options
context:
space:
mode:
authorLuke Shumaker <lukeshu@sbcglobal.net>2017-02-03 13:02:37 -0500
committerLuke Shumaker <lukeshu@sbcglobal.net>2017-02-03 13:02:37 -0500
commitd9fecb8ab0f52272fd4785fe6f15e6855b2f6008 (patch)
treec519942cea1525634351674f609cfc0fcefceaa7 /pcr
parentb7f02b9741f313a6d6b96c1829d45fe09a39d0de (diff)
downloadabslibre-d9fecb8ab0f52272fd4785fe6f15e6855b2f6008.tar.gz
abslibre-d9fecb8ab0f52272fd4785fe6f15e6855b2f6008.tar.bz2
abslibre-d9fecb8ab0f52272fd4785fe6f15e6855b2f6008.zip
add pcr/libsepol
Diffstat (limited to 'pcr')
-rw-r--r--pcr/libsepol/0001-libsepol-cil-Check-for-improper-category-range.patch48
-rw-r--r--pcr/libsepol/0002-libsepol-cil-Use-empty-list-for-category-expression-.patch49
-rw-r--r--pcr/libsepol/0003-libsepol-cil-Use-an-empty-list-to-represent-an-unkno.patch47
-rw-r--r--pcr/libsepol/0004-libsepol-cil-Check-if-identifier-is-NULL-when-verify.patch44
-rw-r--r--pcr/libsepol/0005-libsepol-cil-Check-that-permission-is-not-an-empty-l.patch61
-rw-r--r--pcr/libsepol/0006-libsepol-cil-Verify-alias-in-aliasactual-statement-i.patch69
-rw-r--r--pcr/libsepol/0007-libsepol-cil-Verify-neither-child-nor-parent-in-a-bo.patch137
-rw-r--r--pcr/libsepol/0008-libsepol-cil-cil_strpool-Allow-multiple-strpool-user.patch100
-rw-r--r--pcr/libsepol/0009-libsepol-Add-symver-with-explicit-version-to-build-w.patch49
-rw-r--r--pcr/libsepol/0010-libsepol-cil-Exit-with-an-error-for-an-unknown-map-p.patch72
-rw-r--r--pcr/libsepol/0011-libsepol-sepol_-bool-iface-user-_key_create-copy-nam.patch126
-rw-r--r--pcr/libsepol/0012-libsepol-cil-remove-double-free.patch28
-rw-r--r--pcr/libsepol/0013-libsepol-fix-checkpolicy-dontaudit-compiler-bug.patch51
-rw-r--r--pcr/libsepol/0014-libsepol-test-for-ebitmap_read-negative-return-value.patch46
-rw-r--r--pcr/libsepol/PKGBUILD79
15 files changed, 1006 insertions, 0 deletions
diff --git a/pcr/libsepol/0001-libsepol-cil-Check-for-improper-category-range.patch b/pcr/libsepol/0001-libsepol-cil-Check-for-improper-category-range.patch
new file mode 100644
index 000000000..dc4c07ea5
--- /dev/null
+++ b/pcr/libsepol/0001-libsepol-cil-Check-for-improper-category-range.patch
@@ -0,0 +1,48 @@
+From 0763ecb640e0ad527ec21ba1f9bc95174744b12b Mon Sep 17 00:00:00 2001
+From: James Carter <jwcart2@tycho.nsa.gov>
+Date: Tue, 18 Oct 2016 14:17:03 -0400
+Subject: [PATCH] libsepol/cil: Check for improper category range
+
+Nicolas Iooss found while fuzzing secilc with AFL that the following
+policy will cause a segfault.
+
+(category c0)
+(category c1)
+(categoryorder (c0 c1))
+(sensitivity s0)
+(sensitivitycategory s0 (range c1 c0))
+
+The category range "(range c1 c0)" is invalid because c1 comes after c0
+in order.
+
+The invalid range is evaluated as containing no categories. There is a
+check for the resulting empty list and the category datum expression is
+set to NULL. The segfault occurs because the datum expression is assumed
+to be non-NULL after evaluation.
+
+Add a check for an invalid range when evaluating category ranges.
+
+Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
+---
+ libsepol/cil/src/cil_post.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
+index f8447c981486..caf3321d09e1 100644
+--- a/libsepol/cil/src/cil_post.c
++++ b/libsepol/cil/src/cil_post.c
+@@ -952,6 +952,11 @@ static int __cil_cat_expr_range_to_bitmap_helper(struct cil_list_item *i1, struc
+ c2 = alias->actual;
+ }
+
++ if (c1->value > c2->value) {
++ cil_log(CIL_ERR, "Invalid category range\n");
++ goto exit;
++ }
++
+ for (i = c1->value; i <= c2->value; i++) {
+ if (ebitmap_set_bit(bitmap, i, 1)) {
+ cil_log(CIL_ERR, "Failed to set cat bit\n");
+--
+2.10.2
+
diff --git a/pcr/libsepol/0002-libsepol-cil-Use-empty-list-for-category-expression-.patch b/pcr/libsepol/0002-libsepol-cil-Use-empty-list-for-category-expression-.patch
new file mode 100644
index 000000000..b3159e421
--- /dev/null
+++ b/pcr/libsepol/0002-libsepol-cil-Use-empty-list-for-category-expression-.patch
@@ -0,0 +1,49 @@
+From ce235e6b3c08ef4d06d4ac034868a0dafaa5cdbc Mon Sep 17 00:00:00 2001
+From: James Carter <jwcart2@tycho.nsa.gov>
+Date: Tue, 18 Oct 2016 14:19:03 -0400
+Subject: [PATCH] libsepol/cil: Use empty list for category expression
+ evaluated as empty
+
+Nicolas Iooss found while fuzzing secilc with AFL that the following
+policy will cause a segfault.
+
+(category c0)
+(category c1)
+(categoryorder (c0 c1))
+(sensitivity s0)
+(sensitivitycategory s0 (not (all)))
+
+The expression "(not (all))" is evaluated as containing no categories.
+There is a check for the resulting empty list and the category datum
+expression is set to NULL. The segfault occurs because the datum
+expression is assumed to be non-NULL after evaluation.
+
+Assign the list to the datum expression even if it is empty.
+
+Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
+---
+ libsepol/cil/src/cil_post.c | 8 +-------
+ 1 file changed, 1 insertion(+), 7 deletions(-)
+
+diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
+index caf3321d09e1..687962eae5ee 100644
+--- a/libsepol/cil/src/cil_post.c
++++ b/libsepol/cil/src/cil_post.c
+@@ -865,13 +865,7 @@ static int __evaluate_cat_expression(struct cil_cats *cats, struct cil_db *db)
+
+ ebitmap_destroy(&bitmap);
+ cil_list_destroy(&cats->datum_expr, CIL_FALSE);
+- if (new->head != NULL) {
+- cats->datum_expr = new;
+- } else {
+- /* empty list */
+- cil_list_destroy(&new, CIL_FALSE);
+- cats->datum_expr = NULL;
+- }
++ cats->datum_expr = new;
+
+ cats->evaluated = CIL_TRUE;
+
+--
+2.10.2
+
diff --git a/pcr/libsepol/0003-libsepol-cil-Use-an-empty-list-to-represent-an-unkno.patch b/pcr/libsepol/0003-libsepol-cil-Use-an-empty-list-to-represent-an-unkno.patch
new file mode 100644
index 000000000..04b527a4b
--- /dev/null
+++ b/pcr/libsepol/0003-libsepol-cil-Use-an-empty-list-to-represent-an-unkno.patch
@@ -0,0 +1,47 @@
+From e7fe9afb6e072c9e769586718060607ef7535c80 Mon Sep 17 00:00:00 2001
+From: James Carter <jwcart2@tycho.nsa.gov>
+Date: Tue, 18 Oct 2016 14:20:24 -0400
+Subject: [PATCH] libsepol/cil: Use an empty list to represent an unknown
+ permission
+
+Nicolas Iooss found while fuzzing secilc with AFL that the statement
+"(classpermissionset CPERM (CLASS (and unknow PERM)))" will cause a
+segfault.
+
+In order to support a policy module package using a permission that
+does not exist on the system it is loaded on, CIL will only give a
+warning when it fails to resolve an unknown permission. CIL itself will
+just ignore the unknown permission. This means that an expression like
+"(and UNKNOWN p1)" will look like "(and p1)" to CIL, but, since syntax
+checking has already been done, CIL won't know that the expression is not
+well-formed. When the expression is evaluated a segfault will occur
+because all expressions are assumed to be well-formed at evaluation time.
+
+Use an empty list to represent an unknown permission so that expressions
+will continue to be well-formed and expression evaluation will work but
+the unknown permission will still be ignored.
+
+Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
+---
+ libsepol/cil/src/cil_resolve_ast.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
+index c40354572ce7..f3f3e92739a3 100644
+--- a/libsepol/cil/src/cil_resolve_ast.c
++++ b/libsepol/cil/src/cil_resolve_ast.c
+@@ -131,7 +131,11 @@ static int __cil_resolve_perms(symtab_t *class_symtab, symtab_t *common_symtab,
+ }
+ }
+ if (rc != SEPOL_OK) {
++ struct cil_list *empty_list;
+ cil_log(CIL_WARN, "Failed to resolve permission %s\n", (char*)curr->data);
++ /* Use an empty list to represent unknown perm */
++ cil_list_init(&empty_list, perm_strs->flavor);
++ cil_list_append(*perm_datums, CIL_LIST, empty_list);
+ } else {
+ cil_list_append(*perm_datums, CIL_DATUM, perm_datum);
+ }
+--
+2.10.2
+
diff --git a/pcr/libsepol/0004-libsepol-cil-Check-if-identifier-is-NULL-when-verify.patch b/pcr/libsepol/0004-libsepol-cil-Check-if-identifier-is-NULL-when-verify.patch
new file mode 100644
index 000000000..7f286e02e
--- /dev/null
+++ b/pcr/libsepol/0004-libsepol-cil-Check-if-identifier-is-NULL-when-verify.patch
@@ -0,0 +1,44 @@
+From 5d3404acf99ac42cba5182fcbb099930754fc588 Mon Sep 17 00:00:00 2001
+From: James Carter <jwcart2@tycho.nsa.gov>
+Date: Tue, 18 Oct 2016 14:21:59 -0400
+Subject: [PATCH] libsepol/cil: Check if identifier is NULL when verifying name
+
+Nicolas Iooss found while fuzzing secilc with AFL that the statement
+"(class C (()))" will cause a segfault.
+
+When CIL checks the syntax of the class statement it sees "(())" as a
+valid permission list, but since "()" is not an identifier a NULL is
+passed as the string for name verification. A segfault occurs because
+name verification assumes that the string being checked is non-NULL.
+
+Check if identifier is NULL when verifying name.
+
+Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
+---
+ libsepol/cil/src/cil_verify.c | 8 +++++++-
+ 1 file changed, 7 insertions(+), 1 deletion(-)
+
+diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c
+index 038f77af57d7..47dcfaa27ca0 100644
+--- a/libsepol/cil/src/cil_verify.c
++++ b/libsepol/cil/src/cil_verify.c
+@@ -50,9 +50,15 @@
+ int __cil_verify_name(const char *name)
+ {
+ int rc = SEPOL_ERR;
+- int len = strlen(name);
++ int len;
+ int i = 0;
+
++ if (name == NULL) {
++ cil_log(CIL_ERR, "Name is NULL\n");
++ goto exit;
++ }
++
++ len = strlen(name);
+ if (len >= CIL_MAX_NAME_LENGTH) {
+ cil_log(CIL_ERR, "Name length greater than max name length of %d",
+ CIL_MAX_NAME_LENGTH);
+--
+2.10.2
+
diff --git a/pcr/libsepol/0005-libsepol-cil-Check-that-permission-is-not-an-empty-l.patch b/pcr/libsepol/0005-libsepol-cil-Check-that-permission-is-not-an-empty-l.patch
new file mode 100644
index 000000000..65d3fe44c
--- /dev/null
+++ b/pcr/libsepol/0005-libsepol-cil-Check-that-permission-is-not-an-empty-l.patch
@@ -0,0 +1,61 @@
+From 4ec8e698e8290d78a17de264a900654d312e3af0 Mon Sep 17 00:00:00 2001
+From: James Carter <jwcart2@tycho.nsa.gov>
+Date: Tue, 18 Oct 2016 14:41:41 -0400
+Subject: [PATCH] libsepol/cil: Check that permission is not an empty list
+
+Nicolas Iooss found while fuzzing secilc with AFL that the statement
+"(class C (()))" will cause a segfault.
+
+CIL expects a list of permissions in the class declaration and "(())"
+is a valid list. Each item of the list is expected to be an identifier
+and as the list is processed each item is checked to see if it is a
+list. An error is given if it is a list, otherwise the item is assumed
+to be an identifier. Unfortunately, the check only works if the list
+is not empty. In this case, the item passes the check and is assumed
+to be an identifier and a NULL is passed as the string for name
+verification. If name verification assumes that a non-NULL value will
+be passed in, a segfault will occur.
+
+Add a check for an empty list when processing a permission list and
+improve the error handling for permissions when building the AST.
+
+Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
+---
+ libsepol/cil/src/cil_build_ast.c | 7 +++++++
+ 1 file changed, 7 insertions(+)
+
+diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
+index ee283b535147..e4a0539f64ad 100644
+--- a/libsepol/cil/src/cil_build_ast.c
++++ b/libsepol/cil/src/cil_build_ast.c
+@@ -482,6 +482,10 @@ int cil_gen_perm(struct cil_db *db, struct cil_tree_node *parse_current, struct
+ cil_perm_init(&perm);
+
+ key = parse_current->data;
++ if (key == NULL) {
++ cil_log(CIL_ERR, "Bad permission\n");
++ goto exit;
++ }
+
+ rc = cil_gen_node(db, ast_node, (struct cil_symtab_datum*)perm, (hashtab_key_t)key, CIL_SYM_PERMS, flavor);
+ if (rc != SEPOL_OK) {
+@@ -529,6 +533,7 @@ int cil_gen_perm_nodes(struct cil_db *db, struct cil_tree_node *current_perm, st
+
+ rc = cil_gen_perm(db, current_perm, new_ast, flavor, num_perms);
+ if (rc != SEPOL_OK) {
++ cil_tree_node_destroy(&new_ast);
+ goto exit;
+ }
+
+@@ -546,6 +551,8 @@ int cil_gen_perm_nodes(struct cil_db *db, struct cil_tree_node *current_perm, st
+
+ exit:
+ cil_log(CIL_ERR, "Bad permissions\n");
++ cil_tree_children_destroy(ast_node);
++ cil_clear_node(ast_node);
+ return rc;
+ }
+
+--
+2.10.2
+
diff --git a/pcr/libsepol/0006-libsepol-cil-Verify-alias-in-aliasactual-statement-i.patch b/pcr/libsepol/0006-libsepol-cil-Verify-alias-in-aliasactual-statement-i.patch
new file mode 100644
index 000000000..050bd2f04
--- /dev/null
+++ b/pcr/libsepol/0006-libsepol-cil-Verify-alias-in-aliasactual-statement-i.patch
@@ -0,0 +1,69 @@
+From 1672a15c4a69db6b917bc46ac5f01b07ca506ee3 Mon Sep 17 00:00:00 2001
+From: James Carter <jwcart2@tycho.nsa.gov>
+Date: Tue, 18 Oct 2016 14:49:46 -0400
+Subject: [PATCH] libsepol/cil: Verify alias in aliasactual statement is really
+ an alias
+
+Nicolas Iooss found while fuzzing secilc with AFL that the statement
+"(sensitivityaliasactual SENS SENS)" will cause a segfault.
+
+The segfault occurs because when the aliasactual is resolved the first
+identifier is assumed to refer to an alias structure, but it is not.
+
+Add a check to verify that the datum retrieved is actually an alias
+and exit with an error if it is not.
+
+Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
+---
+ libsepol/cil/src/cil_resolve_ast.c | 13 +++++++++----
+ 1 file changed, 9 insertions(+), 4 deletions(-)
+
+diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
+index f3f3e92739a3..149e4f4e7d42 100644
+--- a/libsepol/cil/src/cil_resolve_ast.c
++++ b/libsepol/cil/src/cil_resolve_ast.c
+@@ -452,7 +452,7 @@ exit:
+ return rc;
+ }
+
+-int cil_resolve_aliasactual(struct cil_tree_node *current, void *extra_args, enum cil_flavor flavor)
++int cil_resolve_aliasactual(struct cil_tree_node *current, void *extra_args, enum cil_flavor flavor, enum cil_flavor alias_flavor)
+ {
+ int rc = SEPOL_ERR;
+ enum cil_sym_index sym_index;
+@@ -465,10 +465,15 @@ int cil_resolve_aliasactual(struct cil_tree_node *current, void *extra_args, enu
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
++
+ rc = cil_resolve_name(current, aliasactual->alias_str, sym_index, extra_args, &alias_datum);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
++ if (NODE(alias_datum)->flavor != alias_flavor) {
++ cil_log(CIL_ERR, "%s is not an alias\n",alias_datum->name);
++ goto exit;
++ }
+
+ rc = cil_resolve_name(current, aliasactual->actual_str, sym_index, extra_args, &actual_datum);
+ if (rc != SEPOL_OK) {
+@@ -3365,13 +3370,13 @@ int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
+ case CIL_PASS_ALIAS1:
+ switch (node->flavor) {
+ case CIL_TYPEALIASACTUAL:
+- rc = cil_resolve_aliasactual(node, args, CIL_TYPE);
++ rc = cil_resolve_aliasactual(node, args, CIL_TYPE, CIL_TYPEALIAS);
+ break;
+ case CIL_SENSALIASACTUAL:
+- rc = cil_resolve_aliasactual(node, args, CIL_SENS);
++ rc = cil_resolve_aliasactual(node, args, CIL_SENS, CIL_SENSALIAS);
+ break;
+ case CIL_CATALIASACTUAL:
+- rc = cil_resolve_aliasactual(node, args, CIL_CAT);
++ rc = cil_resolve_aliasactual(node, args, CIL_CAT, CIL_CATALIAS);
+ break;
+ default:
+ break;
+--
+2.10.2
+
diff --git a/pcr/libsepol/0007-libsepol-cil-Verify-neither-child-nor-parent-in-a-bo.patch b/pcr/libsepol/0007-libsepol-cil-Verify-neither-child-nor-parent-in-a-bo.patch
new file mode 100644
index 000000000..bed074d59
--- /dev/null
+++ b/pcr/libsepol/0007-libsepol-cil-Verify-neither-child-nor-parent-in-a-bo.patch
@@ -0,0 +1,137 @@
+From ab1b88b4e9938048bafabeab7c87c456a5f96196 Mon Sep 17 00:00:00 2001
+From: James Carter <jwcart2@tycho.nsa.gov>
+Date: Tue, 18 Oct 2016 14:50:48 -0400
+Subject: [PATCH] libsepol/cil: Verify neither child nor parent in a bounds is
+ an attribute
+
+Nicolas Iooss found while fuzzing secilc with AFL that using an attribute
+as a child in a typebounds statement will cause a segfault.
+
+This happens because the child datum is assumed to be part of a cil_type
+struct when it is really part of a cil_typeattribute struct. The check to
+verify that it is a type and not an attribute comes after it is used.
+
+This bug effects user and role bounds as well because they do not check
+whether a datum refers to an attribute or not.
+
+Add checks to verify that neither the child nor the parent datum refer
+to an attribute before using them in user, role, and type bounds.
+
+Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
+---
+ libsepol/cil/src/cil_resolve_ast.c | 44 ++++++++++++++++----------------------
+ 1 file changed, 18 insertions(+), 26 deletions(-)
+
+diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
+index 149e4f4e7d42..ec547d38125d 100644
+--- a/libsepol/cil/src/cil_resolve_ast.c
++++ b/libsepol/cil/src/cil_resolve_ast.c
+@@ -2468,7 +2468,7 @@ exit:
+ }
+
+
+-int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil_flavor flavor)
++int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil_flavor flavor, enum cil_flavor attr_flavor)
+ {
+ int rc = SEPOL_ERR;
+ struct cil_bounds *bounds = current->data;
+@@ -2485,19 +2485,29 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
++ if (NODE(parent_datum)->flavor == attr_flavor) {
++ cil_log(CIL_ERR, "Bounds parent %s is an attribute\n", bounds->parent_str);
++ rc = SEPOL_ERR;
++ goto exit;
++ }
++
+
+ rc = cil_resolve_name(current, bounds->child_str, index, extra_args, &child_datum);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
++ if (NODE(child_datum)->flavor == attr_flavor) {
++ cil_log(CIL_ERR, "Bounds child %s is an attribute\n", bounds->child_str);
++ rc = SEPOL_ERR;
++ goto exit;
++ }
+
+ switch (flavor) {
+ case CIL_USER: {
+ struct cil_user *user = (struct cil_user *)child_datum;
+
+ if (user->bounds != NULL) {
+- struct cil_tree_node *node = user->bounds->datum.nodes->head->data;
+- cil_tree_log(node, CIL_ERR, "User %s already bound by parent", bounds->child_str);
++ cil_tree_log(NODE(user->bounds), CIL_ERR, "User %s already bound by parent", bounds->child_str);
+ rc = SEPOL_ERR;
+ goto exit;
+ }
+@@ -2509,8 +2519,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil
+ struct cil_role *role = (struct cil_role *)child_datum;
+
+ if (role->bounds != NULL) {
+- struct cil_tree_node *node = role->bounds->datum.nodes->head->data;
+- cil_tree_log(node, CIL_ERR, "Role %s already bound by parent", bounds->child_str);
++ cil_tree_log(NODE(role->bounds), CIL_ERR, "Role %s already bound by parent", bounds->child_str);
+ rc = SEPOL_ERR;
+ goto exit;
+ }
+@@ -2520,26 +2529,9 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil
+ }
+ case CIL_TYPE: {
+ struct cil_type *type = (struct cil_type *)child_datum;
+- struct cil_tree_node *node = NULL;
+
+ if (type->bounds != NULL) {
+- node = ((struct cil_symtab_datum *)type->bounds)->nodes->head->data;
+- cil_tree_log(node, CIL_ERR, "Type %s already bound by parent", bounds->child_str);
+- cil_tree_log(current, CIL_ERR, "Now being bound to parent %s", bounds->parent_str);
+- rc = SEPOL_ERR;
+- goto exit;
+- }
+-
+- node = parent_datum->nodes->head->data;
+- if (node->flavor == CIL_TYPEATTRIBUTE) {
+- cil_log(CIL_ERR, "Bounds parent %s is an attribute\n", bounds->parent_str);
+- rc = SEPOL_ERR;
+- goto exit;
+- }
+-
+- node = child_datum->nodes->head->data;
+- if (node->flavor == CIL_TYPEATTRIBUTE) {
+- cil_log(CIL_ERR, "Bounds child %s is an attribute\n", bounds->child_str);
++ cil_tree_log(NODE(type->bounds), CIL_ERR, "Type %s already bound by parent", bounds->child_str);
+ rc = SEPOL_ERR;
+ goto exit;
+ }
+@@ -3445,7 +3437,7 @@ int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
+ rc = cil_resolve_typeattributeset(node, args);
+ break;
+ case CIL_TYPEBOUNDS:
+- rc = cil_resolve_bounds(node, args, CIL_TYPE);
++ rc = cil_resolve_bounds(node, args, CIL_TYPE, CIL_TYPEATTRIBUTE);
+ break;
+ case CIL_TYPEPERMISSIVE:
+ rc = cil_resolve_typepermissive(node, args);
+@@ -3482,7 +3474,7 @@ int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
+ rc = cil_resolve_userrange(node, args);
+ break;
+ case CIL_USERBOUNDS:
+- rc = cil_resolve_bounds(node, args, CIL_USER);
++ rc = cil_resolve_bounds(node, args, CIL_USER, CIL_USERATTRIBUTE);
+ break;
+ case CIL_USERPREFIX:
+ rc = cil_resolve_userprefix(node, args);
+@@ -3504,7 +3496,7 @@ int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args)
+ rc = cil_resolve_roleallow(node, args);
+ break;
+ case CIL_ROLEBOUNDS:
+- rc = cil_resolve_bounds(node, args, CIL_ROLE);
++ rc = cil_resolve_bounds(node, args, CIL_ROLE, CIL_ROLEATTRIBUTE);
+ break;
+ case CIL_LEVEL:
+ rc = cil_resolve_level(node, (struct cil_level*)node->data, args);
+--
+2.10.2
+
diff --git a/pcr/libsepol/0008-libsepol-cil-cil_strpool-Allow-multiple-strpool-user.patch b/pcr/libsepol/0008-libsepol-cil-cil_strpool-Allow-multiple-strpool-user.patch
new file mode 100644
index 000000000..174fcf4b6
--- /dev/null
+++ b/pcr/libsepol/0008-libsepol-cil-cil_strpool-Allow-multiple-strpool-user.patch
@@ -0,0 +1,100 @@
+From 34549d299f80c1cb713ea3c10f690bf1572c3f9a Mon Sep 17 00:00:00 2001
+From: dcashman <dcashman@android.com>
+Date: Tue, 18 Oct 2016 14:31:51 -0700
+Subject: [PATCH] libsepol: cil: cil_strpool: Allow multiple strpool users.
+
+cil_strpool currently provides an interface to a statically stored
+global data structure. This interface does not accomodate multiple
+consumers, however, as two calls to cil_strpool_init() will lead to a
+memory leak and a call to cil_strpool_destroy() by one consumer will
+remove data from use by others, and subsequently lead to a segfault on
+the next cil_strpool_destroy() invocation.
+
+Add a reference counter so that the strpool is only initialized once and
+protect the exported interface with a mutex.
+
+Tested by calling cil_db_init() on two cil_dbs and then calling
+cil_db_destroy() on each.
+
+Signed-off-by: Daniel Cashman <dcashman@android.com>
+---
+ libsepol/cil/src/cil_strpool.c | 28 ++++++++++++++++++++++++----
+ 1 file changed, 24 insertions(+), 4 deletions(-)
+
+diff --git a/libsepol/cil/src/cil_strpool.c b/libsepol/cil/src/cil_strpool.c
+index ad2a334f8ebf..5b7df8c6e0ce 100644
+--- a/libsepol/cil/src/cil_strpool.c
++++ b/libsepol/cil/src/cil_strpool.c
+@@ -27,6 +27,7 @@
+ * either expressed or implied, of Tresys Technology, LLC.
+ */
+
++#include <pthread.h>
+ #include <stdlib.h>
+ #include <stdio.h>
+ #include <string.h>
+@@ -40,6 +41,8 @@ struct cil_strpool_entry {
+ char *str;
+ };
+
++static pthread_mutex_t cil_strpool_mutex = PTHREAD_MUTEX_INITIALIZER;
++static unsigned int cil_strpool_readers = 0;
+ static hashtab_t cil_strpool_tab = NULL;
+
+ static unsigned int cil_strpool_hash(hashtab_t h, hashtab_key_t key)
+@@ -68,16 +71,21 @@ char *cil_strpool_add(const char *str)
+ {
+ struct cil_strpool_entry *strpool_ref = NULL;
+
++ pthread_mutex_lock(&cil_strpool_mutex);
++
+ strpool_ref = hashtab_search(cil_strpool_tab, (hashtab_key_t)str);
+ if (strpool_ref == NULL) {
+ strpool_ref = cil_malloc(sizeof(*strpool_ref));
+ strpool_ref->str = cil_strdup(str);
+ int rc = hashtab_insert(cil_strpool_tab, (hashtab_key_t)strpool_ref->str, strpool_ref);
+ if (rc != SEPOL_OK) {
++ pthread_mutex_unlock(&cil_strpool_mutex);
+ (*cil_mem_error_handler)();
++ pthread_mutex_lock(&cil_strpool_mutex);
+ }
+ }
+
++ pthread_mutex_unlock(&cil_strpool_mutex);
+ return strpool_ref->str;
+ }
+
+@@ -91,14 +99,26 @@ static int cil_strpool_entry_destroy(hashtab_key_t k __attribute__ ((unused)), h
+
+ void cil_strpool_init(void)
+ {
+- cil_strpool_tab = hashtab_create(cil_strpool_hash, cil_strpool_compare, CIL_STRPOOL_TABLE_SIZE);
++ pthread_mutex_lock(&cil_strpool_mutex);
+ if (cil_strpool_tab == NULL) {
+- (*cil_mem_error_handler)();
++ cil_strpool_tab = hashtab_create(cil_strpool_hash, cil_strpool_compare, CIL_STRPOOL_TABLE_SIZE);
++ if (cil_strpool_tab == NULL) {
++ pthread_mutex_unlock(&cil_strpool_mutex);
++ (*cil_mem_error_handler)();
++ return;
++ }
+ }
++ cil_strpool_readers++;
++ pthread_mutex_unlock(&cil_strpool_mutex);
+ }
+
+ void cil_strpool_destroy(void)
+ {
+- hashtab_map(cil_strpool_tab, cil_strpool_entry_destroy, NULL);
+- hashtab_destroy(cil_strpool_tab);
++ pthread_mutex_lock(&cil_strpool_mutex);
++ cil_strpool_readers--;
++ if (cil_strpool_readers == 0) {
++ hashtab_map(cil_strpool_tab, cil_strpool_entry_destroy, NULL);
++ hashtab_destroy(cil_strpool_tab);
++ }
++ pthread_mutex_unlock(&cil_strpool_mutex);
+ }
+--
+2.10.2
+
diff --git a/pcr/libsepol/0009-libsepol-Add-symver-with-explicit-version-to-build-w.patch b/pcr/libsepol/0009-libsepol-Add-symver-with-explicit-version-to-build-w.patch
new file mode 100644
index 000000000..f74445220
--- /dev/null
+++ b/pcr/libsepol/0009-libsepol-Add-symver-with-explicit-version-to-build-w.patch
@@ -0,0 +1,49 @@
+From 5786d4dd8a6390a103504c6be7264893bbb5c901 Mon Sep 17 00:00:00 2001
+From: Jason Zaman <jason@perfinion.com>
+Date: Mon, 31 Oct 2016 23:52:27 +0800
+Subject: [PATCH] libsepol: Add symver with explicit version to build with
+ ld.gold
+
+The blank default symver fails to compile with ld.gold. This updates the
+symver from blank to LIBSEPOL_1.0. The dynamic linker will first look
+for the symbol with the explicit version specified. If there is none, it
+will pick the first listed symbol so there is no breakage.
+This also matches how symvers are defined in libsemanage.
+
+Signed-off-by: Jason Zaman <jason@perfinion.com>
+---
+ libsepol/cil/src/cil.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
+index 929ab196926d..9b1877328a97 100644
+--- a/libsepol/cil/src/cil.c
++++ b/libsepol/cil/src/cil.c
+@@ -53,19 +53,19 @@
+ #include "dso.h"
+
+ #ifndef DISABLE_SYMVER
+-asm(".symver cil_build_policydb_pdb, cil_build_policydb@");
++asm(".symver cil_build_policydb_pdb, cil_build_policydb@LIBSEPOL_1.0");
+ asm(".symver cil_build_policydb_create_pdb, cil_build_policydb@@LIBSEPOL_1.1");
+
+-asm(".symver cil_compile_pdb, cil_compile@");
++asm(".symver cil_compile_pdb, cil_compile@LIBSEPOL_1.0");
+ asm(".symver cil_compile_nopdb, cil_compile@@LIBSEPOL_1.1");
+
+-asm(".symver cil_userprefixes_to_string_pdb, cil_userprefixes_to_string@");
++asm(".symver cil_userprefixes_to_string_pdb, cil_userprefixes_to_string@LIBSEPOL_1.0");
+ asm(".symver cil_userprefixes_to_string_nopdb, cil_userprefixes_to_string@@LIBSEPOL_1.1");
+
+-asm(".symver cil_selinuxusers_to_string_pdb, cil_selinuxusers_to_string@");
++asm(".symver cil_selinuxusers_to_string_pdb, cil_selinuxusers_to_string@LIBSEPOL_1.0");
+ asm(".symver cil_selinuxusers_to_string_nopdb, cil_selinuxusers_to_string@@LIBSEPOL_1.1");
+
+-asm(".symver cil_filecons_to_string_pdb, cil_filecons_to_string@");
++asm(".symver cil_filecons_to_string_pdb, cil_filecons_to_string@LIBSEPOL_1.0");
+ asm(".symver cil_filecons_to_string_nopdb, cil_filecons_to_string@@LIBSEPOL_1.1");
+ #endif
+
+--
+2.10.2
+
diff --git a/pcr/libsepol/0010-libsepol-cil-Exit-with-an-error-for-an-unknown-map-p.patch b/pcr/libsepol/0010-libsepol-cil-Exit-with-an-error-for-an-unknown-map-p.patch
new file mode 100644
index 000000000..d1308b72d
--- /dev/null
+++ b/pcr/libsepol/0010-libsepol-cil-Exit-with-an-error-for-an-unknown-map-p.patch
@@ -0,0 +1,72 @@
+From 991de68ce07cb83f442547160e30a63806e69e27 Mon Sep 17 00:00:00 2001
+From: James Carter <jwcart2@tycho.nsa.gov>
+Date: Wed, 2 Nov 2016 10:12:25 -0400
+Subject: [PATCH] libsepol/cil: Exit with an error for an unknown map
+ permission
+
+Nicholas Iooss discovered that using an unknown permission with a
+map class will cause a segfault.
+
+CIL will only give a warning when it fails to resolve an unknown
+permission to support the use of policy module packages that use
+permissions that don't exit on the current system. When resolving
+the unknown map class permission an empty list is used to represent
+the unknown permission. When it is evaluated later the list is
+assumed to be a permission and a segfault occurs.
+
+There is no reason to allow unknown class map permissions because
+the class maps and permissions are defined by the policy.
+
+Exit with an error when failing to resolve a class map permission.
+
+Reported-by: Nicolas Iooss <nicolas.iooss@m4x.org>
+Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
+---
+ libsepol/cil/src/cil_resolve_ast.c | 10 +++++++---
+ 1 file changed, 7 insertions(+), 3 deletions(-)
+
+diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c
+index ec547d38125d..7fe4a74d322f 100644
+--- a/libsepol/cil/src/cil_resolve_ast.c
++++ b/libsepol/cil/src/cil_resolve_ast.c
+@@ -106,7 +106,7 @@ static struct cil_name * __cil_insert_name(struct cil_db *db, hashtab_key_t key,
+ return name;
+ }
+
+-static int __cil_resolve_perms(symtab_t *class_symtab, symtab_t *common_symtab, struct cil_list *perm_strs, struct cil_list **perm_datums)
++static int __cil_resolve_perms(symtab_t *class_symtab, symtab_t *common_symtab, struct cil_list *perm_strs, struct cil_list **perm_datums, enum cil_flavor class_flavor)
+ {
+ int rc = SEPOL_ERR;
+ struct cil_list_item *curr;
+@@ -116,7 +116,7 @@ static int __cil_resolve_perms(symtab_t *class_symtab, symtab_t *common_symtab,
+ cil_list_for_each(curr, perm_strs) {
+ if (curr->flavor == CIL_LIST) {
+ struct cil_list *sub_list;
+- rc = __cil_resolve_perms(class_symtab, common_symtab, curr->data, &sub_list);
++ rc = __cil_resolve_perms(class_symtab, common_symtab, curr->data, &sub_list, class_flavor);
+ if (rc != SEPOL_OK) {
+ cil_log(CIL_ERR, "Failed to resolve permission list\n");
+ goto exit;
+@@ -132,6 +132,10 @@ static int __cil_resolve_perms(symtab_t *class_symtab, symtab_t *common_symtab,
+ }
+ if (rc != SEPOL_OK) {
+ struct cil_list *empty_list;
++ if (class_flavor == CIL_MAP_CLASS) {
++ cil_log(CIL_ERR, "Failed to resolve permission %s for map class\n", (char*)curr->data);
++ goto exit;
++ }
+ cil_log(CIL_WARN, "Failed to resolve permission %s\n", (char*)curr->data);
+ /* Use an empty list to represent unknown perm */
+ cil_list_init(&empty_list, perm_strs->flavor);
+@@ -170,7 +174,7 @@ int cil_resolve_classperms(struct cil_tree_node *current, struct cil_classperms
+
+ cp->class = class;
+
+- rc = __cil_resolve_perms(&class->perms, common_symtab, cp->perm_strs, &cp->perms);
++ rc = __cil_resolve_perms(&class->perms, common_symtab, cp->perm_strs, &cp->perms, FLAVOR(datum));
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+--
+2.10.2
+
diff --git a/pcr/libsepol/0011-libsepol-sepol_-bool-iface-user-_key_create-copy-nam.patch b/pcr/libsepol/0011-libsepol-sepol_-bool-iface-user-_key_create-copy-nam.patch
new file mode 100644
index 000000000..82df34438
--- /dev/null
+++ b/pcr/libsepol/0011-libsepol-sepol_-bool-iface-user-_key_create-copy-nam.patch
@@ -0,0 +1,126 @@
+From b14534df3a481ea73eee578b90dcf34c96e4a2c9 Mon Sep 17 00:00:00 2001
+From: Stephen Smalley <sds@tycho.nsa.gov>
+Date: Tue, 8 Nov 2016 10:46:14 -0500
+Subject: [PATCH] libsepol: sepol_{bool|iface|user}_key_create: copy name
+
+The sepol_{bool|iface|user}_key_create() functions were not
+copying the name. This produces a use-after-free in the
+swig-generated code for python3 bindings. Copy the name
+in these functions, and free it upon sepol_{bool|iface|user}_key_free().
+
+Reported-by: Nicolas Iooss <nicolas.iooss@m4x.org>
+Signed-off-by: Stephen Smalley <sds@tycho.nsa.gov>
+---
+ libsepol/src/boolean_record.c | 10 ++++++++--
+ libsepol/src/iface_record.c | 10 ++++++++--
+ libsepol/src/user_record.c | 10 ++++++++--
+ 3 files changed, 24 insertions(+), 6 deletions(-)
+
+diff --git a/libsepol/src/boolean_record.c b/libsepol/src/boolean_record.c
+index 8b644138a3bc..ebef7f18f0f9 100644
+--- a/libsepol/src/boolean_record.c
++++ b/libsepol/src/boolean_record.c
+@@ -15,7 +15,7 @@ struct sepol_bool {
+
+ struct sepol_bool_key {
+ /* This boolean's name */
+- const char *name;
++ char *name;
+ };
+
+ int sepol_bool_key_create(sepol_handle_t * handle,
+@@ -30,7 +30,12 @@ int sepol_bool_key_create(sepol_handle_t * handle,
+ return STATUS_ERR;
+ }
+
+- tmp_key->name = name;
++ tmp_key->name = strdup(name);
++ if (!tmp_key->name) {
++ ERR(handle, "out of memory, " "could not create boolean key");
++ free(tmp_key);
++ return STATUS_ERR;
++ }
+
+ *key_ptr = tmp_key;
+ return STATUS_SUCCESS;
+@@ -62,6 +67,7 @@ int sepol_bool_key_extract(sepol_handle_t * handle,
+
+ void sepol_bool_key_free(sepol_bool_key_t * key)
+ {
++ free(key->name);
+ free(key);
+ }
+
+diff --git a/libsepol/src/iface_record.c b/libsepol/src/iface_record.c
+index 09adeb79f5e9..c8b977c8facc 100644
+--- a/libsepol/src/iface_record.c
++++ b/libsepol/src/iface_record.c
+@@ -20,7 +20,7 @@ struct sepol_iface {
+ struct sepol_iface_key {
+
+ /* Interface name */
+- const char *name;
++ char *name;
+ };
+
+ /* Key */
+@@ -36,7 +36,12 @@ int sepol_iface_key_create(sepol_handle_t * handle,
+ return STATUS_ERR;
+ }
+
+- tmp_key->name = name;
++ tmp_key->name = strdup(name);
++ if (!tmp_key->name) {
++ ERR(handle, "out of memory, could not create interface key");
++ free(tmp_key);
++ return STATUS_ERR;
++ }
+
+ *key_ptr = tmp_key;
+ return STATUS_SUCCESS;
+@@ -68,6 +73,7 @@ int sepol_iface_key_extract(sepol_handle_t * handle,
+
+ void sepol_iface_key_free(sepol_iface_key_t * key)
+ {
++ free(key->name);
+ free(key);
+ }
+
+diff --git a/libsepol/src/user_record.c b/libsepol/src/user_record.c
+index c59c54b1e9b5..e7e2fc20fe36 100644
+--- a/libsepol/src/user_record.c
++++ b/libsepol/src/user_record.c
+@@ -24,7 +24,7 @@ struct sepol_user {
+
+ struct sepol_user_key {
+ /* This user's name */
+- const char *name;
++ char *name;
+ };
+
+ int sepol_user_key_create(sepol_handle_t * handle,
+@@ -40,7 +40,12 @@ int sepol_user_key_create(sepol_handle_t * handle,
+ return STATUS_ERR;
+ }
+
+- tmp_key->name = name;
++ tmp_key->name = strdup(name);
++ if (!tmp_key->name) {
++ ERR(handle, "out of memory, could not create selinux user key");
++ free(tmp_key);
++ return STATUS_ERR;
++ }
+
+ *key_ptr = tmp_key;
+ return STATUS_SUCCESS;
+@@ -71,6 +76,7 @@ int sepol_user_key_extract(sepol_handle_t * handle,
+
+ void sepol_user_key_free(sepol_user_key_t * key)
+ {
++ free(key->name);
+ free(key);
+ }
+
+--
+2.10.2
+
diff --git a/pcr/libsepol/0012-libsepol-cil-remove-double-free.patch b/pcr/libsepol/0012-libsepol-cil-remove-double-free.patch
new file mode 100644
index 000000000..7a169aec0
--- /dev/null
+++ b/pcr/libsepol/0012-libsepol-cil-remove-double-free.patch
@@ -0,0 +1,28 @@
+From 7b7e779ed2834f6d40ea5f9f6ea9b936d67e936c Mon Sep 17 00:00:00 2001
+From: dcashman <dcashman@android.com>
+Date: Fri, 11 Nov 2016 11:12:44 -0800
+Subject: [PATCH] libsepol: cil: remove double-free.
+
+Test: Untested patch.
+Bug: https://code.google.com/p/android/issues/detail?id=226519
+Change-Id: Icaf992ba1487098f2c4f16ac1017012f611281e9
+Signed-off-by: Daniel Cashman <dcashman@android.com>
+---
+ libsepol/cil/src/cil_binary.c | 1 -
+ 1 file changed, 1 deletion(-)
+
+diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
+index 540227290066..a813201f14c4 100644
+--- a/libsepol/cil/src/cil_binary.c
++++ b/libsepol/cil/src/cil_binary.c
+@@ -843,7 +843,6 @@ int cil_catalias_to_policydb(policydb_t *pdb, struct cil_alias *cil_alias)
+ key = cil_strdup(cil_alias->datum.fqn);
+ rc = symtab_insert(pdb, SYM_CATS, key, sepol_alias, SCOPE_DECL, 0, NULL);
+ if (rc != SEPOL_OK) {
+- free(key);
+ goto exit;
+ }
+ sepol_alias->s.value = sepol_cat->s.value;
+--
+2.10.2
+
diff --git a/pcr/libsepol/0013-libsepol-fix-checkpolicy-dontaudit-compiler-bug.patch b/pcr/libsepol/0013-libsepol-fix-checkpolicy-dontaudit-compiler-bug.patch
new file mode 100644
index 000000000..ff43a5e27
--- /dev/null
+++ b/pcr/libsepol/0013-libsepol-fix-checkpolicy-dontaudit-compiler-bug.patch
@@ -0,0 +1,51 @@
+From 00603062c7e9d74a76d62ee9806c9042ec7ad7fa Mon Sep 17 00:00:00 2001
+From: William Roberts <william.c.roberts@intel.com>
+Date: Tue, 15 Nov 2016 16:42:23 -0800
+Subject: [PATCH] libsepol: fix checkpolicy dontaudit compiler bug
+
+The combining logic for dontaudit rules was wrong, causing
+a dontaudit A B:C *; rule to be clobbered by a dontaudit A B:C p;
+rule.
+
+This is a reimplementation of:
+commit 6201bb5e258e2b5bcc04d502d6fbc05c69d21d71 ("libsepol:
+fix checkpolicy dontaudit compiler bug")
+that avoids the cumbersome pointer assignments on alloced.
+
+Reported-by: Nick Kralevich <nnk@google.com>
+Signed-off-by: William Roberts <william.c.roberts@intel.com>
+---
+ libsepol/src/expand.c | 10 ++++++----
+ 1 file changed, 6 insertions(+), 4 deletions(-)
+
+diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c
+index 004a02949b98..3e16f586028c 100644
+--- a/libsepol/src/expand.c
++++ b/libsepol/src/expand.c
+@@ -1640,6 +1640,11 @@ static avtab_ptr_t find_avtab_node(sepol_handle_t * handle,
+
+ if (!node) {
+ memset(&avdatum, 0, sizeof avdatum);
++ /*
++ * AUDITDENY, aka DONTAUDIT, are &= assigned, versus |= for
++ * others. Initialize the data accordingly.
++ */
++ avdatum.data = key->specified == AVTAB_AUDITDENY ? ~0 : 0;
+ /* this is used to get the node - insertion is actually unique */
+ node = avtab_insert_nonunique(avtab, key, &avdatum);
+ if (!node) {
+@@ -1850,10 +1855,7 @@ static int expand_avrule_helper(sepol_handle_t * handle,
+ */
+ avdatump->data &= cur->data;
+ } else if (specified & AVRULE_DONTAUDIT) {
+- if (avdatump->data)
+- avdatump->data &= ~cur->data;
+- else
+- avdatump->data = ~cur->data;
++ avdatump->data &= ~cur->data;
+ } else if (specified & AVRULE_XPERMS) {
+ xperms = avdatump->xperms;
+ if (!xperms) {
+--
+2.10.2
+
diff --git a/pcr/libsepol/0014-libsepol-test-for-ebitmap_read-negative-return-value.patch b/pcr/libsepol/0014-libsepol-test-for-ebitmap_read-negative-return-value.patch
new file mode 100644
index 000000000..2f61de026
--- /dev/null
+++ b/pcr/libsepol/0014-libsepol-test-for-ebitmap_read-negative-return-value.patch
@@ -0,0 +1,46 @@
+From 800b7dba36d42367ca3653711028d0658c2f6ef3 Mon Sep 17 00:00:00 2001
+From: Nicolas Iooss <nicolas.iooss@m4x.org>
+Date: Wed, 16 Nov 2016 00:07:22 +0100
+Subject: [PATCH] libsepol: test for ebitmap_read() negative return value
+
+While fuzzing hll/pp, the fuzzer (AFL) crafted a policy which triggered
+the following message without making the policy loading fail (the
+program crashed with a segmentation fault later):
+
+ security: ebitmap: map size 192 does not match my size 64 (high bit
+ was 0)
+
+This is because ebitmap_read() returned -EINVAL and this value was
+handled as a successful return value by scope_index_read() because it
+was not -1.
+
+Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>
+---
+ libsepol/src/policydb.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c
+index cdb3cde6b5e2..edac57e5f64c 100644
+--- a/libsepol/src/policydb.c
++++ b/libsepol/src/policydb.c
+@@ -3447,7 +3447,7 @@ static int scope_index_read(scope_index_t * scope_index,
+ int rc;
+
+ for (i = 0; i < num_scope_syms; i++) {
+- if (ebitmap_read(scope_index->scope + i, fp) == -1) {
++ if (ebitmap_read(scope_index->scope + i, fp) < 0) {
+ return -1;
+ }
+ }
+@@ -3465,7 +3465,7 @@ static int scope_index_read(scope_index_t * scope_index,
+ return -1;
+ }
+ for (i = 0; i < scope_index->class_perms_len; i++) {
+- if (ebitmap_read(scope_index->class_perms_map + i, fp) == -1) {
++ if (ebitmap_read(scope_index->class_perms_map + i, fp) < 0) {
+ return -1;
+ }
+ }
+--
+2.10.2
+
diff --git a/pcr/libsepol/PKGBUILD b/pcr/libsepol/PKGBUILD
new file mode 100644
index 000000000..7c6cb97e8
--- /dev/null
+++ b/pcr/libsepol/PKGBUILD
@@ -0,0 +1,79 @@
+# Maintainer: Luke Shumaker <lukeshu@parabola.nu>
+# Maintainer (AUR): Nicolas Iooss <nicolas.iooss@m4x.org>
+# Contributor (AUR): Timothée Ravier <tim@siosm.fr>
+# Contributor (AUR): Nicky726 <Nicky726@gmail.com>
+# Contributor (AUR): Sergej Pupykin <pupykin.s+arch@gmail.com>
+
+pkgname=libsepol
+_reldate=20161014
+pkgver=2.6
+pkgrel=1
+pkgdesc="SELinux binary policy manipulation library"
+arch=('i686' 'x86_64' 'armv6h')
+url='https://github.com/SELinuxProject/selinux/wiki/Userspace-Packages'
+license=('GPL')
+groups=('selinux')
+makedepends=('flex')
+depends=('glibc')
+options=(staticlibs)
+conflicts=("selinux-usr-${pkgname}")
+provides=("selinux-usr-${pkgname}=${pkgver}-${pkgrel}")
+source=("https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases/${_reldate}/${pkgname}-${pkgver}.tar.gz"
+ '0001-libsepol-cil-Check-for-improper-category-range.patch'
+ '0002-libsepol-cil-Use-empty-list-for-category-expression-.patch'
+ '0003-libsepol-cil-Use-an-empty-list-to-represent-an-unkno.patch'
+ '0004-libsepol-cil-Check-if-identifier-is-NULL-when-verify.patch'
+ '0005-libsepol-cil-Check-that-permission-is-not-an-empty-l.patch'
+ '0006-libsepol-cil-Verify-alias-in-aliasactual-statement-i.patch'
+ '0007-libsepol-cil-Verify-neither-child-nor-parent-in-a-bo.patch'
+ '0008-libsepol-cil-cil_strpool-Allow-multiple-strpool-user.patch'
+ '0009-libsepol-Add-symver-with-explicit-version-to-build-w.patch'
+ '0010-libsepol-cil-Exit-with-an-error-for-an-unknown-map-p.patch'
+ '0011-libsepol-sepol_-bool-iface-user-_key_create-copy-nam.patch'
+ '0012-libsepol-cil-remove-double-free.patch'
+ '0013-libsepol-fix-checkpolicy-dontaudit-compiler-bug.patch'
+ '0014-libsepol-test-for-ebitmap_read-negative-return-value.patch')
+sha256sums=('d856d6506054f52abeaa3543ea2f2344595a3dc05d0d873ed7f724f7a16b1874'
+ 'bf91f6ba2b8f48c927ac57d6a6b981931ce7b4450fe1d6500ea2c803c4e56626'
+ 'e92e97c35bb08831b08be75a35e7580d5aec5890ac3045300834d42c632b1dfd'
+ 'b454ca0b8cad91832d72a3aa2bb0e2a918ed83a64b569e61b8206b33956be1d8'
+ 'f609c47c156eb9dfa5d9e6de974bec53468f413d3b930730dafe2f5d2e50d108'
+ '99d0e405a1c1502193ee9f794f0694d6e0e9a6b8fdc3ce4848fb2677063b1060'
+ 'efc08e8c2ccf15004633d909f2eaab69b44329000eae66ef5489b02b6c87d957'
+ 'c90ffac363835b1c446834a79a71128a35ab4a9250b2277acbb21995e039bbf4'
+ '188836eb7511ae7cad1d7c4113c66632f37eeb81f91774d3baa83dd73217cb80'
+ '3958e086522aa0a51ee102b4a2b0c9e9430228e13c31eebaab889a0481e01c03'
+ '8abcd9786d3c87c17e93a186b798a6bf3b41a9835a729545cf47421c29afe3ea'
+ '92b5867df062dbc0bdc9ef10c14bf04e38bcf41d000a08b9694d61aa3a10fbe3'
+ '99c6c385bbed2955eeba2d20688857c93b37ad63599e461c476d0c8c9e2c5cd8'
+ 'ff189419f3c491b10c88cf2779936084cbf66cd6b89ed3118f3656660ebf2fcd'
+ '067a50c52556b4c6f346bb1dc7ba6d6c916c921aea11835ab0b79ed2332d1faf')
+
+prepare() {
+ cd "${pkgname}-${pkgver}"
+
+ patch -Np2 -i '../0001-libsepol-cil-Check-for-improper-category-range.patch'
+ patch -Np2 -i '../0002-libsepol-cil-Use-empty-list-for-category-expression-.patch'
+ patch -Np2 -i '../0003-libsepol-cil-Use-an-empty-list-to-represent-an-unkno.patch'
+ patch -Np2 -i '../0004-libsepol-cil-Check-if-identifier-is-NULL-when-verify.patch'
+ patch -Np2 -i '../0005-libsepol-cil-Check-that-permission-is-not-an-empty-l.patch'
+ patch -Np2 -i '../0006-libsepol-cil-Verify-alias-in-aliasactual-statement-i.patch'
+ patch -Np2 -i '../0007-libsepol-cil-Verify-neither-child-nor-parent-in-a-bo.patch'
+ patch -Np2 -i '../0008-libsepol-cil-cil_strpool-Allow-multiple-strpool-user.patch'
+ patch -Np2 -i '../0009-libsepol-Add-symver-with-explicit-version-to-build-w.patch'
+ patch -Np2 -i '../0010-libsepol-cil-Exit-with-an-error-for-an-unknown-map-p.patch'
+ patch -Np2 -i '../0011-libsepol-sepol_-bool-iface-user-_key_create-copy-nam.patch'
+ patch -Np2 -i '../0012-libsepol-cil-remove-double-free.patch'
+ patch -Np2 -i '../0013-libsepol-fix-checkpolicy-dontaudit-compiler-bug.patch'
+ patch -Np2 -i '../0014-libsepol-test-for-ebitmap_read-negative-return-value.patch'
+}
+
+build() {
+ cd "${pkgname}-${pkgver}"
+ make
+}
+
+package(){
+ cd "${pkgname}-${pkgver}"
+ make DESTDIR="${pkgdir}" LIBDIR="${pkgdir}"/usr/lib SHLIBDIR="${pkgdir}"/usr/lib install
+}