#19 Disable symbol versioning and re-enable lto
Closed 3 years ago by plautrba. Opened 3 years ago by plautrba.
rpms/ plautrba/libsepol enable-lto-disable_symver  into  master

@@ -0,0 +1,592 @@ 

+ From 42ae834a7428c57f7b2a9f448adf4cf991fa3487 Mon Sep 17 00:00:00 2001

+ From: Ondrej Mosnacek <omosnace@redhat.com>

+ Date: Fri, 31 Jul 2020 13:10:34 +0200

+ Subject: [PATCH] libsepol,checkpolicy: optimize storage of filename

+  transitions

+ 

+ In preparation to support a new policy format with a more optimal

+ representation of filename transition rules, this patch applies an

+ equivalent change from kernel commit c3a276111ea2 ("selinux: optimize

+ storage of filename transitions").

+ 

+ See the kernel commit's description [1] for the rationale behind this

+ representation. This change doesn't bring any measurable difference of

+ policy build performance (semodule -B) on Fedora.

+ 

+ [1] https://git.kernel.org/pub/scm/linux/kernel/git/pcmoore/selinux.git/commit/?id=c3a276111ea2572399281988b3129683e2a6b60b

+ 

+ Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>

+ ---

+  libsepol/cil/src/cil_binary.c              |  26 ++---

+  libsepol/include/sepol/policydb/policydb.h |  15 ++-

+  libsepol/src/expand.c                      |  56 ++-------

+  libsepol/src/kernel_to_cil.c               |  24 +++-

+  libsepol/src/kernel_to_conf.c              |  24 +++-

+  libsepol/src/policydb.c                    | 125 +++++++++++++++------

+  libsepol/src/write.c                       |  46 ++++----

+  7 files changed, 183 insertions(+), 133 deletions(-)

+ 

+ diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c

+ index 62178d998468..7726685809af 100644

+ --- a/libsepol/cil/src/cil_binary.c

+ +++ b/libsepol/cil/src/cil_binary.c

+ @@ -1131,11 +1131,10 @@ int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, stru

+  	class_datum_t *sepol_obj = NULL;

+  	struct cil_list *class_list;

+  	type_datum_t *sepol_result = NULL;

+ -	filename_trans_t *newkey = NULL;

+ -	filename_trans_datum_t *newdatum = NULL, *otype = NULL;

+  	ebitmap_t src_bitmap, tgt_bitmap;

+  	ebitmap_node_t *node1, *node2;

+  	unsigned int i, j;

+ +	uint32_t otype;

+  	struct cil_list_item *c;

+  	char *name = DATUM(typetrans->name)->name;

+  

+ @@ -1176,22 +1175,14 @@ int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, stru

+  				rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj);

+  				if (rc != SEPOL_OK) goto exit;

+  

+ -				newkey = cil_calloc(1, sizeof(*newkey));

+ -				newdatum = cil_calloc(1, sizeof(*newdatum));

+ -				newkey->stype = sepol_src->s.value;

+ -				newkey->ttype = sepol_tgt->s.value;

+ -				newkey->tclass = sepol_obj->s.value;

+ -				newkey->name = cil_strdup(name);

+ -				newdatum->otype = sepol_result->s.value;

+ -

+ -				rc = hashtab_insert(pdb->filename_trans,

+ -						    (hashtab_key_t)newkey,

+ -						    newdatum);

+ +				rc = policydb_filetrans_insert(

+ +					pdb, sepol_src->s.value, sepol_tgt->s.value,

+ +					sepol_obj->s.value, name, NULL,

+ +					sepol_result->s.value, &otype

+ +				);

+  				if (rc != SEPOL_OK) {

+  					if (rc == SEPOL_EEXIST) {

+ -						otype = hashtab_search(pdb->filename_trans,

+ -								(hashtab_key_t)newkey);

+ -						if (newdatum->otype != otype->otype) {

+ +						if (sepol_result->s.value!= otype) {

+  							cil_log(CIL_ERR, "Conflicting name type transition rules\n");

+  						} else {

+  							rc = SEPOL_OK;

+ @@ -1199,9 +1190,6 @@ int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, stru

+  					} else {

+  						cil_log(CIL_ERR, "Out of memory\n");

+  					}

+ -					free(newkey->name);

+ -					free(newkey);

+ -					free(newdatum);

+  					if (rc != SEPOL_OK) {

+  						goto exit;

+  					}

+ diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h

+ index 81b63fefbb20..c3180c611c64 100644

+ --- a/libsepol/include/sepol/policydb/policydb.h

+ +++ b/libsepol/include/sepol/policydb/policydb.h

+ @@ -162,15 +162,16 @@ typedef struct role_allow {

+  } role_allow_t;

+  

+  /* filename_trans rules */

+ -typedef struct filename_trans {

+ -	uint32_t stype;

+ +typedef struct filename_trans_key {

+  	uint32_t ttype;

+  	uint32_t tclass;

+  	char *name;

+ -} filename_trans_t;

+ +} filename_trans_key_t;

+  

+  typedef struct filename_trans_datum {

+ -	uint32_t otype;		/* expected of new object */

+ +	ebitmap_t stypes;

+ +	uint32_t otype;

+ +	struct filename_trans_datum *next;

+  } filename_trans_datum_t;

+  

+  /* Type attributes */

+ @@ -591,6 +592,7 @@ typedef struct policydb {

+  

+  	/* file transitions with the last path component */

+  	hashtab_t filename_trans;

+ +	uint32_t filename_trans_count;

+  

+  	ebitmap_t *type_attr_map;

+  

+ @@ -650,6 +652,11 @@ extern int policydb_load_isids(policydb_t * p, sidtab_t * s);

+  

+  extern int policydb_sort_ocontexts(policydb_t *p);

+  

+ +extern int policydb_filetrans_insert(policydb_t *p, uint32_t stype,

+ +				     uint32_t ttype, uint32_t tclass,

+ +				     const char *name, char **name_alloc,

+ +				     uint32_t otype, uint32_t *present_otype);

+ +

+  /* Deprecated */

+  extern int policydb_context_isvalid(const policydb_t * p,

+  				    const context_struct_t * c);

+ diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c

+ index 529e1d356a89..19e48c507236 100644

+ --- a/libsepol/src/expand.c

+ +++ b/libsepol/src/expand.c

+ @@ -1371,8 +1371,6 @@ static int copy_role_trans(expand_state_t * state, role_trans_rule_t * rules)

+  static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *rules)

+  {

+  	unsigned int i, j;

+ -	filename_trans_t key, *new_trans;

+ -	filename_trans_datum_t *otype;

+  	filename_trans_rule_t *cur_rule;

+  	ebitmap_t stypes, ttypes;

+  	ebitmap_node_t *snode, *tnode;

+ @@ -1380,7 +1378,7 @@ static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *r

+  

+  	cur_rule = rules;

+  	while (cur_rule) {

+ -		uint32_t mapped_otype;

+ +		uint32_t mapped_otype, present_otype;

+  

+  		ebitmap_init(&stypes);

+  		ebitmap_init(&ttypes);

+ @@ -1401,15 +1399,14 @@ static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *r

+  

+  		ebitmap_for_each_positive_bit(&stypes, snode, i) {

+  			ebitmap_for_each_positive_bit(&ttypes, tnode, j) {

+ -				key.stype = i + 1;

+ -				key.ttype = j + 1;

+ -				key.tclass = cur_rule->tclass;

+ -				key.name = cur_rule->name;

+ -				otype = hashtab_search(state->out->filename_trans,

+ -						       (hashtab_key_t) &key);

+ -				if (otype) {

+ +				rc = policydb_filetrans_insert(

+ +					state->out, i + 1, j + 1,

+ +					cur_rule->tclass, cur_rule->name,

+ +					NULL, mapped_otype, &present_otype

+ +				);

+ +				if (rc == SEPOL_EEXIST) {

+  					/* duplicate rule, ignore */

+ -					if (otype->otype == mapped_otype)

+ +					if (present_otype == mapped_otype)

+  						continue;

+  

+  					ERR(state->handle, "Conflicting name-based type_transition %s %s:%s \"%s\":  %s vs %s",

+ @@ -1417,44 +1414,11 @@ static int expand_filename_trans(expand_state_t *state, filename_trans_rule_t *r

+  					    state->out->p_type_val_to_name[j],

+  					    state->out->p_class_val_to_name[cur_rule->tclass - 1],

+  					    cur_rule->name,

+ -					    state->out->p_type_val_to_name[otype->otype - 1],

+ +					    state->out->p_type_val_to_name[present_otype - 1],

+  					    state->out->p_type_val_to_name[mapped_otype - 1]);

+  					return -1;

+ -				}

+ -

+ -				new_trans = calloc(1, sizeof(*new_trans));

+ -				if (!new_trans) {

+ -					ERR(state->handle, "Out of memory!");

+ -					return -1;

+ -				}

+ -

+ -				new_trans->name = strdup(cur_rule->name);

+ -				if (!new_trans->name) {

+ -					ERR(state->handle, "Out of memory!");

+ -					free(new_trans);

+ -					return -1;

+ -				}

+ -				new_trans->stype = i + 1;

+ -				new_trans->ttype = j + 1;

+ -				new_trans->tclass = cur_rule->tclass;

+ -

+ -				otype = calloc(1, sizeof(*otype));

+ -				if (!otype) {

+ -					ERR(state->handle, "Out of memory!");

+ -					free(new_trans->name);

+ -					free(new_trans);

+ -					return -1;

+ -				}

+ -				otype->otype = mapped_otype;

+ -

+ -				rc = hashtab_insert(state->out->filename_trans,

+ -						    (hashtab_key_t)new_trans,

+ -						    otype);

+ -				if (rc) {

+ +				} else if (rc < 0) {

+  					ERR(state->handle, "Out of memory!");

+ -					free(otype);

+ -					free(new_trans->name);

+ -					free(new_trans);

+  					return -1;

+  				}

+  			}

+ diff --git a/libsepol/src/kernel_to_cil.c b/libsepol/src/kernel_to_cil.c

+ index 958adc4cfc0a..c247b32f9e75 100644

+ --- a/libsepol/src/kernel_to_cil.c

+ +++ b/libsepol/src/kernel_to_cil.c

+ @@ -1841,21 +1841,35 @@ struct map_filename_trans_args {

+  

+  static int map_filename_trans_to_str(hashtab_key_t key, void *data, void *arg)

+  {

+ -	filename_trans_t *ft = (filename_trans_t *)key;

+ +	filename_trans_key_t *ft = (filename_trans_key_t *)key;

+  	filename_trans_datum_t *datum = data;

+  	struct map_filename_trans_args *map_args = arg;

+  	struct policydb *pdb = map_args->pdb;

+  	struct strs *strs = map_args->strs;

+  	char *src, *tgt, *class, *filename, *new;

+ +	struct ebitmap_node *node;

+ +	uint32_t bit;

+ +	int rc;

+  

+ -	src = pdb->p_type_val_to_name[ft->stype - 1];

+  	tgt = pdb->p_type_val_to_name[ft->ttype - 1];

+  	class = pdb->p_class_val_to_name[ft->tclass - 1];

+  	filename = ft->name;

+ -	new =  pdb->p_type_val_to_name[datum->otype - 1];

+ +	do {

+ +		new = pdb->p_type_val_to_name[datum->otype - 1];

+ +

+ +		ebitmap_for_each_positive_bit(&datum->stypes, node, bit) {

+ +			src = pdb->p_type_val_to_name[bit];

+ +			rc = strs_create_and_add(strs,

+ +						 "(typetransition %s %s %s %s %s)",

+ +						 5, src, tgt, class, filename, new);

+ +			if (rc)

+ +				return rc;

+ +		}

+ +

+ +		datum = datum->next;

+ +	} while (datum);

+  

+ -	return strs_create_and_add(strs, "(typetransition %s %s %s %s %s)", 5,

+ -				   src, tgt, class, filename, new);

+ +	return 0;

+  }

+  

+  static int write_filename_trans_rules_to_cil(FILE *out, struct policydb *pdb)

+ diff --git a/libsepol/src/kernel_to_conf.c b/libsepol/src/kernel_to_conf.c

+ index 7cc91eb3d129..62bf706c1aa0 100644

+ --- a/libsepol/src/kernel_to_conf.c

+ +++ b/libsepol/src/kernel_to_conf.c

+ @@ -1822,21 +1822,35 @@ struct map_filename_trans_args {

+  

+  static int map_filename_trans_to_str(hashtab_key_t key, void *data, void *arg)

+  {

+ -	filename_trans_t *ft = (filename_trans_t *)key;

+ +	filename_trans_key_t *ft = (filename_trans_key_t *)key;

+  	filename_trans_datum_t *datum = data;

+  	struct map_filename_trans_args *map_args = arg;

+  	struct policydb *pdb = map_args->pdb;

+  	struct strs *strs = map_args->strs;

+  	char *src, *tgt, *class, *filename, *new;

+ +	struct ebitmap_node *node;

+ +	uint32_t bit;

+ +	int rc;

+  

+ -	src = pdb->p_type_val_to_name[ft->stype - 1];

+  	tgt = pdb->p_type_val_to_name[ft->ttype - 1];

+  	class = pdb->p_class_val_to_name[ft->tclass - 1];

+  	filename = ft->name;

+ -	new =  pdb->p_type_val_to_name[datum->otype - 1];

+ +	do {

+ +		new = pdb->p_type_val_to_name[datum->otype - 1];

+ +

+ +		ebitmap_for_each_positive_bit(&datum->stypes, node, bit) {

+ +			src = pdb->p_type_val_to_name[bit];

+ +			rc = strs_create_and_add(strs,

+ +						 "type_transition %s %s:%s %s \"%s\";",

+ +						 5, src, tgt, class, new, filename);

+ +			if (rc)

+ +				return rc;

+ +		}

+ +

+ +		datum = datum->next;

+ +	} while (datum);

+  

+ -	return strs_create_and_add(strs, "type_transition %s %s:%s %s \"%s\";", 5,

+ -				   src, tgt, class, new, filename);

+ +	return 0;

+  }

+  

+  static int write_filename_trans_rules_to_conf(FILE *out, struct policydb *pdb)

+ diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c

+ index 3992ea56f092..0b98d50b8096 100644

+ --- a/libsepol/src/policydb.c

+ +++ b/libsepol/src/policydb.c

+ @@ -789,12 +789,12 @@ partial_name_hash(unsigned long c, unsigned long prevhash)

+  

+  static unsigned int filenametr_hash(hashtab_t h, const_hashtab_key_t k)

+  {

+ -	const struct filename_trans *ft = (const struct filename_trans *)k;

+ +	const filename_trans_key_t *ft = (const filename_trans_key_t *)k;

+  	unsigned long hash;

+  	unsigned int byte_num;

+  	unsigned char focus;

+  

+ -	hash = ft->stype ^ ft->ttype ^ ft->tclass;

+ +	hash = ft->ttype ^ ft->tclass;

+  

+  	byte_num = 0;

+  	while ((focus = ft->name[byte_num++]))

+ @@ -805,14 +805,10 @@ static unsigned int filenametr_hash(hashtab_t h, const_hashtab_key_t k)

+  static int filenametr_cmp(hashtab_t h __attribute__ ((unused)),

+  			  const_hashtab_key_t k1, const_hashtab_key_t k2)

+  {

+ -	const struct filename_trans *ft1 = (const struct filename_trans *)k1;

+ -	const struct filename_trans *ft2 = (const struct filename_trans *)k2;

+ +	const filename_trans_key_t *ft1 = (const filename_trans_key_t *)k1;

+ +	const filename_trans_key_t *ft2 = (const filename_trans_key_t *)k2;

+  	int v;

+  

+ -	v = ft1->stype - ft2->stype;

+ -	if (v)

+ -		return v;

+ -

+  	v = ft1->ttype - ft2->ttype;

+  	if (v)

+  		return v;

+ @@ -1409,9 +1405,12 @@ common_destroy, class_destroy, role_destroy, type_destroy, user_destroy,

+  static int filenametr_destroy(hashtab_key_t key, hashtab_datum_t datum,

+  			      void *p __attribute__ ((unused)))

+  {

+ -	struct filename_trans *ft = (struct filename_trans *)key;

+ +	filename_trans_key_t *ft = (filename_trans_key_t *)key;

+ +	filename_trans_datum_t *fd = datum;

+ +

+  	free(ft->name);

+  	free(key);

+ +	ebitmap_destroy(&fd->stypes);

+  	free(datum);

+  	return 0;

+  }

+ @@ -2595,12 +2594,85 @@ int role_allow_read(role_allow_t ** r, struct policy_file *fp)

+  	return 0;

+  }

+  

+ +int policydb_filetrans_insert(policydb_t *p, uint32_t stype, uint32_t ttype,

+ +			      uint32_t tclass, const char *name,

+ +			      char **name_alloc, uint32_t otype,

+ +			      uint32_t *present_otype)

+ +{

+ +	filename_trans_key_t *ft, key;

+ +	filename_trans_datum_t *datum, *last;

+ +

+ +	key.ttype = ttype;

+ +	key.tclass = tclass;

+ +	key.name = (char *)name;

+ +

+ +	last = NULL;

+ +	datum = hashtab_search(p->filename_trans, (hashtab_key_t)&key);

+ +	while (datum) {

+ +		if (ebitmap_get_bit(&datum->stypes, stype - 1)) {

+ +			if (present_otype)

+ +				*present_otype = datum->otype;

+ +			return SEPOL_EEXIST;

+ +		}

+ +		if (datum->otype == otype)

+ +			break;

+ +		last = datum;

+ +		datum = datum->next;

+ +	}

+ +	if (!datum) {

+ +		datum = malloc(sizeof(*datum));

+ +		if (!datum)

+ +			return SEPOL_ENOMEM;

+ +

+ +		ebitmap_init(&datum->stypes);

+ +		datum->otype = otype;

+ +		datum->next = NULL;

+ +

+ +		if (last) {

+ +			last->next = datum;

+ +		} else {

+ +			char *name_dup;

+ +

+ +			if (name_alloc) {

+ +				name_dup = *name_alloc;

+ +				*name_alloc = NULL;

+ +			} else {

+ +				name_dup = strdup(name);

+ +				if (!name_dup) {

+ +					free(datum);

+ +					return SEPOL_ENOMEM;

+ +				}

+ +			}

+ +

+ +			ft = malloc(sizeof(*ft));

+ +			if (!ft) {

+ +				free(name_dup);

+ +				free(datum);

+ +				return SEPOL_ENOMEM;

+ +			}

+ +

+ +			ft->ttype = ttype;

+ +			ft->tclass = tclass;

+ +			ft->name = name_dup;

+ +

+ +			if (hashtab_insert(p->filename_trans, (hashtab_key_t)ft,

+ +					   (hashtab_datum_t)datum)) {

+ +				free(name_dup);

+ +				free(datum);

+ +				free(ft);

+ +				return SEPOL_ENOMEM;

+ +			}

+ +		}

+ +	}

+ +

+ +	p->filename_trans_count++;

+ +	return ebitmap_set_bit(&datum->stypes, stype - 1, 1);

+ +}

+ +

+  int filename_trans_read(policydb_t *p, struct policy_file *fp)

+  {

+  	unsigned int i;

+ -	uint32_t buf[4], nel, len;

+ -	filename_trans_t *ft;

+ -	filename_trans_datum_t *otype;

+ +	uint32_t buf[4], nel, len, stype, ttype, tclass, otype;

+  	int rc;

+  	char *name;

+  

+ @@ -2610,16 +2682,8 @@ int filename_trans_read(policydb_t *p, struct policy_file *fp)

+  	nel = le32_to_cpu(buf[0]);

+  

+  	for (i = 0; i < nel; i++) {

+ -		ft = NULL;

+ -		otype = NULL;

+  		name = NULL;

+  

+ -		ft = calloc(1, sizeof(*ft));

+ -		if (!ft)

+ -			goto err;

+ -		otype = calloc(1, sizeof(*otype));

+ -		if (!otype)

+ -			goto err;

+  		rc = next_entry(buf, fp, sizeof(uint32_t));

+  		if (rc < 0)

+  			goto err;

+ @@ -2631,8 +2695,6 @@ int filename_trans_read(policydb_t *p, struct policy_file *fp)

+  		if (!name)

+  			goto err;

+  

+ -		ft->name = name;

+ -

+  		rc = next_entry(name, fp, len);

+  		if (rc < 0)

+  			goto err;

+ @@ -2641,13 +2703,13 @@ int filename_trans_read(policydb_t *p, struct policy_file *fp)

+  		if (rc < 0)

+  			goto err;

+  

+ -		ft->stype = le32_to_cpu(buf[0]);

+ -		ft->ttype = le32_to_cpu(buf[1]);

+ -		ft->tclass = le32_to_cpu(buf[2]);

+ -		otype->otype = le32_to_cpu(buf[3]);

+ +		stype  = le32_to_cpu(buf[0]);

+ +		ttype  = le32_to_cpu(buf[1]);

+ +		tclass = le32_to_cpu(buf[2]);

+ +		otype  = le32_to_cpu(buf[3]);

+  

+ -		rc = hashtab_insert(p->filename_trans, (hashtab_key_t) ft,

+ -				    otype);

+ +		rc = policydb_filetrans_insert(p, stype, ttype, tclass, name,

+ +					       &name, otype, NULL);

+  		if (rc) {

+  			if (rc != SEPOL_EEXIST)

+  				goto err;

+ @@ -2657,16 +2719,11 @@ int filename_trans_read(policydb_t *p, struct policy_file *fp)

+  			 * compatibility, do not reject such policies, just

+  			 * ignore the duplicate.

+  			 */

+ -			free(ft);

+ -			free(name);

+ -			free(otype);

+ -			/* continue, ignoring this one */

+  		}

+ +		free(name);

+  	}

+  	return 0;

+  err:

+ -	free(ft);

+ -	free(otype);

+  	free(name);

+  	return -1;

+  }

+ diff --git a/libsepol/src/write.c b/libsepol/src/write.c

+ index 1fd6a16a248b..d3aee8d5bf22 100644

+ --- a/libsepol/src/write.c

+ +++ b/libsepol/src/write.c

+ @@ -571,44 +571,50 @@ static int role_allow_write(role_allow_t * r, struct policy_file *fp)

+  

+  static int filename_write_helper(hashtab_key_t key, void *data, void *ptr)

+  {

+ -	uint32_t buf[4];

+ +	uint32_t bit, buf[4];

+  	size_t items, len;

+ -	struct filename_trans *ft = (struct filename_trans *)key;

+ -	struct filename_trans_datum *otype = data;

+ +	filename_trans_key_t *ft = (filename_trans_key_t *)key;

+ +	filename_trans_datum_t *datum = data;

+ +	ebitmap_node_t *node;

+  	void *fp = ptr;

+  

+  	len = strlen(ft->name);

+ -	buf[0] = cpu_to_le32(len);

+ -	items = put_entry(buf, sizeof(uint32_t), 1, fp);

+ -	if (items != 1)

+ -		return POLICYDB_ERROR;

+ +	do {

+ +		ebitmap_for_each_positive_bit(&datum->stypes, node, bit) {

+ +			buf[0] = cpu_to_le32(len);

+ +			items = put_entry(buf, sizeof(uint32_t), 1, fp);

+ +			if (items != 1)

+ +				return POLICYDB_ERROR;

+  

+ -	items = put_entry(ft->name, sizeof(char), len, fp);

+ -	if (items != len)

+ -		return POLICYDB_ERROR;

+ +			items = put_entry(ft->name, sizeof(char), len, fp);

+ +			if (items != len)

+ +				return POLICYDB_ERROR;

+  

+ -	buf[0] = cpu_to_le32(ft->stype);

+ -	buf[1] = cpu_to_le32(ft->ttype);

+ -	buf[2] = cpu_to_le32(ft->tclass);

+ -	buf[3] = cpu_to_le32(otype->otype);

+ -	items = put_entry(buf, sizeof(uint32_t), 4, fp);

+ -	if (items != 4)

+ -		return POLICYDB_ERROR;

+ +			buf[0] = cpu_to_le32(bit + 1);

+ +			buf[1] = cpu_to_le32(ft->ttype);

+ +			buf[2] = cpu_to_le32(ft->tclass);

+ +			buf[3] = cpu_to_le32(datum->otype);

+ +			items = put_entry(buf, sizeof(uint32_t), 4, fp);

+ +			if (items != 4)

+ +				return POLICYDB_ERROR;

+ +		}

+ +

+ +		datum = datum->next;

+ +	} while (datum);

+  

+  	return 0;

+  }

+  

+  static int filename_trans_write(struct policydb *p, void *fp)

+  {

+ -	size_t nel, items;

+ +	size_t items;

+  	uint32_t buf[1];

+  	int rc;

+  

+  	if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)

+  		return 0;

+  

+ -	nel =  p->filename_trans->nel;

+ -	buf[0] = cpu_to_le32(nel);

+ +	buf[0] = cpu_to_le32(p->filename_trans_count);

+  	items = put_entry(buf, sizeof(uint32_t), 1, fp);

+  	if (items != 1)

+  		return POLICYDB_ERROR;

+ -- 

+ 2.29.0.rc2

+ 

@@ -0,0 +1,394 @@ 

+ From 8206b8cb00392aab358f4eeae38f98850438085c Mon Sep 17 00:00:00 2001

+ From: Ondrej Mosnacek <omosnace@redhat.com>

+ Date: Fri, 31 Jul 2020 13:10:35 +0200

+ Subject: [PATCH] libsepol: implement POLICYDB_VERSION_COMP_FTRANS

+ 

+ Implement a new, more space-efficient form of storing filename

+ transitions in the binary policy. The internal structures have already

+ been converted to this new representation; this patch just implements

+ reading/writing an equivalent representation from/to the binary policy.

+ 

+ This new format reduces the size of Fedora policy from 7.6 MB to only

+ 3.3 MB (with policy optimization enabled in both cases). With the

+ unconfined module disabled, the size is reduced from 3.3 MB to 2.4 MB.

+ 

+ Signed-off-by: Ondrej Mosnacek <omosnace@redhat.com>

+ ---

+  libsepol/include/sepol/policydb/policydb.h |   3 +-

+  libsepol/src/policydb.c                    | 209 +++++++++++++++++----

+  libsepol/src/write.c                       |  73 ++++++-

+  3 files changed, 242 insertions(+), 43 deletions(-)

+ 

+ diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h

+ index c3180c611c64..9ef43abc2f12 100644

+ --- a/libsepol/include/sepol/policydb/policydb.h

+ +++ b/libsepol/include/sepol/policydb/policydb.h

+ @@ -755,10 +755,11 @@ extern int policydb_set_target_platform(policydb_t *p, int platform);

+  #define POLICYDB_VERSION_XPERMS_IOCTL	30 /* Linux-specific */

+  #define POLICYDB_VERSION_INFINIBAND		31 /* Linux-specific */

+  #define POLICYDB_VERSION_GLBLUB		32

+ +#define POLICYDB_VERSION_COMP_FTRANS	33 /* compressed filename transitions */

+  

+  /* Range of policy versions we understand*/

+  #define POLICYDB_VERSION_MIN	POLICYDB_VERSION_BASE

+ -#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_GLBLUB

+ +#define POLICYDB_VERSION_MAX	POLICYDB_VERSION_COMP_FTRANS

+  

+  /* Module versions and specific changes*/

+  #define MOD_POLICYDB_VERSION_BASE		4

+ diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c

+ index 0b98d50b8096..ce8f3ad77005 100644

+ --- a/libsepol/src/policydb.c

+ +++ b/libsepol/src/policydb.c

+ @@ -200,6 +200,13 @@ static struct policydb_compat_info policydb_compat[] = {

+  	 .ocon_num = OCON_IBENDPORT + 1,

+  	 .target_platform = SEPOL_TARGET_SELINUX,

+  	},

+ +	{

+ +	 .type = POLICY_KERN,

+ +	 .version = POLICYDB_VERSION_COMP_FTRANS,

+ +	 .sym_num = SYM_NUM,

+ +	 .ocon_num = OCON_IBENDPORT + 1,

+ +	 .target_platform = SEPOL_TARGET_SELINUX,

+ +	},

+  	{

+  	 .type = POLICY_BASE,

+  	 .version = MOD_POLICYDB_VERSION_BASE,

+ @@ -2669,65 +2676,201 @@ int policydb_filetrans_insert(policydb_t *p, uint32_t stype, uint32_t ttype,

+  	return ebitmap_set_bit(&datum->stypes, stype - 1, 1);

+  }

+  

+ -int filename_trans_read(policydb_t *p, struct policy_file *fp)

+ +static int filename_trans_read_one_compat(policydb_t *p, struct policy_file *fp)

+  {

+ -	unsigned int i;

+ -	uint32_t buf[4], nel, len, stype, ttype, tclass, otype;

+ +	uint32_t buf[4], len, stype, ttype, tclass, otype;

+ +	char *name = NULL;

+  	int rc;

+ -	char *name;

+  

+  	rc = next_entry(buf, fp, sizeof(uint32_t));

+  	if (rc < 0)

+  		return -1;

+ -	nel = le32_to_cpu(buf[0]);

+ +	len = le32_to_cpu(buf[0]);

+ +	if (zero_or_saturated(len))

+ +		return -1;

+  

+ -	for (i = 0; i < nel; i++) {

+ -		name = NULL;

+ +	name = calloc(len + 1, sizeof(*name));

+ +	if (!name)

+ +		return -1;

+  

+ -		rc = next_entry(buf, fp, sizeof(uint32_t));

+ -		if (rc < 0)

+ -			goto err;

+ -		len = le32_to_cpu(buf[0]);

+ -		if (zero_or_saturated(len))

+ +	rc = next_entry(name, fp, len);

+ +	if (rc < 0)

+ +		goto err;

+ +

+ +	rc = next_entry(buf, fp, sizeof(uint32_t) * 4);

+ +	if (rc < 0)

+ +		goto err;

+ +

+ +	stype  = le32_to_cpu(buf[0]);

+ +	ttype  = le32_to_cpu(buf[1]);

+ +	tclass = le32_to_cpu(buf[2]);

+ +	otype  = le32_to_cpu(buf[3]);

+ +

+ +	rc = policydb_filetrans_insert(p, stype, ttype, tclass, name, &name,

+ +				       otype, NULL);

+ +	if (rc) {

+ +		if (rc != SEPOL_EEXIST)

+  			goto err;

+ +		/*

+ +		 * Some old policies were wrongly generated with

+ +		 * duplicate filename transition rules.  For backward

+ +		 * compatibility, do not reject such policies, just

+ +		 * ignore the duplicate.

+ +		 */

+ +	}

+ +	free(name);

+ +	return 0;

+ +err:

+ +	free(name);

+ +	return -1;

+ +}

+ +

+ +static int filename_trans_check_datum(filename_trans_datum_t *datum)

+ +{

+ +	ebitmap_t stypes, otypes;

+ +	int rc = -1;

+ +

+ +	ebitmap_init(&stypes);

+ +	ebitmap_init(&otypes);

+ +

+ +	while (datum) {

+ +		if (ebitmap_get_bit(&otypes, datum->otype))

+ +			goto out;

+ +

+ +		if (ebitmap_set_bit(&otypes, datum->otype, 1))

+ +			goto out;

+ +

+ +		if (ebitmap_match_any(&stypes, &datum->stypes))

+ +			goto out;

+  

+ -		name = calloc(len + 1, sizeof(*name));

+ -		if (!name)

+ +		if (ebitmap_union(&stypes, &datum->stypes))

+ +			goto out;

+ +

+ +		datum = datum->next;

+ +	}

+ +	rc = 0;

+ +out:

+ +	ebitmap_destroy(&stypes);

+ +	ebitmap_destroy(&otypes);

+ +	return rc;

+ +}

+ +

+ +static int filename_trans_read_one(policydb_t *p, struct policy_file *fp)

+ +{

+ +	filename_trans_key_t *ft = NULL;

+ +	filename_trans_datum_t **dst, *datum, *first = NULL;

+ +	unsigned int i;

+ +	uint32_t buf[3], len, ttype, tclass, ndatum;

+ +	char *name = NULL;

+ +	int rc;

+ +

+ +	rc = next_entry(buf, fp, sizeof(uint32_t));

+ +	if (rc < 0)

+ +		return -1;

+ +	len = le32_to_cpu(buf[0]);

+ +	if (zero_or_saturated(len))

+ +		return -1;

+ +

+ +	name = calloc(len + 1, sizeof(*name));

+ +	if (!name)

+ +		return -1;

+ +

+ +	rc = next_entry(name, fp, len);

+ +	if (rc < 0)

+ +		goto err;

+ +

+ +	rc = next_entry(buf, fp, sizeof(uint32_t) * 3);

+ +	if (rc < 0)

+ +		goto err;

+ +

+ +	ttype = le32_to_cpu(buf[0]);

+ +	tclass = le32_to_cpu(buf[1]);

+ +	ndatum = le32_to_cpu(buf[2]);

+ +	if (ndatum == 0)

+ +		goto err;

+ +

+ +	dst = &first;

+ +	for (i = 0; i < ndatum; i++) {

+ +		datum = malloc(sizeof(*datum));

+ +		if (!datum)

+  			goto err;

+  

+ -		rc = next_entry(name, fp, len);

+ +		*dst = datum;

+ +

+ +		/* ebitmap_read() will at least init the bitmap */

+ +		rc = ebitmap_read(&datum->stypes, fp);

+  		if (rc < 0)

+  			goto err;

+  

+ -		rc = next_entry(buf, fp, sizeof(uint32_t) * 4);

+ +		rc = next_entry(buf, fp, sizeof(uint32_t));

+  		if (rc < 0)

+  			goto err;

+  

+ -		stype  = le32_to_cpu(buf[0]);

+ -		ttype  = le32_to_cpu(buf[1]);

+ -		tclass = le32_to_cpu(buf[2]);

+ -		otype  = le32_to_cpu(buf[3]);

+ +		datum->otype = le32_to_cpu(buf[0]);

+  

+ -		rc = policydb_filetrans_insert(p, stype, ttype, tclass, name,

+ -					       &name, otype, NULL);

+ -		if (rc) {

+ -			if (rc != SEPOL_EEXIST)

+ -				goto err;

+ -			/*

+ -			 * Some old policies were wrongly generated with

+ -			 * duplicate filename transition rules.  For backward

+ -			 * compatibility, do not reject such policies, just

+ -			 * ignore the duplicate.

+ -			 */

+ -		}

+ -		free(name);

+ +		p->filename_trans_count += ebitmap_cardinality(&datum->stypes);

+ +

+ +		dst = &datum->next;

+  	}

+ +	*dst = NULL;

+ +

+ +	if (ndatum > 1 && filename_trans_check_datum(first))

+ +		goto err;

+ +

+ +	ft = malloc(sizeof(*ft));

+ +	if (!ft)

+ +		goto err;

+ +

+ +	ft->ttype = ttype;

+ +	ft->tclass = tclass;

+ +	ft->name = name;

+ +

+ +	rc = hashtab_insert(p->filename_trans, (hashtab_key_t)ft,

+ +			    (hashtab_datum_t)first);

+ +	if (rc)

+ +		goto err;

+ +

+  	return 0;

+  err:

+ +	free(ft);

+  	free(name);

+ +	while (first) {

+ +		datum = first;

+ +		first = first->next;

+ +

+ +		ebitmap_destroy(&datum->stypes);

+ +		free(datum);

+ +	}

+  	return -1;

+  }

+  

+ +int filename_trans_read(policydb_t *p, struct policy_file *fp)

+ +{

+ +	unsigned int i;

+ +	uint32_t buf[1], nel;

+ +	int rc;

+ +

+ +	rc = next_entry(buf, fp, sizeof(uint32_t));

+ +	if (rc < 0)

+ +		return -1;

+ +	nel = le32_to_cpu(buf[0]);

+ +

+ +	if (p->policyvers < POLICYDB_VERSION_COMP_FTRANS) {

+ +		for (i = 0; i < nel; i++) {

+ +			rc = filename_trans_read_one_compat(p, fp);

+ +			if (rc < 0)

+ +				return -1;

+ +		}

+ +	} else {

+ +		for (i = 0; i < nel; i++) {

+ +			rc = filename_trans_read_one(p, fp);

+ +			if (rc < 0)

+ +				return -1;

+ +		}

+ +	}

+ +	return 0;

+ +}

+ +

+  static int ocontext_read_xen(struct policydb_compat_info *info,

+  	policydb_t *p, struct policy_file *fp)

+  {

+ diff --git a/libsepol/src/write.c b/libsepol/src/write.c

+ index d3aee8d5bf22..84bcaf3f57ca 100644

+ --- a/libsepol/src/write.c

+ +++ b/libsepol/src/write.c

+ @@ -569,7 +569,7 @@ static int role_allow_write(role_allow_t * r, struct policy_file *fp)

+  	return POLICYDB_SUCCESS;

+  }

+  

+ -static int filename_write_helper(hashtab_key_t key, void *data, void *ptr)

+ +static int filename_write_one_compat(hashtab_key_t key, void *data, void *ptr)

+  {

+  	uint32_t bit, buf[4];

+  	size_t items, len;

+ @@ -605,6 +605,54 @@ static int filename_write_helper(hashtab_key_t key, void *data, void *ptr)

+  	return 0;

+  }

+  

+ +static int filename_write_one(hashtab_key_t key, void *data, void *ptr)

+ +{

+ +	uint32_t buf[3];

+ +	size_t items, len, ndatum;

+ +	filename_trans_key_t *ft = (filename_trans_key_t *)key;

+ +	filename_trans_datum_t *datum;

+ +	void *fp = ptr;

+ +

+ +	len = strlen(ft->name);

+ +	buf[0] = cpu_to_le32(len);

+ +	items = put_entry(buf, sizeof(uint32_t), 1, fp);

+ +	if (items != 1)

+ +		return POLICYDB_ERROR;

+ +

+ +	items = put_entry(ft->name, sizeof(char), len, fp);

+ +	if (items != len)

+ +		return POLICYDB_ERROR;

+ +

+ +	ndatum = 0;

+ +	datum = data;

+ +	do {

+ +		ndatum++;

+ +		datum = datum->next;

+ +	} while (datum);

+ +

+ +	buf[0] = cpu_to_le32(ft->ttype);

+ +	buf[1] = cpu_to_le32(ft->tclass);

+ +	buf[2] = cpu_to_le32(ndatum);

+ +	items = put_entry(buf, sizeof(uint32_t), 3, fp);

+ +	if (items != 3)

+ +		return POLICYDB_ERROR;

+ +

+ +	datum = data;

+ +	do {

+ +		if (ebitmap_write(&datum->stypes, fp))

+ +			return POLICYDB_ERROR;

+ +

+ +		buf[0] = cpu_to_le32(datum->otype);

+ +		items = put_entry(buf, sizeof(uint32_t), 1, fp);

+ +		if (items != 1)

+ +			return POLICYDB_ERROR;

+ +

+ +		datum = datum->next;

+ +	} while (datum);

+ +

+ +	return 0;

+ +}

+ +

+  static int filename_trans_write(struct policydb *p, void *fp)

+  {

+  	size_t items;

+ @@ -614,16 +662,23 @@ static int filename_trans_write(struct policydb *p, void *fp)

+  	if (p->policyvers < POLICYDB_VERSION_FILENAME_TRANS)

+  		return 0;

+  

+ -	buf[0] = cpu_to_le32(p->filename_trans_count);

+ -	items = put_entry(buf, sizeof(uint32_t), 1, fp);

+ -	if (items != 1)

+ -		return POLICYDB_ERROR;

+ +	if (p->policyvers < POLICYDB_VERSION_COMP_FTRANS) {

+ +		buf[0] = cpu_to_le32(p->filename_trans_count);

+ +		items = put_entry(buf, sizeof(uint32_t), 1, fp);

+ +		if (items != 1)

+ +			return POLICYDB_ERROR;

+  

+ -	rc = hashtab_map(p->filename_trans, filename_write_helper, fp);

+ -	if (rc)

+ -		return rc;

+ +		rc = hashtab_map(p->filename_trans, filename_write_one_compat,

+ +				 fp);

+ +	} else {

+ +		buf[0] = cpu_to_le32(p->filename_trans->nel);

+ +		items = put_entry(buf, sizeof(uint32_t), 1, fp);

+ +		if (items != 1)

+ +			return POLICYDB_ERROR;

+  

+ -	return 0;

+ +		rc = hashtab_map(p->filename_trans, filename_write_one, fp);

+ +	}

+ +	return rc;

+  }

+  

+  static int role_set_write(role_set_t * x, struct policy_file *fp)

+ -- 

+ 2.29.0.rc2

+ 

@@ -0,0 +1,172 @@ 

+ From 685f577aa01ed378374cde9c0105b19c18ca7c07 Mon Sep 17 00:00:00 2001

+ From: James Carter <jwcart2@gmail.com>

+ Date: Wed, 9 Sep 2020 16:57:12 -0400

+ Subject: [PATCH] libsepol/cil: Validate constraint expressions before adding

+  to binary policy

+ 

+ CIL was not correctly determining the depth of constraint expressions

+ which prevented it from giving an error when the max depth was exceeded.

+ This allowed invalid policy binaries with constraint expressions exceeding

+ the max depth to be created.

+ 

+ Validate the constraint expression using the same logic that is used

+ when reading the binary policy. This includes checking the depth of the

+ the expression.

+ 

+ Reported-by: Jonathan Hettwer <j2468h@gmail.com>

+ Signed-off-by: James Carter <jwcart2@gmail.com>

+ Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>

+ ---

+  libsepol/cil/src/cil_binary.c    | 48 ++++++++++++++++++++++++++++++++

+  libsepol/cil/src/cil_build_ast.c | 20 ++++---------

+  2 files changed, 53 insertions(+), 15 deletions(-)

+ 

+ diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c

+ index 7726685809af..c8e41f09e53f 100644

+ --- a/libsepol/cil/src/cil_binary.c

+ +++ b/libsepol/cil/src/cil_binary.c

+ @@ -2713,6 +2713,49 @@ int __cil_constrain_expr_to_sepol_expr(policydb_t *pdb, const struct cil_db *db,

+  	return SEPOL_OK;

+  }

+  

+ +int __cil_validate_constrain_expr(constraint_expr_t *sepol_expr)

+ +{

+ +	constraint_expr_t *e;

+ +	int depth = -1;

+ +

+ +	for (e = sepol_expr; e != NULL; e = e->next) {

+ +		switch (e->expr_type) {

+ +		case CEXPR_NOT:

+ +			if (depth < 0) {

+ +				cil_log(CIL_ERR,"Invalid constraint expression\n");

+ +				return SEPOL_ERR;

+ +			}

+ +			break;

+ +		case CEXPR_AND:

+ +		case CEXPR_OR:

+ +			if (depth < 1) {

+ +				cil_log(CIL_ERR,"Invalid constraint expression\n");

+ +				return SEPOL_ERR;

+ +			}

+ +			depth--;

+ +			break;

+ +		case CEXPR_ATTR:

+ +		case CEXPR_NAMES:

+ +			if (depth == (CEXPR_MAXDEPTH - 1)) {

+ +				cil_log(CIL_ERR,"Constraint expression exceeded max allowable depth\n");

+ +				return SEPOL_ERR;

+ +			}

+ +			depth++;

+ +			break;

+ +		default:

+ +			cil_log(CIL_ERR,"Invalid constraint expression\n");

+ +			return SEPOL_ERR;

+ +		}

+ +	}

+ +

+ +	if (depth != 0) {

+ +		cil_log(CIL_ERR,"Invalid constraint expression\n");

+ +		return SEPOL_ERR;

+ +	}

+ +

+ +	return SEPOL_OK;

+ +}

+ +

+  int cil_constrain_to_policydb_helper(policydb_t *pdb, const struct cil_db *db, struct cil_symtab_datum *class, struct cil_list *perms, struct cil_list *expr)

+  {

+  	int rc = SEPOL_ERR;

+ @@ -2736,6 +2779,11 @@ int cil_constrain_to_policydb_helper(policydb_t *pdb, const struct cil_db *db, s

+  		goto exit;

+  	}

+  

+ +	rc = __cil_validate_constrain_expr(sepol_expr);

+ +	if (rc != SEPOL_OK) {

+ +		goto exit;

+ +	}

+ +

+  	sepol_constrain->expr = sepol_expr;

+  	sepol_constrain->next = sepol_class->constraints;

+  	sepol_class->constraints = sepol_constrain;

+ diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c

+ index 60ecaaff3060..870c6923b4de 100644

+ --- a/libsepol/cil/src/cil_build_ast.c

+ +++ b/libsepol/cil/src/cil_build_ast.c

+ @@ -2738,7 +2738,7 @@ exit:

+  	return SEPOL_ERR;

+  }

+  

+ -static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr, int *depth)

+ +static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr)

+  {

+  	int rc = SEPOL_ERR;

+  	enum cil_flavor op;

+ @@ -2750,12 +2750,6 @@ static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_fl

+  		goto exit;

+  	}

+  

+ -	if (*depth > CEXPR_MAXDEPTH) {

+ -		cil_log(CIL_ERR, "Max depth of %d exceeded for constraint expression\n", CEXPR_MAXDEPTH);

+ -		rc = SEPOL_ERR;

+ -		goto exit;

+ -	}

+ -

+  	op = __cil_get_constraint_operator_flavor(current->data);

+  

+  	rc = cil_verify_constraint_expr_syntax(current, op);

+ @@ -2769,14 +2763,13 @@ static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_fl

+  	case CIL_CONS_DOM:

+  	case CIL_CONS_DOMBY:

+  	case CIL_CONS_INCOMP:

+ -		(*depth)++;

+  		rc = __cil_fill_constraint_leaf_expr(current, flavor, op, expr);

+  		if (rc != SEPOL_OK) {

+  			goto exit;

+  		}

+  		break;

+  	case CIL_NOT:

+ -		rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr, depth);

+ +		rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr);

+  		if (rc != SEPOL_OK) {

+  			goto exit;

+  		}

+ @@ -2785,11 +2778,11 @@ static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_fl

+  		cil_list_append(*expr, CIL_LIST, lexpr);

+  		break;

+  	default:

+ -		rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr, depth);

+ +		rc = __cil_fill_constraint_expr(current->next->cl_head, flavor, &lexpr);

+  		if (rc != SEPOL_OK) {

+  			goto exit;

+  		}

+ -		rc = __cil_fill_constraint_expr(current->next->next->cl_head, flavor, &rexpr, depth);

+ +		rc = __cil_fill_constraint_expr(current->next->next->cl_head, flavor, &rexpr);

+  		if (rc != SEPOL_OK) {

+  			cil_list_destroy(&lexpr, CIL_TRUE);

+  			goto exit;

+ @@ -2801,8 +2794,6 @@ static int __cil_fill_constraint_expr(struct cil_tree_node *current, enum cil_fl

+  		break;

+  	}

+  

+ -	(*depth)--;

+ -

+  	return SEPOL_OK;

+  exit:

+  

+ @@ -2812,13 +2803,12 @@ exit:

+  int cil_gen_constraint_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr)

+  {

+  	int rc = SEPOL_ERR;

+ -	int depth = 0;

+  

+  	if (current->cl_head == NULL) {

+  		goto exit;

+  	}

+  

+ -	rc = __cil_fill_constraint_expr(current->cl_head, flavor, expr, &depth);

+ +	rc = __cil_fill_constraint_expr(current->cl_head, flavor, expr);

+  	if (rc != SEPOL_OK) {

+  		goto exit;

+  	}

+ -- 

+ 2.29.0.rc2

+ 

@@ -0,0 +1,172 @@ 

+ From 734e4beb55cb53d3370201838caa4850b2a6d276 Mon Sep 17 00:00:00 2001

+ From: James Carter <jwcart2@gmail.com>

+ Date: Wed, 9 Sep 2020 16:57:02 -0400

+ Subject: [PATCH] libsepol/cil: Validate conditional expressions before adding

+  to binary policy

+ 

+ CIL was not correctly determining the depth of conditional expressions

+ which prevented it from giving an error when the max depth was exceeded.

+ This allowed invalid policy binaries to be created.

+ 

+ Validate the conditional expression using the same logic that is used

+ when evaluating a conditional expression. This includes checking the

+ depth of the expression.

+ 

+ Signed-off-by: James Carter <jwcart2@gmail.com>

+ Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>

+ ---

+  libsepol/cil/src/cil_binary.c    | 50 ++++++++++++++++++++++++++++++++

+  libsepol/cil/src/cil_build_ast.c | 26 +++++------------

+  2 files changed, 57 insertions(+), 19 deletions(-)

+ 

+ diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c

+ index c8e41f09e53f..50cc7f757c62 100644

+ --- a/libsepol/cil/src/cil_binary.c

+ +++ b/libsepol/cil/src/cil_binary.c

+ @@ -2176,6 +2176,51 @@ static int __cil_cond_expr_to_sepol_expr(policydb_t *pdb, struct cil_list *cil_e

+  	return SEPOL_OK;

+  }

+  

+ +int __cil_validate_cond_expr(cond_expr_t *cond_expr)

+ +{

+ +	cond_expr_t *e;

+ +	int depth = -1;

+ +

+ +	for (e = cond_expr; e != NULL; e = e->next) {

+ +		switch (e->expr_type) {

+ +		case COND_BOOL:

+ +			if (depth == (COND_EXPR_MAXDEPTH - 1)) {

+ +				cil_log(CIL_ERR,"Conditional expression exceeded max allowable depth\n");

+ +				return SEPOL_ERR;

+ +			}

+ +			depth++;

+ +			break;

+ +		case COND_NOT:

+ +			if (depth < 0) {

+ +				cil_log(CIL_ERR,"Invalid conditional expression\n");

+ +				return SEPOL_ERR;

+ +			}

+ +			break;

+ +		case COND_OR:

+ +		case COND_AND:

+ +		case COND_XOR:

+ +		case COND_EQ:

+ +		case COND_NEQ:

+ +			if (depth < 1) {

+ +				cil_log(CIL_ERR,"Invalid conditional expression\n");

+ +				return SEPOL_ERR;

+ +			}

+ +			depth--;

+ +			break;

+ +		default:

+ +			cil_log(CIL_ERR,"Invalid conditional expression\n");

+ +			return SEPOL_ERR;

+ +		}

+ +	}

+ +

+ +	if (depth != 0) {

+ +		cil_log(CIL_ERR,"Invalid conditional expression\n");

+ +		return SEPOL_ERR;

+ +	}

+ +

+ +	return SEPOL_OK;

+ +}

+ +

+  int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node)

+  {

+  	int rc = SEPOL_ERR;

+ @@ -2204,6 +2249,11 @@ int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c

+  		goto exit;

+  	}

+  

+ +	rc = __cil_validate_cond_expr(tmp_cond->expr);

+ +	if (rc != SEPOL_OK) {

+ +		goto exit;

+ +	}

+ +

+  	tmp_cond->true_list = &tmp_cl;

+  

+  	rc = cond_normalize_expr(pdb, tmp_cond);

+ diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c

+ index 870c6923b4de..3aabb05ec534 100644

+ --- a/libsepol/cil/src/cil_build_ast.c

+ +++ b/libsepol/cil/src/cil_build_ast.c

+ @@ -2548,18 +2548,13 @@ static enum cil_flavor __cil_get_expr_operator_flavor(const char *op)

+  	else return CIL_NONE;

+  }

+  

+ -static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr, int *depth);

+ +static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr);

+  

+ -static int __cil_fill_expr_helper(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr, int *depth)

+ +static int __cil_fill_expr_helper(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr)

+  {

+  	int rc = SEPOL_ERR;

+  	enum cil_flavor op;

+  

+ -	if (flavor == CIL_BOOL && *depth > COND_EXPR_MAXDEPTH) {

+ -		cil_log(CIL_ERR, "Max depth of %d exceeded for boolean expression\n", COND_EXPR_MAXDEPTH);

+ -		goto exit;

+ -	}

+ -

+  	op = __cil_get_expr_operator_flavor(current->data);

+  

+  	rc = cil_verify_expr_syntax(current, op, flavor);

+ @@ -2572,26 +2567,20 @@ static int __cil_fill_expr_helper(struct cil_tree_node *current, enum cil_flavor

+  		current = current->next;

+  	}

+  

+ -	if (op == CIL_NONE || op == CIL_ALL) {

+ -		(*depth)++;

+ -	}

+ -

+  	for (;current != NULL; current = current->next) {

+ -		rc = __cil_fill_expr(current, flavor, expr, depth);

+ +		rc = __cil_fill_expr(current, flavor, expr);

+  		if (rc != SEPOL_OK) {

+  			goto exit;

+  		}

+  	}

+  

+ -	(*depth)--;

+ -

+  	return SEPOL_OK;

+  

+  exit:

+  	return rc;

+  }

+  

+ -static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr, int *depth)

+ +static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list *expr)

+  {

+  	int rc = SEPOL_ERR;

+  

+ @@ -2605,7 +2594,7 @@ static int __cil_fill_expr(struct cil_tree_node *current, enum cil_flavor flavor

+  	} else {

+  		struct cil_list *sub_expr;

+  		cil_list_init(&sub_expr, flavor);

+ -		rc = __cil_fill_expr_helper(current->cl_head, flavor, sub_expr, depth);

+ +		rc = __cil_fill_expr_helper(current->cl_head, flavor, sub_expr);

+  		if (rc != SEPOL_OK) {

+  			cil_list_destroy(&sub_expr, CIL_TRUE);

+  			goto exit;

+ @@ -2623,14 +2612,13 @@ exit:

+  int cil_gen_expr(struct cil_tree_node *current, enum cil_flavor flavor, struct cil_list **expr)

+  {

+  	int rc = SEPOL_ERR;

+ -	int depth = 0;

+  

+  	cil_list_init(expr, flavor);

+  

+  	if (current->cl_head == NULL) {

+ -		rc = __cil_fill_expr(current, flavor, *expr, &depth);

+ +		rc = __cil_fill_expr(current, flavor, *expr);

+  	} else {

+ -		rc = __cil_fill_expr_helper(current->cl_head, flavor, *expr, &depth);

+ +		rc = __cil_fill_expr_helper(current->cl_head, flavor, *expr);

+  	}

+  

+  	if (rc != SEPOL_OK) {

+ -- 

+ 2.29.0.rc2

+ 

@@ -0,0 +1,50 @@ 

+ From a152653b9a43fe2c776d239efc2d46d336555bc8 Mon Sep 17 00:00:00 2001

+ From: James Carter <jwcart2@gmail.com>

+ Date: Tue, 15 Sep 2020 14:48:06 -0400

+ Subject: [PATCH] libsepol/cil: Fix neverallow checking involving classmaps

+ 

+ When classmaps used in a neverallow were being expanded during CIL

+ neverallow checking, an empty classmapping in the list of

+ classmappings for a classmap would cause the classmap expansion to

+ stop and the rest of the classmapping of the classmap to be ignored.

+ This would mean that not all of the classes and permissions associated

+ with the classmap would be used to check for a neverallow violation.

+ 

+ Do not end the expansion of a classmap when one classmapping is empty.

+ 

+ Reported-by: Jonathan Hettwer <j2468h@gmail.com>

+ Signed-off-by: James Carter <jwcart2@gmail.com>

+ Acked-by: Stephen Smalley <stephen.smalley.work@gmail.com>

+ ---

+  libsepol/cil/src/cil_binary.c | 14 ++++++--------

+  1 file changed, 6 insertions(+), 8 deletions(-)

+ 

+ diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c

+ index 50cc7f757c62..36720eda4549 100644

+ --- a/libsepol/cil/src/cil_binary.c

+ +++ b/libsepol/cil/src/cil_binary.c

+ @@ -4363,15 +4363,13 @@ static int __cil_rule_to_sepol_class_perms(policydb_t *pdb, struct cil_list *cla

+  

+  				rc = __cil_perms_to_datum(cp->perms, sepol_class, &data);

+  				if (rc != SEPOL_OK) goto exit;

+ -				if (data == 0) {

+ -					/* No permissions */

+ -					return SEPOL_OK;

+ +				if (data != 0) { /* Only add if there are permissions */

+ +					cpn = cil_malloc(sizeof(class_perm_node_t));

+ +					cpn->tclass = sepol_class->s.value;

+ +					cpn->data = data;

+ +					cpn->next = *sepol_class_perms;

+ +					*sepol_class_perms = cpn;

+  				}

+ -				cpn = cil_malloc(sizeof(class_perm_node_t));

+ -				cpn->tclass = sepol_class->s.value;

+ -				cpn->data = data;

+ -				cpn->next = *sepol_class_perms;

+ -				*sepol_class_perms = cpn;

+  			} else { /* MAP */

+  				struct cil_list_item *j = NULL;

+  				cil_list_for_each(j, cp->perms) {

+ -- 

+ 2.29.0.rc2

+ 

@@ -0,0 +1,90 @@ 

+ From 521e6a2f478a4c7a7c198c017d4d12e8667d89e7 Mon Sep 17 00:00:00 2001

+ From: Nicolas Iooss <nicolas.iooss@m4x.org>

+ Date: Sat, 3 Oct 2020 15:19:08 +0200

+ Subject: [PATCH] libsepol/cil: fix signed overflow caused by using (1 << 31) -

+  1

+ 

+ When compiling SELinux userspace tools with -ftrapv (this option

+ generates traps for signed overflow on addition, subtraction,

+ multiplication operations, instead of silently wrapping around),

+ semodule crashes when running the tests from

+ scripts/ci/fedora-test-runner.sh in a Fedora 32 virtual machine:

+ 

+     [root@localhost selinux-testsuite]# make test

+     make -C policy load

+     make[1]: Entering directory '/root/selinux-testsuite/policy'

+     # Test for "expand-check = 0" in /etc/selinux/semanage.conf

+     # General policy build

+     make[2]: Entering directory '/root/selinux-testsuite/policy/test_policy'

+     Compiling targeted test_policy module

+     Creating targeted test_policy.pp policy package

+     rm tmp/test_policy.mod.fc

+     make[2]: Leaving directory '/root/selinux-testsuite/policy/test_policy'

+     # General policy load

+     domain_fd_use --> off

+     /usr/sbin/semodule -i test_policy/test_policy.pp test_mlsconstrain.cil test_overlay_defaultrange.cil test_add_levels.cil test_glblub.cil

+     make[1]: *** [Makefile:174: load] Aborted (core dumped)

+ 

+ Using "coredumpctl gdb" leads to the following strack trace:

+ 

+     (gdb) bt

+     #0  0x00007f608fe4fa25 in raise () from /lib64/libc.so.6

+     #1  0x00007f608fe38895 in abort () from /lib64/libc.so.6

+     #2  0x00007f6090028aca in __addvsi3.cold () from /lib64/libsepol.so.1

+     #3  0x00007f6090096f59 in __avrule_xperm_setrangebits (low=30, high=30, xperms=0x8b9eea0)

+         at ../cil/src/cil_binary.c:1551

+     #4  0x00007f60900970dd in __cil_permx_bitmap_to_sepol_xperms_list (xperms=0xb650a30, xperms_list=0x7ffce2653b18)

+         at ../cil/src/cil_binary.c:1596

+     #5  0x00007f6090097286 in __cil_avrulex_ioctl_to_policydb (k=0xb8ec200 "@\023\214\022\006", datum=0xb650a30,

+         args=0x239a640) at ../cil/src/cil_binary.c:1649

+     #6  0x00007f609003f1e5 in hashtab_map (h=0x41f8710, apply=0x7f60900971da <__cil_avrulex_ioctl_to_policydb>,

+         args=0x239a640) at hashtab.c:234

+     #7  0x00007f609009ea19 in cil_binary_create_allocated_pdb (db=0x2394f10, policydb=0x239a640)

+         at ../cil/src/cil_binary.c:4969

+     #8  0x00007f609009d19d in cil_binary_create (db=0x2394f10, policydb=0x7ffce2653d30) at ../cil/src/cil_binary.c:4329

+     #9  0x00007f609008ec23 in cil_build_policydb_create_pdb (db=0x2394f10, sepol_db=0x7ffce2653d30)

+         at ../cil/src/cil.c:631

+     #10 0x00007f608fff4bf3 in semanage_direct_commit () from /lib64/libsemanage.so.1

+     #11 0x00007f608fff9fae in semanage_commit () from /lib64/libsemanage.so.1

+     #12 0x0000000000403e2b in main (argc=7, argv=0x7ffce2655058) at semodule.c:753

+ 

+     (gdb) f 3

+     #3  0x00007f6090096f59 in __avrule_xperm_setrangebits (low=30, high=30, xperms=0x8b9eea0)

+         at ../cil/src/cil_binary.c:1551

+     1551     xperms->perms[i] |= XPERM_SETBITS(h) - XPERM_SETBITS(low);

+ 

+ A signed integer overflow therefore occurs in XPERM_SETBITS(h):

+ 

+     #define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1)

+ 

+ This macro is expanded with h=31, so "(1 << 31) - 1" is computed:

+ 

+ * (1 << 31) = -0x80000000 is the lowest signed 32-bit integer value

+ * (1 << 31) - 1 overflows the capacity of a signed 32-bit integer and

+   results in 0x7fffffff (which is unsigned)

+ 

+ Using unsigned integers (with "1U") fixes the crash, as

+ (1U << 31) = 0x80000000U has no overflowing issues.

+ 

+ Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>

+ Acked-by: Petr Lautrbach <plautrba@redhat.com>

+ ---

+  libsepol/cil/src/cil_binary.c | 2 +-

+  1 file changed, 1 insertion(+), 1 deletion(-)

+ 

+ diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c

+ index 36720eda4549..e417c5c28b8b 100644

+ --- a/libsepol/cil/src/cil_binary.c

+ +++ b/libsepol/cil/src/cil_binary.c

+ @@ -1526,7 +1526,7 @@ int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_

+  /* index of the u32 containing the permission */

+  #define XPERM_IDX(x) (x >> 5)

+  /* set bits 0 through x-1 within the u32 */

+ -#define XPERM_SETBITS(x) ((1 << (x & 0x1f)) - 1)

+ +#define XPERM_SETBITS(x) ((1U << (x & 0x1f)) - 1)

+  /* low value for this u32 */

+  #define XPERM_LOW(x) (x << 5)

+  /* high value for this u32 */

+ -- 

+ 2.29.0.rc2

+ 

@@ -0,0 +1,77 @@ 

+ From 64387cb37379fc8f135eeecd2bd9fdf3c591c763 Mon Sep 17 00:00:00 2001

+ From: Nicolas Iooss <nicolas.iooss@m4x.org>

+ Date: Sat, 3 Oct 2020 15:34:19 +0200

+ Subject: [PATCH] libsepol: drop confusing BUG_ON macro

+ 

+ Contrary to Linux kernel, BUG_ON() does not halt the execution, in

+ libsepol/src/services.c. Instead it displays an error message and

+ continues the execution.

+ 

+ This means that this code does not prevent an out-of-bound write from

+ happening:

+ 

+     case CEXPR_AND:

+         BUG_ON(sp < 1);

+         sp--;

+         s[sp] &= s[sp + 1];

+ 

+ Use if(...){BUG();rc=-EINVAL;goto out;} constructions instead, to make

+ sure that the array access is always in-bound.

+ 

+ This issue has been found using clang's static analyzer:

+ https://558-118970575-gh.circle-artifacts.com/0/output-scan-build/2020-10-02-065849-6375-1/report-50a861.html#EndPath

+ 

+ Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>

+ ---

+  libsepol/src/services.c | 19 +++++++++++++++----

+  1 file changed, 15 insertions(+), 4 deletions(-)

+ 

+ diff --git a/libsepol/src/services.c b/libsepol/src/services.c

+ index 90da1f4efef3..beb0711f6680 100644

+ --- a/libsepol/src/services.c

+ +++ b/libsepol/src/services.c

+ @@ -67,7 +67,6 @@

+  #include "flask.h"

+  

+  #define BUG() do { ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0)

+ -#define BUG_ON(x) do { if (x) ERR(NULL, "Badness at %s:%d", __FILE__, __LINE__); } while (0)

+  

+  static int selinux_enforcing = 1;

+  

+ @@ -469,18 +468,30 @@ static int constraint_expr_eval_reason(context_struct_t *scontext,

+  		/* Now process each expression of the constraint */

+  		switch (e->expr_type) {

+  		case CEXPR_NOT:

+ -			BUG_ON(sp < 0);

+ +			if (sp < 0) {

+ +				BUG();

+ +				rc = -EINVAL;

+ +				goto out;

+ +			}

+  			s[sp] = !s[sp];

+  			cat_expr_buf(expr_list[expr_counter], "not");

+  			break;

+  		case CEXPR_AND:

+ -			BUG_ON(sp < 1);

+ +			if (sp < 1) {

+ +				BUG();

+ +				rc = -EINVAL;

+ +				goto out;

+ +			}

+  			sp--;

+  			s[sp] &= s[sp + 1];

+  			cat_expr_buf(expr_list[expr_counter], "and");

+  			break;

+  		case CEXPR_OR:

+ -			BUG_ON(sp < 1);

+ +			if (sp < 1) {

+ +				BUG();

+ +				rc = -EINVAL;

+ +				goto out;

+ +			}

+  			sp--;

+  			s[sp] |= s[sp + 1];

+  			cat_expr_buf(expr_list[expr_counter], "or");

+ -- 

+ 2.29.0.rc2

+ 

@@ -0,0 +1,66 @@ 

+ From c97d63c6b40c71c693d3b5bb25628869a95dff24 Mon Sep 17 00:00:00 2001

+ From: Nicolas Iooss <nicolas.iooss@m4x.org>

+ Date: Sat, 3 Oct 2020 15:56:58 +0200

+ Subject: [PATCH] libsepol: silence potential NULL pointer dereference warning

+ 

+ When find_avtab_node() is called with key->specified & AVTAB_XPERMS and

+ xperms=NULL, xperms is being dereferenced. This is detected as a

+ "NULL pointer dereference issue" by static analyzers.

+ 

+ Even though it does not make much sense to call find_avtab_node() in a

+ way which triggers the NULL pointer dereference issue, static analyzers

+ have a hard time with calls such as:

+ 

+     node = find_avtab_node(handle, avtab, &avkey, cond, NULL);

+ 

+ ... where xperms=NULL.

+ 

+ So, make the function report an error instead of crashing.

+ 

+ Here is an example of report from clang's static analyzer:

+ https://558-118970575-gh.circle-artifacts.com/0/output-scan-build/2020-10-02-065849-6375-1/report-d86a57.html#EndPath

+ 

+ Signed-off-by: Nicolas Iooss <nicolas.iooss@m4x.org>

+ ---

+  libsepol/src/expand.c | 23 ++++++++++++++---------

+  1 file changed, 14 insertions(+), 9 deletions(-)

+ 

+ diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c

+ index 19e48c507236..eac7e4507d02 100644

+ --- a/libsepol/src/expand.c

+ +++ b/libsepol/src/expand.c

+ @@ -1570,17 +1570,22 @@ static avtab_ptr_t find_avtab_node(sepol_handle_t * handle,

+  

+  	/* AVTAB_XPERMS entries are not necessarily unique */

+  	if (key->specified & AVTAB_XPERMS) {

+ -		node = avtab_search_node(avtab, key);

+ -		while (node) {

+ -			if ((node->datum.xperms->specified == xperms->specified) &&

+ -				(node->datum.xperms->driver == xperms->driver)) {

+ -				match = 1;

+ -				break;

+ +		if (xperms == NULL) {

+ +			ERR(handle, "searching xperms NULL");

+ +			node = NULL;

+ +		} else {

+ +			node = avtab_search_node(avtab, key);

+ +			while (node) {

+ +				if ((node->datum.xperms->specified == xperms->specified) &&

+ +					(node->datum.xperms->driver == xperms->driver)) {

+ +					match = 1;

+ +					break;

+ +				}

+ +				node = avtab_search_node_next(node, key->specified);

+  			}

+ -			node = avtab_search_node_next(node, key->specified);

+ +			if (!match)

+ +				node = NULL;

+  		}

+ -		if (!match)

+ -			node = NULL;

+  	} else {

+  		node = avtab_search_node(avtab, key);

+  	}

+ -- 

+ 2.29.0.rc2

+ 

@@ -0,0 +1,193 @@ 

+ From ae58e84b4fd825b6cd2c67f3856ac35557c45e9c Mon Sep 17 00:00:00 2001

+ From: Petr Lautrbach <plautrba@redhat.com>

+ Date: Fri, 9 Oct 2020 15:00:47 +0200

+ Subject: [PATCH] libsepol: Get rid of the old and duplicated symbols

+ 

+ Versioned duplicate symbols cause problems for LTO. These symbols were

+ introduced during the CIL integration several releases ago and were only

+ consumed by other SELinux userspace components.

+ 

+ Fixes: https://github.com/SELinuxProject/selinux/issues/245

+ 

+ Signed-off-by: Petr Lautrbach <plautrba@redhat.com>

+ ---

+  libsepol/cil/src/cil.c       | 84 ------------------------------------

+  libsepol/src/libsepol.map.in |  5 ---

+  2 files changed, 89 deletions(-)

+ 

+ diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c

+ index a3c6a2934c72..95bdb5e5854c 100644

+ --- a/libsepol/cil/src/cil.c

+ +++ b/libsepol/cil/src/cil.c

+ @@ -51,27 +51,6 @@

+  #include "cil_policy.h"

+  #include "cil_strpool.h"

+  

+ -#if !defined(SHARED) || defined(ANDROID) || defined(__APPLE__)

+ -    #define DISABLE_SYMVER 1

+ -#endif

+ -

+ -#ifndef DISABLE_SYMVER

+ -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@LIBSEPOL_1.0");

+ -asm(".symver cil_compile_nopdb, cil_compile@@LIBSEPOL_1.1");

+ -

+ -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@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@LIBSEPOL_1.0");

+ -asm(".symver cil_filecons_to_string_nopdb, cil_filecons_to_string@@LIBSEPOL_1.1");

+ -#endif

+ -

+  int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM] = {

+  	{64, 64, 64, 1 << 13, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},

+  	{64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64},

+ @@ -549,11 +528,7 @@ exit:

+  	return rc;

+  }

+  

+ -#ifdef DISABLE_SYMVER

+  int cil_compile(struct cil_db *db)

+ -#else

+ -int cil_compile_nopdb(struct cil_db *db)

+ -#endif

+  {

+  	int rc = SEPOL_ERR;

+  

+ @@ -597,33 +572,7 @@ exit:

+  	return rc;

+  }

+  

+ -#ifndef DISABLE_SYMVER

+ -int cil_compile_pdb(struct cil_db *db, __attribute__((unused)) sepol_policydb_t *sepol_db)

+ -{

+ -	return cil_compile_nopdb(db);

+ -}

+ -

+ -int cil_build_policydb_pdb(cil_db_t *db, sepol_policydb_t *sepol_db)

+ -{

+ -	int rc;

+ -

+ -	cil_log(CIL_INFO, "Building policy binary\n");

+ -	rc = cil_binary_create_allocated_pdb(db, sepol_db);

+ -	if (rc != SEPOL_OK) {

+ -		cil_log(CIL_ERR, "Failed to generate binary\n");

+ -		goto exit;

+ -	}

+ -

+ -exit:

+ -	return rc;

+ -}

+ -#endif

+ -

+ -#ifdef DISABLE_SYMVER

+  int cil_build_policydb(cil_db_t *db, sepol_policydb_t **sepol_db)

+ -#else

+ -int cil_build_policydb_create_pdb(cil_db_t *db, sepol_policydb_t **sepol_db)

+ -#endif

+  {

+  	int rc;

+  

+ @@ -1371,11 +1320,7 @@ const char * cil_node_to_string(struct cil_tree_node *node)

+  	return "<unknown>";

+  }

+  

+ -#ifdef DISABLE_SYMVER

+  int cil_userprefixes_to_string(struct cil_db *db, char **out, size_t *size)

+ -#else

+ -int cil_userprefixes_to_string_nopdb(struct cil_db *db, char **out, size_t *size)

+ -#endif

+  {

+  	int rc = SEPOL_ERR;

+  	size_t str_len = 0;

+ @@ -1420,13 +1365,6 @@ exit:

+  

+  }

+  

+ -#ifndef DISABLE_SYMVER

+ -int cil_userprefixes_to_string_pdb(struct cil_db *db, __attribute__((unused)) sepol_policydb_t *sepol_db, char **out, size_t *size)

+ -{

+ -	return cil_userprefixes_to_string_nopdb(db, out, size);

+ -}

+ -#endif

+ -

+  static int cil_cats_to_ebitmap(struct cil_cats *cats, struct ebitmap* cats_ebitmap)

+  {

+  	int rc = SEPOL_ERR;

+ @@ -1614,11 +1552,7 @@ static int __cil_level_to_string(struct cil_level *lvl, char *out)

+  	return str_tmp - out;

+  }

+  

+ -#ifdef DISABLE_SYMVER

+  int cil_selinuxusers_to_string(struct cil_db *db, char **out, size_t *size)

+ -#else

+ -int cil_selinuxusers_to_string_nopdb(struct cil_db *db, char **out, size_t *size)

+ -#endif

+  {

+  	size_t str_len = 0;

+  	int buf_pos = 0;

+ @@ -1675,18 +1609,7 @@ int cil_selinuxusers_to_string_nopdb(struct cil_db *db, char **out, size_t *size

+  	return SEPOL_OK;

+  }

+  

+ -#ifndef DISABLE_SYMVER

+ -int cil_selinuxusers_to_string_pdb(struct cil_db *db, __attribute__((unused)) sepol_policydb_t *sepol_db, char **out, size_t *size)

+ -{

+ -	return cil_selinuxusers_to_string_nopdb(db, out, size);

+ -}

+ -#endif

+ -

+ -#ifdef DISABLE_SYMVER

+  int cil_filecons_to_string(struct cil_db *db, char **out, size_t *size)

+ -#else

+ -int cil_filecons_to_string_nopdb(struct cil_db *db, char **out, size_t *size)

+ -#endif

+  {

+  	uint32_t i = 0;

+  	int buf_pos = 0;

+ @@ -1804,13 +1727,6 @@ int cil_filecons_to_string_nopdb(struct cil_db *db, char **out, size_t *size)

+  	return SEPOL_OK;

+  }

+  

+ -#ifndef DISABLE_SYMVER

+ -int cil_filecons_to_string_pdb(struct cil_db *db, __attribute__((unused)) sepol_policydb_t *sepol_db, char **out, size_t *size)

+ -{

+ -	return cil_filecons_to_string_nopdb(db, out, size);

+ -}

+ -#endif

+ -

+  void cil_set_disable_dontaudit(struct cil_db *db, int disable_dontaudit)

+  {

+  	db->disable_dontaudit = disable_dontaudit;

+ diff --git a/libsepol/src/libsepol.map.in b/libsepol/src/libsepol.map.in

+ index f08c2a861693..98da9789b71b 100644

+ --- a/libsepol/src/libsepol.map.in

+ +++ b/libsepol/src/libsepol.map.in

+ @@ -1,19 +1,14 @@

+  LIBSEPOL_1.0 {

+    global:

+  	cil_add_file;

+ -	cil_build_policydb;

+ -	cil_compile;

+  	cil_db_destroy;

+  	cil_db_init;

+ -	cil_filecons_to_string;

+ -	cil_selinuxusers_to_string;

+  	cil_set_disable_dontaudit;

+  	cil_set_disable_neverallow;

+  	cil_set_handle_unknown;

+  	cil_set_log_handler;

+  	cil_set_log_level;

+  	cil_set_preserve_tunables;

+ -	cil_userprefixes_to_string;

+  	expand_module_avrules;

+  	sepol_bool_clone;

+  	sepol_bool_compare;

+ -- 

+ 2.29.0.rc2

+ 

@@ -0,0 +1,134 @@ 

+ From 506c7b95b802ab157fe9ae1dae22fab12c515306 Mon Sep 17 00:00:00 2001

+ From: Petr Lautrbach <plautrba@redhat.com>

+ Date: Fri, 9 Oct 2020 15:00:48 +0200

+ Subject: [PATCH] libsepol: Drop deprecated functions

+ 

+ These functions were converted to no-op by commit

+ c3f9492d7ff0 ("selinux: Remove legacy local boolean and user code") and

+ left in libsepol/src/deprecated_functions.c to preserve API/ABI. As we

+ change libsepol ABI dropping duplicate symbols it's time to drop these

+ functions too.

+ 

+ Signed-off-by: Petr Lautrbach <plautrba@redhat.com>

+ ---

+  libsepol/include/sepol/booleans.h |  5 ----

+  libsepol/include/sepol/users.h    |  6 ----

+  libsepol/src/deprecated_funcs.c   | 50 -------------------------------

+  libsepol/src/libsepol.map.in      |  4 ---

+  4 files changed, 65 deletions(-)

+  delete mode 100644 libsepol/src/deprecated_funcs.c

+ 

+ diff --git a/libsepol/include/sepol/booleans.h b/libsepol/include/sepol/booleans.h

+ index 06d2230c395d..25229057dbd7 100644

+ --- a/libsepol/include/sepol/booleans.h

+ +++ b/libsepol/include/sepol/booleans.h

+ @@ -10,11 +10,6 @@

+  extern "C" {

+  #endif

+  

+ -/* These two functions are deprecated. See src/deprecated_funcs.c */

+ -extern int sepol_genbools(void *data, size_t len, const char *boolpath);

+ -extern int sepol_genbools_array(void *data, size_t len,

+ -				char **names, int *values, int nel);

+ -

+  /* Set the specified boolean */

+  extern int sepol_bool_set(sepol_handle_t * handle,

+  			  sepol_policydb_t * policydb,

+ diff --git a/libsepol/include/sepol/users.h b/libsepol/include/sepol/users.h

+ index 70158ac41e40..156d1adb2d60 100644

+ --- a/libsepol/include/sepol/users.h

+ +++ b/libsepol/include/sepol/users.h

+ @@ -10,12 +10,6 @@

+  extern "C" {

+  #endif

+  

+ -/* These two functions are deprecated. See src/deprecated_funcs.c */

+ -extern int sepol_genusers(void *data, size_t len,

+ -			  const char *usersdir,

+ -			  void **newdata, size_t * newlen);

+ -extern void sepol_set_delusers(int on);

+ -

+  /* Modify the user, or add it, if the key is not found */

+  extern int sepol_user_modify(sepol_handle_t * handle,

+  			     sepol_policydb_t * policydb,

+ diff --git a/libsepol/src/deprecated_funcs.c b/libsepol/src/deprecated_funcs.c

+ deleted file mode 100644

+ index d0dab7dfcb4a..000000000000

+ --- a/libsepol/src/deprecated_funcs.c

+ +++ /dev/null

+ @@ -1,50 +0,0 @@

+ -#include <stdio.h>

+ -#include "debug.h"

+ -

+ -/*

+ - * Need to keep these stubs for the libsepol interfaces exported in

+ - * libsepol.map.in, as they are part of the shared library ABI.

+ - */

+ -

+ -static const char *msg = "Deprecated interface";

+ -

+ -/*

+ - * These two functions are deprecated and referenced in:

+ - *	include/libsepol/users.h

+ - */

+ -int sepol_genusers(void *data __attribute((unused)),

+ -		   size_t len __attribute((unused)),

+ -		   const char *usersdir __attribute((unused)),

+ -		   void **newdata __attribute((unused)),

+ -		   size_t *newlen __attribute((unused)))

+ -{

+ -	WARN(NULL, "%s", msg);

+ -	return -1;

+ -}

+ -

+ -void sepol_set_delusers(int on __attribute((unused)))

+ -{

+ -	WARN(NULL, "%s", msg);

+ -}

+ -

+ -/*

+ - * These two functions are deprecated and referenced in:

+ - *	include/libsepol/booleans.h

+ - */

+ -int sepol_genbools(void *data __attribute((unused)),

+ -		   size_t len __attribute((unused)),

+ -		   const char *booleans __attribute((unused)))

+ -{

+ -	WARN(NULL, "%s", msg);

+ -	return -1;

+ -}

+ -

+ -int sepol_genbools_array(void *data __attribute((unused)),

+ -			 size_t len __attribute((unused)),

+ -			 char **names __attribute((unused)),

+ -			 int *values __attribute((unused)),

+ -			 int nel __attribute((unused)))

+ -{

+ -	WARN(NULL, "%s", msg);

+ -	return -1;

+ -}

+ diff --git a/libsepol/src/libsepol.map.in b/libsepol/src/libsepol.map.in

+ index 98da9789b71b..eb5721257638 100644

+ --- a/libsepol/src/libsepol.map.in

+ +++ b/libsepol/src/libsepol.map.in

+ @@ -45,9 +45,6 @@ LIBSEPOL_1.0 {

+  	sepol_context_to_string;

+  	sepol_debug;

+  	sepol_expand_module;

+ -	sepol_genbools;

+ -	sepol_genbools_array;

+ -	sepol_genusers;

+  	sepol_get_disable_dontaudit;

+  	sepol_get_preserve_tunables;

+  	sepol_handle_create;

+ @@ -213,7 +210,6 @@ LIBSEPOL_1.0 {

+  	sepol_port_set_port;

+  	sepol_port_set_proto;

+  	sepol_port_set_range;

+ -	sepol_set_delusers;

+  	sepol_set_disable_dontaudit;

+  	sepol_set_expand_consume_base;

+  	sepol_set_policydb_from_file;

+ -- 

+ 2.29.0.rc2

+ 

@@ -0,0 +1,45 @@ 

+ From 4a142ac46a116feb9f978eaec68a30efef979c73 Mon Sep 17 00:00:00 2001

+ From: Petr Lautrbach <plautrba@redhat.com>

+ Date: Fri, 9 Oct 2020 15:00:49 +0200

+ Subject: [PATCH] libsepol: Bump libsepol.so version

+ 

+ Previous commits removed some symbols and broke ABI, therefore we need to change

+ SONAME.

+ 

+ See the following quotes from distribution guidelines:

+ 

+ https://www.debian.org/doc/debian-policy/ch-sharedlibs.html#run-time-shared-libraries

+ 

+ Every time the shared library ABI changes in a way that may break

+ binaries linked against older versions of the shared library, the SONAME

+ of the library and the corresponding name for the binary package

+ containing the runtime shared library should change.

+ 

+ https://docs.fedoraproject.org/en-US/packaging-guidelines/#_downstream_so_name_versioning

+ 

+ When new versions of the library are released, you should use an ABI

+ comparison tool to check for ABI differences in the built shared

+ libraries. If it detects any incompatibilities, bump the n number by

+ one.

+ 

+ Signed-off-by: Petr Lautrbach <plautrba@redhat.com>

+ ---

+  libsepol/src/Makefile | 2 +-

+  1 file changed, 1 insertion(+), 1 deletion(-)

+ 

+ diff --git a/libsepol/src/Makefile b/libsepol/src/Makefile

+ index 8d466f56ed0e..dc8b1773d974 100644

+ --- a/libsepol/src/Makefile

+ +++ b/libsepol/src/Makefile

+ @@ -7,7 +7,7 @@ RANLIB ?= ranlib

+  CILDIR ?= ../cil

+  

+  VERSION = $(shell cat ../VERSION)

+ -LIBVERSION = 1

+ +LIBVERSION = 2

+  

+  LEX = flex

+  CIL_GENERATED = $(CILDIR)/src/cil_lexer.c

+ -- 

+ 2.29.0.rc2

+ 

file modified
+32 -3
@@ -1,7 +1,7 @@ 

  Summary: SELinux binary policy manipulation library

  Name: libsepol

  Version: 3.1

- Release: 3%{?dist}

+ Release: 4%{?dist}

  License: LGPLv2+

  Source0: https://github.com/SELinuxProject/selinux/releases/download/20200710/libsepol-3.1.tar.gz

  URL: https://github.com/SELinuxProject/selinux/wiki
@@ -10,6 +10,17 @@ 

  # $ git format-patch -N libsepol-3.1 -- libsepol

  # $ i=1; for j in 00*patch; do printf "Patch%04d: %s\n" $i $j; i=$((i+1));done

  # Patch list start

+ Patch0001: 0001-libsepol-checkpolicy-optimize-storage-of-filename-tr.patch

+ Patch0002: 0002-libsepol-implement-POLICYDB_VERSION_COMP_FTRANS.patch

+ Patch0003: 0003-libsepol-cil-Validate-constraint-expressions-before-.patch

+ Patch0004: 0004-libsepol-cil-Validate-conditional-expressions-before.patch

+ Patch0005: 0005-libsepol-cil-Fix-neverallow-checking-involving-class.patch

+ Patch0006: 0006-libsepol-cil-fix-signed-overflow-caused-by-using-1-3.patch

+ Patch0007: 0007-libsepol-drop-confusing-BUG_ON-macro.patch

+ Patch0008: 0008-libsepol-silence-potential-NULL-pointer-dereference-.patch

+ Patch0009: 0009-libsepol-Get-rid-of-the-old-and-duplicated-symbols.patch

+ Patch0010: 0010-libsepol-Drop-deprecated-functions.patch

+ Patch0011: 0011-libsepol-Bump-libsepol.so-version.patch

  # Patch list end

  BuildRequires: gcc

  BuildRequires: flex
@@ -46,6 +57,12 @@ 

  The libsepol-static package contains the static libraries and header files

  needed for developing applications that manipulate binary policies. 

  

+ %package compat

+ Summary: Temporary compat libsepol.so.1 used for transition to libsepol.so.2

+ 

+ %description compat

+ Temporary compat libsepol.so.1 used for transition to libsepol.so.2

+ 

  %prep

  %autosetup -p 2 -n libsepol-%{version}

  
@@ -55,8 +72,6 @@ 

  %endif

  

  %build

- # Disable LTO

- %define _lto_cflags %{nil}

  %set_build_flags

  CFLAGS="$CFLAGS -fno-semantic-interposition"

  %make_build
@@ -75,6 +90,11 @@ 

  rm -rf ${RPM_BUILD_ROOT}%{_mandir}/man8

  rm -rf ${RPM_BUILD_ROOT}%{_mandir}/ru/man8

  

+ %set_build_flags

+ CFLAGS="$CFLAGS -fno-semantic-interposition"

+ sed -i 's/LIBVERSION = 2/LIBVERSION = 1/' src/Makefile

+ %make_build

+ cp src/libsepol.so.1 ${RPM_BUILD_ROOT}/%{_libdir}/libsepol.so.1

  

  %files static

  %{_libdir}/libsepol.a
@@ -93,9 +113,18 @@ 

  %files

  %{!?_licensedir:%global license %%doc}

  %license COPYING

+ %{_libdir}/libsepol.so.2

+ 

+ %files compat

  %{_libdir}/libsepol.so.1

  

  %changelog

+ * Fri Oct 23 2020 Petr Lautrbach <plautrba@redhat.com> - 3.1-4

+ - Drop deprecated functions and duplicated symbols

+ - Dange library version to libsepol.so.2

+ - temporary ship -compat with libsepol.so.1

+ - Re-enable LTO flags

+ 

  * Mon Jul 27 2020 Petr Lautrbach <plautrba@redhat.com> - 3.1-3

  - Disable LTO cflags

  - Drop telinit from % post sciptlet

no initial comment

rebased onto 525d6d4

3 years ago

rebased onto 2d8f69c

3 years ago

rebased onto 78c1803

3 years ago

rebased onto 15d2912

3 years ago

rebased onto 13eae1c

3 years ago

Pull-Request has been closed by plautrba

3 years ago