Patches as of 2018-03-06 release
diff --git a/patches/platform_external_selinux/0001-libsepol-cil-Add-ability-to-redeclare-types-attribut.patch b/patches/platform_external_selinux/0001-libsepol-cil-Add-ability-to-redeclare-types-attribut.patch
new file mode 100644
index 0000000..d38aec2
--- /dev/null
+++ b/patches/platform_external_selinux/0001-libsepol-cil-Add-ability-to-redeclare-types-attribut.patch
@@ -0,0 +1,208 @@
+From be352c253dffb5c0d952fbeef905c3269853b7e0 Mon Sep 17 00:00:00 2001
+From: Dan Cashman <dcashman@android.com>
+Date: Tue, 29 Aug 2017 09:32:05 -0700
+Subject: [PATCH 1/5] libsepol: cil: Add ability to redeclare types[attributes]
+
+Modify cil_gen_node() to check to see if the cil_db supports multiple
+declarations, and if so, to check whether or not the
+repeated symbol is eligible to share the existing, already-stored datum. The
+only types considered so far are CIL_TYPE and CIL_TYPEATTRIBUTE, both of
+which intall empty datums during AST building, so they automatically return
+true.
+
+Test: Build policy with multilpe type and attribute declarations, and
+without. Policies are binary-identical.
+
+Signed-off-by: Dan Cashman <dcashman@android.com>
+Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
+---
+ libsepol/cil/include/cil/cil.h   |  1 +
+ libsepol/cil/src/cil.c           |  5 +++++
+ libsepol/cil/src/cil_build_ast.c | 48 ++++++++++++++++++++++++++++++++++------
+ libsepol/cil/src/cil_internal.h  |  1 +
+ libsepol/src/libsepol.map.in     |  1 +
+ secilc/secilc.c                  |  9 +++++++-
+ 6 files changed, 57 insertions(+), 8 deletions(-)
+
+diff --git a/libsepol/cil/include/cil/cil.h b/libsepol/cil/include/cil/cil.h
+index 4507892c..4df646a0 100644
+--- a/libsepol/cil/include/cil/cil.h
++++ b/libsepol/cil/include/cil/cil.h
+@@ -46,6 +46,7 @@ extern int cil_userprefixes_to_string(cil_db_t *db, char **out, size_t *size);
+ extern int cil_selinuxusers_to_string(cil_db_t *db, char **out, size_t *size);
+ extern int cil_filecons_to_string(cil_db_t *db, char **out, size_t *size);
+ extern void cil_set_disable_dontaudit(cil_db_t *db, int disable_dontaudit);
++extern void cil_set_multiple_decls(cil_db_t *db, int multiple_decls);
+ extern void cil_set_disable_neverallow(cil_db_t *db, int disable_neverallow);
+ extern void cil_set_preserve_tunables(cil_db_t *db, int preserve_tunables);
+ extern int cil_set_handle_unknown(cil_db_t *db, int handle_unknown);
+diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
+index 9b9ccc36..e8bbbfdf 100644
+--- a/libsepol/cil/src/cil.c
++++ b/libsepol/cil/src/cil.c
+@@ -1675,6 +1675,11 @@ void cil_set_mls(struct cil_db *db, int mls)
+ 	db->mls = mls;
+ }
+ 
++void cil_set_multiple_decls(struct cil_db *db, int multiple_decls)
++{
++	db->multiple_decls = multiple_decls;
++}
++
+ void cil_set_target_platform(struct cil_db *db, int target_platform)
+ {
+ 	db->target_platform = target_platform;
+diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c
+index 36cc6735..9a10e7ab 100644
+--- a/libsepol/cil/src/cil_build_ast.c
++++ b/libsepol/cil/src/cil_build_ast.c
+@@ -82,10 +82,33 @@ exit:
+ 	return rc;
+ }
+ 
++/*
++ * Determine whether or not multiple declarations of the same key can share a
++ * datum, given the new datum and the one already present in a given symtab.
++ */
++int cil_is_datum_multiple_decl(__attribute__((unused)) struct cil_symtab_datum *cur,
++                               __attribute__((unused)) struct cil_symtab_datum *old,
++                               enum cil_flavor f)
++{
++	int rc = CIL_FALSE;
++
++	switch (f) {
++	case CIL_TYPE:
++	case CIL_TYPEATTRIBUTE:
++		/* type and typeattribute statements insert empty datums, ret true */
++		rc = CIL_TRUE;
++		break;
++	default:
++		break;
++	}
++	return rc;
++}
++
+ int cil_gen_node(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *ast_node, struct cil_symtab_datum *datum, hashtab_key_t key, enum cil_sym_index sflavor, enum cil_flavor nflavor)
+ {
+ 	int rc = SEPOL_ERR;
+ 	symtab_t *symtab = NULL;
++	struct cil_symtab_datum *prev;
+ 
+ 	rc = __cil_verify_name((const char*)key);
+ 	if (rc != SEPOL_OK) {
+@@ -103,15 +126,26 @@ int cil_gen_node(__attribute__((unused)) struct cil_db *db, struct cil_tree_node
+ 	if (symtab != NULL) {
+ 		rc = cil_symtab_insert(symtab, (hashtab_key_t)key, datum, ast_node);
+ 		if (rc == SEPOL_EEXIST) {
+-			cil_log(CIL_ERR, "Re-declaration of %s %s\n", 
+-				cil_node_to_string(ast_node), key);
+-			if (cil_symtab_get_datum(symtab, key, &datum) == SEPOL_OK) {
+-				if (sflavor == CIL_SYM_BLOCKS) {
+-					struct cil_tree_node *node = datum->nodes->head->data;
+-					cil_tree_log(node, CIL_ERR, "Previous declaration");
++			if (!db->multiple_decls ||
++			    cil_symtab_get_datum(symtab, (hashtab_key_t)key, &prev) != SEPOL_OK ||
++			    !cil_is_datum_multiple_decl(datum, prev, nflavor)) {
++
++				/* multiple_decls not ok, ret error */
++				cil_log(CIL_ERR, "Re-declaration of %s %s\n",
++					cil_node_to_string(ast_node), key);
++				if (cil_symtab_get_datum(symtab, key, &datum) == SEPOL_OK) {
++					if (sflavor == CIL_SYM_BLOCKS) {
++						struct cil_tree_node *node = datum->nodes->head->data;
++						cil_tree_log(node, CIL_ERR, "Previous declaration");
++					}
+ 				}
++				goto exit;
+ 			}
+-			goto exit;
++			/* multiple_decls is enabled and works for this datum type, add node */
++			cil_list_append(prev->nodes, CIL_NODE, ast_node);
++			ast_node->data = prev;
++			cil_symtab_datum_destroy(datum);
++			free(datum);
+ 		}
+ 	}
+ 
+diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
+index aee3f00c..abfacd8d 100644
+--- a/libsepol/cil/src/cil_internal.h
++++ b/libsepol/cil/src/cil_internal.h
+@@ -312,6 +312,7 @@ struct cil_db {
+ 	int preserve_tunables;
+ 	int handle_unknown;
+ 	int mls;
++	int multiple_decls;
+ 	int target_platform;
+ 	int policy_version;
+ };
+diff --git a/libsepol/src/libsepol.map.in b/libsepol/src/libsepol.map.in
+index 40426408..edd98d5a 100644
+--- a/libsepol/src/libsepol.map.in
++++ b/libsepol/src/libsepol.map.in
+@@ -47,6 +47,7 @@ LIBSEPOL_1.1 {
+ 	cil_set_mls;
+ 	cil_set_attrs_expand_generated;
+ 	cil_set_attrs_expand_size;
++	cil_set_multiple_decls;
+ 	cil_write_policy_conf;
+ 	sepol_ppfile_to_module_package;
+ 	sepol_module_package_to_cil;
+diff --git a/secilc/secilc.c b/secilc/secilc.c
+index f2232e72..0be6975b 100644
+--- a/secilc/secilc.c
++++ b/secilc/secilc.c
+@@ -63,6 +63,7 @@ static __attribute__((__noreturn__)) void usage(const char *prog)
+ 	printf("                                 statement if present in the policy\n");
+ 	printf("  -D, --disable-dontaudit        do not add dontaudit rules to the binary policy\n");
+ 	printf("  -P, --preserve-tunables        treat tunables as booleans\n");
++	printf("  -m, --multiple-decls           allow some statements to be re-declared\n");
+ 	printf("  -N, --disable-neverallow       do not check neverallow rules\n");
+ 	printf("  -G, --expand-generated         Expand and remove auto-generated attributes\n");
+ 	printf("  -X, --expand-size <SIZE>       Expand type attributes with fewer than <SIZE>\n");
+@@ -89,6 +90,7 @@ int main(int argc, char *argv[])
+ 	int target = SEPOL_TARGET_SELINUX;
+ 	int mls = -1;
+ 	int disable_dontaudit = 0;
++	int multiple_decls = 0;
+ 	int disable_neverallow = 0;
+ 	int preserve_tunables = 0;
+ 	int handle_unknown = -1;
+@@ -108,6 +110,7 @@ int main(int argc, char *argv[])
+ 		{"policyversion", required_argument, 0, 'c'},
+ 		{"handle-unknown", required_argument, 0, 'U'},
+ 		{"disable-dontaudit", no_argument, 0, 'D'},
++		{"multiple-decls", no_argument, 0, 'm'},
+ 		{"disable-neverallow", no_argument, 0, 'N'},
+ 		{"preserve-tunables", no_argument, 0, 'P'},
+ 		{"output", required_argument, 0, 'o'},
+@@ -119,7 +122,7 @@ int main(int argc, char *argv[])
+ 	int i;
+ 
+ 	while (1) {
+-		opt_char = getopt_long(argc, argv, "o:f:U:hvt:M:PDNc:GX:", long_opts, &opt_index);
++		opt_char = getopt_long(argc, argv, "o:f:U:hvt:M:PDmNc:GX:", long_opts, &opt_index);
+ 		if (opt_char == -1) {
+ 			break;
+ 		}
+@@ -175,6 +178,9 @@ int main(int argc, char *argv[])
+ 			case 'D':
+ 				disable_dontaudit = 1;
+ 				break;
++			case 'm':
++				multiple_decls = 1;
++				break;
+ 			case 'N':
+ 				disable_neverallow = 1;
+ 				break;
+@@ -223,6 +229,7 @@ int main(int argc, char *argv[])
+ 
+ 	cil_db_init(&db);
+ 	cil_set_disable_dontaudit(db, disable_dontaudit);
++	cil_set_multiple_decls(db, multiple_decls);
+ 	cil_set_disable_neverallow(db, disable_neverallow);
+ 	cil_set_preserve_tunables(db, preserve_tunables);
+ 	if (handle_unknown != -1) {
+-- 
+2.15.1
+
diff --git a/patches/platform_external_selinux/0002-libsepol-cil-Keep-type-attribute-declarations-when-a.patch b/patches/platform_external_selinux/0002-libsepol-cil-Keep-type-attribute-declarations-when-a.patch
new file mode 100644
index 0000000..f88b855
--- /dev/null
+++ b/patches/platform_external_selinux/0002-libsepol-cil-Keep-type-attribute-declarations-when-a.patch
@@ -0,0 +1,89 @@
+From 0a0c8e77b3a55c70ef55cd78aa5c2a4bce5b0862 Mon Sep 17 00:00:00 2001
+From: Dan Cashman <dcashman@google.com>
+Date: Wed, 11 Oct 2017 12:59:43 -0700
+Subject: [PATCH 2/5] libsepol: cil: Keep type[attribute] declarations when
+ attributizing.
+
+cil_android_attributize() uses a source policy to identify types and
+attributes to be versioned according to the given version number, and
+then proceeds to modify the provided target policy to provide this
+versioning.  Previously, the versioned policy relied on a base policy
+for the declarations of these type[attribute]s, but with multiple_decl
+support added, the declarations can be made in both places.  This will
+make the policy more robust and allow for greater flexibility and the
+types of base policy used.
+
+Bug: 37915794
+Test: Builds 'n' boots.  non_plat_sepolicy.cil now contains the public
+type[attribute] declarations.
+
+Change-Id: Iaa084211a9e2774a7ed391888fb21c4c0cf955db
+---
+ libsepol/cil/include/cil/android.h |  2 ++
+ libsepol/cil/src/android.c         | 17 ++++++++---------
+ 2 files changed, 10 insertions(+), 9 deletions(-)
+
+diff --git a/libsepol/cil/include/cil/android.h b/libsepol/cil/include/cil/android.h
+index 082d7fd2..5aceda62 100644
+--- a/libsepol/cil/include/cil/android.h
++++ b/libsepol/cil/include/cil/android.h
+@@ -21,6 +21,8 @@ int cil_android_attrib_mapping(struct cil_db **mdb, struct cil_db *srcdb, const
+ /*
+  * cil_android_attributize - extract attributizable elements of the policy in
+  * srcdb and convert all usage of those elements in tgtdb to versioned attributes.
++ * Keep the attributes and type definitions so that tgtdb policy is more robust
++ * against future changes to the public policy.
+  *   tgtdb - initialized and parsed cil_db reference to modify.
+  *   srcdb - initialized and parsed cil_db reference to source public policy
+  *           from which to extract attributizable elements.
+diff --git a/libsepol/cil/src/android.c b/libsepol/cil/src/android.c
+index 1d80046b..53df4187 100644
+--- a/libsepol/cil/src/android.c
++++ b/libsepol/cil/src/android.c
+@@ -200,23 +200,27 @@ static char *__cil_attrib_get_versname(char *old, const char *vers)
+ 
+ /*
+  * Change type to attribute - create new versioned name based on old, create
+- * typeattribute node and replace existing type node.
++ * typeattribute node add to the existing type node.
+  */
+ static int __cil_attrib_convert_type(struct cil_tree_node *node, struct version_args *args)
+ {
+ 	int rc = SEPOL_ERR;
+ 	struct cil_type *type = (struct cil_type *)node->data;
+ 	struct cil_typeattribute *typeattr = NULL;
++	struct cil_tree_node *new_ast_node = NULL;
+ 	char *new_key;
+ 
+ 	cil_typeattribute_init(&typeattr);
+ 
+ 	new_key = __cil_attrib_get_versname(type->datum.name, args->num);
+ 
+-	cil_symtab_datum_remove_node(&type->datum, node);
+-	cil_destroy_type(type);
++	/* create new tree node to contain typeattribute and add to tree */
++	cil_tree_node_init(&new_ast_node);
++	new_ast_node->parent = node->parent;
++	new_ast_node->next = node->next;
++	node->next = new_ast_node;
+ 
+-	rc = cil_gen_node(args->db, node, (struct cil_symtab_datum *) typeattr,
++	rc = cil_gen_node(args->db, new_ast_node, (struct cil_symtab_datum *) typeattr,
+ 			  new_key, CIL_SYM_TYPES, CIL_TYPEATTRIBUTE);
+ 	if (rc != SEPOL_OK) {
+ 		goto exit;
+@@ -422,11 +426,6 @@ static int cil_attrib_typeattribute(struct cil_tree_node *node, struct version_a
+ 		if (rc != SEPOL_OK) {
+ 			goto exit;
+ 		}
+-	} else if (__cil_get_plat_flavor(args->vers_map, key) == PLAT_ATTRIB) {
+-		// platform attribute declaration to be provided by platform policy
+-		cil_symtab_datum_remove_node(&typeattr->datum, node);
+-		cil_destroy_typeattribute(typeattr);
+-		node->flavor = CIL_NONE; // traversal relies on this node sticking around, empty it.
+ 	}
+ 
+ 	return SEPOL_OK;
+-- 
+2.15.1
+
diff --git a/patches/platform_external_selinux/0003-libsepol-cil-Create-new-keep-field-for-type-attribut.patch b/patches/platform_external_selinux/0003-libsepol-cil-Create-new-keep-field-for-type-attribut.patch
new file mode 100644
index 0000000..86f94f1
--- /dev/null
+++ b/patches/platform_external_selinux/0003-libsepol-cil-Create-new-keep-field-for-type-attribut.patch
@@ -0,0 +1,138 @@
+From 92fac49b74a4d83bd07b086e35f3e7dfe84fd429 Mon Sep 17 00:00:00 2001
+From: James Carter <jwcart2@tycho.nsa.gov>
+Date: Fri, 17 Nov 2017 08:09:52 -0500
+Subject: [PATCH 3/5] libsepol/cil: Create new keep field for type attribute
+ sets
+
+Daniel Cashman <dcashman@android.com> discovered the following:
+When using cil_db multiple_decls, the different cil_attribute nodes
+all point to the same underlying cil_attribute struct.  This leads
+to problems, though, when modifying the used value in the struct.
+__cil_post_db_attr() changes the value of the field to based on
+the output of cil_typeattribute_used(), for use later in
+cil_typeattribute_to_policydb and cil_typeattribute_to_bitmap, but
+due to the multiple declarations, cil_typeattribute_used() could be
+called again by a second node.  In this second call, the value used
+is the modifed value of CIL_TRUE or CIL_FALSE, not the flags actually
+needed. This could result in the field being reset again, to an
+incorrect CIL_FALSE value.
+
+Add the field "keep" to struct cil_typeattributeset, set its value
+using cil_typeattribute_used(), and use it when determining whether
+the attribute is to be kept or if it should be expanded.
+
+Signed-off-by: James Carter <jwcart2@tycho.nsa.gov>
+---
+ libsepol/cil/src/cil.c           | 1 +
+ libsepol/cil/src/cil_binary.c    | 8 ++++----
+ libsepol/cil/src/cil_internal.h  | 1 +
+ libsepol/cil/src/cil_policy.c    | 2 +-
+ libsepol/cil/src/cil_post.c      | 2 +-
+ libsepol/cil/src/cil_reset_ast.c | 1 +
+ 6 files changed, 9 insertions(+), 6 deletions(-)
+
+diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c
+index e8bbbfdf..a5a3e263 100644
+--- a/libsepol/cil/src/cil.c
++++ b/libsepol/cil/src/cil.c
+@@ -2038,6 +2038,7 @@ void cil_typeattribute_init(struct cil_typeattribute **attr)
+ 	(*attr)->expr_list = NULL;
+ 	(*attr)->types = NULL;
+ 	(*attr)->used = CIL_FALSE;
++	(*attr)->keep = CIL_FALSE;
+ }
+ 
+ void cil_typeattributeset_init(struct cil_typeattributeset **attrset)
+diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c
+index e1481a43..1818ffa9 100644
+--- a/libsepol/cil/src/cil_binary.c
++++ b/libsepol/cil/src/cil_binary.c
+@@ -567,7 +567,7 @@ int cil_typeattribute_to_policydb(policydb_t *pdb, struct cil_typeattribute *cil
+ 	char *key = NULL;
+ 	type_datum_t *sepol_attr = NULL;
+ 
+-	if (!cil_attr->used) {
++	if (!cil_attr->keep) {
+ 		return SEPOL_OK;		
+ 	}
+ 
+@@ -632,7 +632,7 @@ int cil_typeattribute_to_bitmap(policydb_t *pdb, const struct cil_db *db, struct
+ 	ebitmap_node_t *tnode;
+ 	unsigned int i;
+ 
+-	if (!cil_attr->used) {
++	if (!cil_attr->keep) {
+ 		return SEPOL_OK;
+ 	}
+ 
+@@ -1442,7 +1442,7 @@ static int __cil_should_expand_attribute( const struct cil_db *db, struct cil_sy
+ 
+ 	attr = (struct cil_typeattribute *)datum;
+ 
+-	return !attr->used || (ebitmap_cardinality(attr->types) < db->attrs_expand_size);
++	return !attr->keep || (ebitmap_cardinality(attr->types) < db->attrs_expand_size);
+ }
+ 
+ int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_avrule *cil_avrule, cond_node_t *cond_node, enum cil_flavor cond_flavor)
+@@ -2525,7 +2525,7 @@ int __cil_constrain_expr_datum_to_sepol_expr(policydb_t *pdb, const struct cil_d
+ 			if (rc != SEPOL_OK) {
+ 				if (FLAVOR(item->data) == CIL_TYPEATTRIBUTE) {
+ 					struct cil_typeattribute *attr = item->data;
+-					if (!attr->used) {
++					if (!attr->keep) {
+ 						rc = 0;
+ 					}
+ 				}
+diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h
+index abfacd8d..942b28f0 100644
+--- a/libsepol/cil/src/cil_internal.h
++++ b/libsepol/cil/src/cil_internal.h
+@@ -527,6 +527,7 @@ struct cil_typeattribute {
+ 	struct cil_list *expr_list;
+ 	ebitmap_t *types;
+ 	int used;	// whether or not this attribute was used in a binary policy rule
++	int keep;
+ };
+ 
+ struct cil_typeattributeset {
+diff --git a/libsepol/cil/src/cil_policy.c b/libsepol/cil/src/cil_policy.c
+index 77179e63..3e511330 100644
+--- a/libsepol/cil/src/cil_policy.c
++++ b/libsepol/cil/src/cil_policy.c
+@@ -1085,7 +1085,7 @@ static void cil_typeattributes_to_policy(FILE *out, struct cil_list *types, stru
+ 		type = i1->data;
+ 		cil_list_for_each(i2, attributes) {
+ 			attribute = i2->data;
+-			if (!attribute->used)
++			if (!attribute->keep)
+ 				continue;
+ 			if (ebitmap_get_bit(attribute->types, type->value)) {
+ 				if (first) {
+diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
+index 1941fab3..a30de0e1 100644
+--- a/libsepol/cil/src/cil_post.c
++++ b/libsepol/cil/src/cil_post.c
+@@ -1250,7 +1250,7 @@ static int __cil_post_db_attr_helper(struct cil_tree_node *node, uint32_t *finis
+ 			rc = __evaluate_type_expression(attr, db);
+ 			if (rc != SEPOL_OK) goto exit;
+ 		}
+-		attr->used = cil_typeattribute_used(attr, db);
++		attr->keep = cil_typeattribute_used(attr, db);
+ 		break;
+ 	}
+ 	case CIL_ROLEATTRIBUTE: {
+diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c
+index 676e156e..142179ee 100644
+--- a/libsepol/cil/src/cil_reset_ast.c
++++ b/libsepol/cil/src/cil_reset_ast.c
+@@ -186,6 +186,7 @@ static void cil_reset_typeattr(struct cil_typeattribute *attr)
+ 		attr->expr_list = NULL;
+ 	}
+ 	attr->used = CIL_FALSE;
++	attr->keep = CIL_FALSE;
+ }
+ 
+ static void cil_reset_typeattributeset(struct cil_typeattributeset *tas)
+-- 
+2.15.1
+
diff --git a/patches/platform_external_selinux/0004-Enable-multipl_decls-by-default.-This-is-needed-beca.patch b/patches/platform_external_selinux/0004-Enable-multipl_decls-by-default.-This-is-needed-beca.patch
new file mode 100644
index 0000000..edf02fa
--- /dev/null
+++ b/patches/platform_external_selinux/0004-Enable-multipl_decls-by-default.-This-is-needed-beca.patch
@@ -0,0 +1,27 @@
+From 6afcaac2da4ea0fad2e3aea4b579eddd02523e73 Mon Sep 17 00:00:00 2001
+From: Pierre-Hugues Husson <phh@phh.me>
+Date: Fri, 2 Mar 2018 22:49:55 +0100
+Subject: [PATCH 4/5] Enable multipl_decls by default. This is needed because
+ 8.0 init doesn't add -m
+
+Change-Id: I43dc661d519f7b8576d72a828d8cbd444592bf5e
+---
+ secilc/secilc.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/secilc/secilc.c b/secilc/secilc.c
+index 0be6975b..e30572e5 100644
+--- a/secilc/secilc.c
++++ b/secilc/secilc.c
+@@ -90,7 +90,7 @@ int main(int argc, char *argv[])
+ 	int target = SEPOL_TARGET_SELINUX;
+ 	int mls = -1;
+ 	int disable_dontaudit = 0;
+-	int multiple_decls = 0;
++	int multiple_decls = 1;
+ 	int disable_neverallow = 0;
+ 	int preserve_tunables = 0;
+ 	int handle_unknown = -1;
+-- 
+2.15.1
+
diff --git a/patches/platform_external_selinux/0005-Delete-identical-genfscon-s.patch b/patches/platform_external_selinux/0005-Delete-identical-genfscon-s.patch
new file mode 100644
index 0000000..bf664e1
--- /dev/null
+++ b/patches/platform_external_selinux/0005-Delete-identical-genfscon-s.patch
@@ -0,0 +1,42 @@
+From c334f823d0eccac2656ceceb707367680cca32f2 Mon Sep 17 00:00:00 2001
+From: Pierre-Hugues Husson <phh@phh.me>
+Date: Sat, 3 Mar 2018 19:02:29 +0100
+Subject: [PATCH 5/5] Delete identical genfscon-s
+
+Change-Id: I9775187b9da3568390ab66ebd59cb774b1283ad1
+---
+ libsepol/cil/src/cil_post.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c
+index a30de0e1..605847d1 100644
+--- a/libsepol/cil/src/cil_post.c
++++ b/libsepol/cil/src/cil_post.c
+@@ -53,6 +53,16 @@
+ static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max, struct cil_db *db);
+ static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t *out, int max, struct cil_db *db);
+ 
++static int compact(void* array, int count, int len, int (*compar)(const void *, const void *)) {
++	char *a = (char*)array;
++	int j = 0;
++	for(int i=1; i<count; i++) {
++		if(compar(a+i*len, a+j*len) != 0) j++;
++		if(i != j) memcpy(a+j*len, a+i*len, len);
++	}
++	return j;
++}
++
+ static int cil_verify_is_list(struct cil_list *list, enum cil_flavor flavor)
+ {
+ 	struct cil_list_item *curr;
+@@ -1977,6 +1987,7 @@ static int cil_post_db(struct cil_db *db)
+ 
+ 	qsort(db->netifcon->array, db->netifcon->count, sizeof(db->netifcon->array), cil_post_netifcon_compare);
+ 	qsort(db->genfscon->array, db->genfscon->count, sizeof(db->genfscon->array), cil_post_genfscon_compare);
++	db->genfscon->count = compact(db->genfscon->array, db->genfscon->count, sizeof(db->genfscon->array), cil_post_genfscon_compare);
+ 	qsort(db->portcon->array, db->portcon->count, sizeof(db->portcon->array), cil_post_portcon_compare);
+ 	qsort(db->nodecon->array, db->nodecon->count, sizeof(db->nodecon->array), cil_post_nodecon_compare);
+ 	qsort(db->fsuse->array, db->fsuse->count, sizeof(db->fsuse->array), cil_post_fsuse_compare);
+-- 
+2.15.1
+