diff options
author | Nick Kralevich <nnk@google.com> | 2020-02-11 10:17:17 -0800 |
---|---|---|
committer | Nick Kralevich <nnk@google.com> | 2020-02-11 10:18:08 -0800 |
commit | 18205ff9d71717029af075d82e0e25906901af97 (patch) | |
tree | 28ec24aa2f19ece275ceb3ca0e5c4ef28608b698 | |
parent | 4a9e04bc056f23d3ba82deeb03b41e7547dbff33 (diff) | |
parent | a60343cabfc22bdd08491103d8308fcd56df1a4d (diff) | |
download | selinux-18205ff9d71717029af075d82e0e25906901af97.tar.gz |
Merge remote-tracking branch 'aosp/upstream-master' into mymerge
Followed the following steps:
# In repo client
cd external/selinux
repo sync .
repo start mymerge .
git merge aosp/upstream-master --no-ff # resolve any conflicts
lunch && make -j
repo upload .
Test: compiles and boots
Change-Id: I45fd32fb9bfe2291ef32afcc86f26eb2b24e03e8
-rw-r--r-- | .travis.yml | 3 | ||||
-rw-r--r-- | checkpolicy/test/dismod.c | 4 | ||||
-rw-r--r-- | libsemanage/src/Makefile | 4 | ||||
-rw-r--r-- | libsepol/cil/src/cil_binary.c | 127 | ||||
-rw-r--r-- | libsepol/cil/src/cil_binary.h | 6 | ||||
-rw-r--r-- | libsepol/cil/src/cil_verify.c | 86 | ||||
-rw-r--r-- | libsepol/include/sepol/policydb/polcaps.h | 1 | ||||
-rw-r--r-- | libsepol/src/expand.c | 24 | ||||
-rw-r--r-- | libsepol/src/polcaps.c | 1 | ||||
-rw-r--r-- | libsepol/src/policydb.c | 4 | ||||
-rw-r--r-- | libsepol/src/write.c | 22 |
11 files changed, 102 insertions, 180 deletions
diff --git a/.travis.yml b/.travis.yml index e9f86baa..918958ac 100644 --- a/.travis.yml +++ b/.travis.yml @@ -13,6 +13,7 @@ env: # Test the last version of Python and Ruby together, with some linkers - PYVER=python3.7 RUBYLIBVER=2.6 - PYVER=python3.7 RUBYLIBVER=2.6 TEST_FLAGS_OVERRIDE=1 + - PYVER=python3.7 RUBYLIBVER=2.6 TEST_DEBUG=1 - PYVER=python3.7 RUBYLIBVER=2.6 LINKER=gold - PYVER=python3.7 RUBYLIBVER=2.6 LINKER=bfd @@ -116,6 +117,8 @@ before_script: # If TEST_FLAGS_OVERRIDE is defined, test that overriding CFLAGS, LDFLAGS and other variables works fine - if [ -n "$TEST_FLAGS_OVERRIDE" ]; then EXPLICIT_MAKE_VARS="CFLAGS=-I$DESTDIR/usr/include LDFLAGS=-L$DESTDIR/usr/lib LDLIBS= CPPFLAGS=" ; fi + # If TEST_DEBUG is defined, test that debug build works fine + - if [ -n "$TEST_DEBUG" ]; then EXPLICIT_MAKE_VARS="$EXPLICIT_MAKE_VARS DEBUG=1" ; fi script: # Start by installing everything into $DESTDIR diff --git a/checkpolicy/test/dismod.c b/checkpolicy/test/dismod.c index 996cf33f..41bde48f 100644 --- a/checkpolicy/test/dismod.c +++ b/checkpolicy/test/dismod.c @@ -445,8 +445,8 @@ void display_initial_sids(policydb_t * p, FILE * fp) user = p->p_user_val_to_name[cur->context[0].user - 1]; role = p->p_role_val_to_name[cur->context[0].role - 1]; type = p->p_type_val_to_name[cur->context[0].type - 1]; - fprintf(fp, "\t%s: sid %d, context %s:%s:%s\n", - cur->u.name, cur->sid[0], user, role, type); + fprintf(fp, "\tsid %d, context %s:%s:%s\n", + cur->sid[0], user, role, type); } #if 0 fprintf(fp, "Policy Initial SIDs:\n"); diff --git a/libsemanage/src/Makefile b/libsemanage/src/Makefile index 8a9570c7..f6780dc6 100644 --- a/libsemanage/src/Makefile +++ b/libsemanage/src/Makefile @@ -22,8 +22,8 @@ RUBYINSTALL ?= $(shell $(RUBY) -e 'puts RbConfig::CONFIG["vendorarchdir"]') DEFAULT_SEMANAGE_CONF_LOCATION=/etc/selinux/semanage.conf ifeq ($(DEBUG),1) - export CFLAGS = -g3 -O0 -gdwarf-2 -fno-strict-aliasing -Wall -Wshadow -Werror - export LDFLAGS = -g + export CFLAGS ?= -g3 -O0 -gdwarf-2 -fno-strict-aliasing -Wall -Wshadow -Werror + export LDFLAGS ?= -g endif LEX = flex diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c index 4cf6f481..03d53e1f 100644 --- a/libsepol/cil/src/cil_binary.c +++ b/libsepol/cil/src/cil_binary.c @@ -59,8 +59,6 @@ /* There are 44000 filename_trans in current fedora policy. 1.33 times this is the recommended * size of a hashtable. The next power of 2 of this is 2 ** 16. */ -#define FILENAME_TRANS_TABLE_SIZE (1 << 16) -#define RANGE_TRANS_TABLE_SIZE (1 << 13) #define ROLE_TRANS_TABLE_SIZE (1 << 10) #define AVRULEX_TABLE_SIZE (1 << 10) #define PERMS_PER_CLASS 32 @@ -70,8 +68,6 @@ struct cil_args_binary { policydb_t *pdb; struct cil_list *neverallows; int pass; - hashtab_t filename_trans_table; - hashtab_t range_trans_table; hashtab_t role_trans_table; hashtab_t avrulex_ioctl_table; void **type_value_to_cil; @@ -82,7 +78,6 @@ struct cil_args_booleanif { policydb_t *pdb; cond_node_t *cond_node; enum cil_flavor cond_flavor; - hashtab_t filename_trans_table; }; static int __cil_get_sepol_user_datum(policydb_t *pdb, struct cil_symtab_datum *datum, user_datum_t **sepol_user) @@ -1129,7 +1124,7 @@ int cil_type_rule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c return __cil_type_rule_to_avtab(pdb, db, cil_rule, NULL, CIL_FALSE); } -int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans, cond_node_t *cond_node, enum cil_flavor cond_flavor, hashtab_t filename_trans_table) +int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans, cond_node_t *cond_node, enum cil_flavor cond_flavor) { int rc = SEPOL_ERR; type_datum_t *sepol_src = NULL; @@ -1179,7 +1174,6 @@ int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, stru if (rc != SEPOL_OK) goto exit; cil_list_for_each(c, class_list) { - int add = CIL_TRUE; rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj); if (rc != SEPOL_OK) goto exit; @@ -1191,11 +1185,13 @@ int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, stru newkey->name = cil_strdup(name); newdatum->otype = sepol_result->s.value; - rc = hashtab_insert(filename_trans_table, (hashtab_key_t)newkey, newdatum); + rc = hashtab_insert(pdb->filename_trans, + (hashtab_key_t)newkey, + newdatum); if (rc != SEPOL_OK) { if (rc == SEPOL_EEXIST) { - add = CIL_FALSE; - otype = hashtab_search(filename_trans_table, (hashtab_key_t)newkey); + otype = hashtab_search(pdb->filename_trans, + (hashtab_key_t)newkey); if (newdatum->otype != otype->otype) { cil_log(CIL_ERR, "Conflicting name type transition rules\n"); } else { @@ -1204,17 +1200,6 @@ int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *db, stru } else { cil_log(CIL_ERR, "Out of memory\n"); } - } - - if (add == CIL_TRUE) { - rc = hashtab_insert(pdb->filename_trans, - (hashtab_key_t)newkey, - newdatum); - if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Out of memory\n"); - goto exit; - } - } else { free(newkey->name); free(newkey); free(newdatum); @@ -1235,9 +1220,9 @@ exit: return rc; } -int cil_typetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans, hashtab_t filename_trans_table) +int cil_typetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans) { - return __cil_typetransition_to_avtab(pdb, db, typetrans, NULL, CIL_FALSE, filename_trans_table); + return __cil_typetransition_to_avtab(pdb, db, typetrans, NULL, CIL_FALSE); } int __perm_str_to_datum(char *perm_str, class_datum_t *sepol_class, uint32_t *datum) @@ -1925,7 +1910,6 @@ int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unu struct cil_type_rule *cil_type_rule; struct cil_avrule *cil_avrule; struct cil_nametypetransition *cil_typetrans; - hashtab_t filename_trans_table = args->filename_trans_table; flavor = node->flavor; switch (flavor) { @@ -1936,7 +1920,7 @@ int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unu cil_tree_log(node, CIL_ERR,"Invalid typetransition statement"); goto exit; } - rc = __cil_typetransition_to_avtab(pdb, db, cil_typetrans, cond_node, cond_flavor, filename_trans_table); + rc = __cil_typetransition_to_avtab(pdb, db, cil_typetrans, cond_node, cond_flavor); if (rc != SEPOL_OK) { cil_tree_log(node, CIL_ERR, "Failed to insert type transition into avtab"); goto exit; @@ -2205,7 +2189,7 @@ static int __cil_cond_expr_to_sepol_expr(policydb_t *pdb, struct cil_list *cil_e return SEPOL_OK; } -int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node, hashtab_t filename_trans_table) +int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node) { int rc = SEPOL_ERR; struct cil_args_booleanif bool_args; @@ -2280,7 +2264,6 @@ int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c bool_args.db = db; bool_args.pdb = pdb; bool_args.cond_node = cond_node; - bool_args.filename_trans_table = filename_trans_table; if (true_node != NULL) { bool_args.cond_flavor = CIL_CONDTRUE; @@ -3068,9 +3051,11 @@ int cil_sidorder_to_policydb(policydb_t *pdb, const struct cil_db *db) struct cil_sid *cil_sid = (struct cil_sid*)curr->data; struct cil_context *cil_context = cil_sid->context; + /* even if no context, we must preserve initial SID values */ + count++; + if (cil_context != NULL) { ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_ISID], &tail); - count++; new_ocon->sid[0] = count; new_ocon->u.name = cil_strdup(cil_sid->datum.fqn); rc = __cil_context_to_sepol_context(pdb, cil_context, &new_ocon->context[0]); @@ -3087,7 +3072,7 @@ exit: return rc; } -int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_rangetransition *rangetrans, hashtab_t range_trans_table) +int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_rangetransition *rangetrans) { int rc = SEPOL_ERR; type_datum_t *sepol_src = NULL; @@ -3119,7 +3104,6 @@ int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, st if (rc != SEPOL_OK) goto exit; cil_list_for_each(c, class_list) { - int add = CIL_TRUE; rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_class); if (rc != SEPOL_OK) goto exit; @@ -3135,11 +3119,10 @@ int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, st goto exit; } - rc = hashtab_insert(range_trans_table, (hashtab_key_t)newkey, newdatum); + rc = hashtab_insert(pdb->range_tr, (hashtab_key_t)newkey, newdatum); if (rc != SEPOL_OK) { if (rc == SEPOL_EEXIST) { - add = CIL_FALSE; - o_range = hashtab_search(range_trans_table, (hashtab_key_t)newkey); + o_range = hashtab_search(pdb->range_tr, (hashtab_key_t)newkey); if (!mls_range_eq(newdatum, o_range)) { cil_log(CIL_ERR, "Conflicting Range transition rules\n"); } else { @@ -3148,27 +3131,13 @@ int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, st } else { cil_log(CIL_ERR, "Out of memory\n"); } - } - - if (add == CIL_TRUE) { - rc = hashtab_insert(pdb->range_tr, - (hashtab_key_t)newkey, - newdatum); - if (rc != SEPOL_OK) { - mls_range_destroy(newdatum); - free(newdatum); - free(newkey); - cil_log(CIL_ERR, "Out of memory\n"); - goto exit; - } - } else { mls_range_destroy(newdatum); free(newdatum); free(newkey); if (rc != SEPOL_OK) { goto exit; } - } + } } } } @@ -3637,16 +3606,12 @@ int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args) struct cil_args_binary *args = extra_args; const struct cil_db *db; policydb_t *pdb; - hashtab_t filename_trans_table; - hashtab_t range_trans_table; hashtab_t role_trans_table; void **type_value_to_cil; db = args->db; pdb = args->pdb; pass = args->pass; - filename_trans_table = args->filename_trans_table; - range_trans_table = args->range_trans_table; role_trans_table = args->role_trans_table; type_value_to_cil = args->type_value_to_cil; @@ -3745,7 +3710,7 @@ int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args) /*rc = cil_roleattributeset_to_policydb(pdb, node->data);*/ break; case CIL_NAMETYPETRANSITION: - rc = cil_typetransition_to_policydb(pdb, db, node->data, filename_trans_table); + rc = cil_typetransition_to_policydb(pdb, db, node->data); break; case CIL_CONSTRAIN: rc = cil_constrain_to_policydb(pdb, db, node->data); @@ -3765,7 +3730,7 @@ int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args) break; case CIL_RANGETRANSITION: if (pdb->mls == CIL_TRUE) { - rc = cil_rangetransition_to_policydb(pdb, db, node->data, range_trans_table); + rc = cil_rangetransition_to_policydb(pdb, db, node->data); } break; case CIL_DEFAULTUSER: @@ -3783,7 +3748,7 @@ int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args) case 3: switch (node->flavor) { case CIL_BOOLEANIF: - rc = cil_booleanif_to_policydb(pdb, db, node, filename_trans_table); + rc = cil_booleanif_to_policydb(pdb, db, node); break; case CIL_AVRULE: { struct cil_avrule *rule = node->data; @@ -4191,40 +4156,6 @@ exit: return rc; } -static unsigned int filename_trans_hash(hashtab_t h, const_hashtab_key_t key) -{ - const filename_trans_t *k = (const filename_trans_t *)key; - return ((k->tclass + (k->ttype << 2) + - (k->stype << 9)) & (h->size - 1)); -} - -static int filename_trans_compare(hashtab_t h - __attribute__ ((unused)), const_hashtab_key_t key1, - const_hashtab_key_t key2) -{ - const filename_trans_t *a = (const filename_trans_t *)key1; - const filename_trans_t *b = (const filename_trans_t *)key2; - - return a->stype != b->stype || a->ttype != b->ttype || a->tclass != b->tclass || strcmp(a->name, b->name); -} - -static unsigned int range_trans_hash(hashtab_t h, const_hashtab_key_t key) -{ - const range_trans_t *k = (const range_trans_t *)key; - return ((k->target_class + (k->target_type << 2) + - (k->source_type << 5)) & (h->size - 1)); -} - -static int range_trans_compare(hashtab_t h - __attribute__ ((unused)), const_hashtab_key_t key1, - const_hashtab_key_t key2) -{ - const range_trans_t *a = (const range_trans_t *)key1; - const range_trans_t *b = (const range_trans_t *)key2; - - return a->source_type != b->source_type || a->target_type != b->target_type || a->target_class != b->target_class; -} - static unsigned int role_trans_hash(hashtab_t h, const_hashtab_key_t key) { const role_trans_t *k = (const role_trans_t *)key; @@ -4870,8 +4801,6 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p struct cil_args_binary extra_args; policydb_t *pdb = &policydb->p; struct cil_list *neverallows = NULL; - hashtab_t filename_trans_table = NULL; - hashtab_t range_trans_table = NULL; hashtab_t role_trans_table = NULL; hashtab_t avrulex_ioctl_table = NULL; void **type_value_to_cil = NULL; @@ -4909,18 +4838,6 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p goto exit; } - filename_trans_table = hashtab_create(filename_trans_hash, filename_trans_compare, FILENAME_TRANS_TABLE_SIZE); - if (!filename_trans_table) { - cil_log(CIL_INFO, "Failure to create hashtab for filename_trans\n"); - goto exit; - } - - range_trans_table = hashtab_create(range_trans_hash, range_trans_compare, RANGE_TRANS_TABLE_SIZE); - if (!range_trans_table) { - cil_log(CIL_INFO, "Failure to create hashtab for range_trans\n"); - goto exit; - } - role_trans_table = hashtab_create(role_trans_hash, role_trans_compare, ROLE_TRANS_TABLE_SIZE); if (!role_trans_table) { cil_log(CIL_INFO, "Failure to create hashtab for role_trans\n"); @@ -4938,8 +4855,6 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p extra_args.db = db; extra_args.pdb = pdb; extra_args.neverallows = neverallows; - extra_args.filename_trans_table = filename_trans_table; - extra_args.range_trans_table = range_trans_table; extra_args.role_trans_table = role_trans_table; extra_args.avrulex_ioctl_table = avrulex_ioctl_table; extra_args.type_value_to_cil = type_value_to_cil; @@ -5037,8 +4952,6 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p rc = SEPOL_OK; exit: - hashtab_destroy(filename_trans_table); - hashtab_destroy(range_trans_table); hashtab_destroy(role_trans_table); hashtab_destroy(avrulex_ioctl_table); free(type_value_to_cil); diff --git a/libsepol/cil/src/cil_binary.h b/libsepol/cil/src/cil_binary.h index 1004df45..0b6e3b79 100644 --- a/libsepol/cil/src/cil_binary.h +++ b/libsepol/cil/src/cil_binary.h @@ -263,7 +263,7 @@ int cil_avrule_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_ * * @return SEPOL_OK upon success or an error otherwise. */ -int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node, hashtab_t filename_trans_table); +int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_tree_node *node); /** * Insert cil role transition structure into sepol policydb. @@ -293,7 +293,7 @@ int cil_roleallow_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c * * @return SEPOL_OK upon success or SEPOL_ERR upon error. */ -int cil_typetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans, hashtab_t filename_trans_table); +int cil_typetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_nametypetransition *typetrans); /** * Insert cil constrain/mlsconstrain structure(s) into sepol policydb. @@ -327,7 +327,7 @@ int cil_sepol_level_define(policydb_t *pdb, struct cil_sens *cil_sens); * * @return SEPOL_OK upon success or an error otherwise. */ -int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_rangetransition *rangetrans, hashtab_t range_trans_table); +int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_rangetransition *rangetrans); /** * Insert cil ibpkeycon structure into sepol policydb. diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c index 018514dc..c73bbeee 100644 --- a/libsepol/cil/src/cil_verify.c +++ b/libsepol/cil/src/cil_verify.c @@ -439,8 +439,7 @@ int __cil_verify_initsids(struct cil_list *sids) struct cil_sid *sid = i->data; if (sid->context == NULL) { struct cil_tree_node *node = sid->datum.nodes->head->data; - cil_tree_log(node, CIL_ERR, "No context assigned to SID %s declared",sid->datum.name); - rc = SEPOL_ERR; + cil_tree_log(node, CIL_INFO, "No context assigned to SID %s, omitting from policy",sid->datum.name); } } @@ -1545,25 +1544,49 @@ exit: return rc; } -static int __cil_verify_classperms(struct cil_list *classperms, struct cil_symtab_datum *orig) +static int __cil_verify_classperms(struct cil_list *classperms, + struct cil_symtab_datum *orig, + struct cil_symtab_datum *parent, + struct cil_symtab_datum *cur, + enum cil_flavor flavor, + unsigned steps, unsigned limit) { int rc = SEPOL_ERR; struct cil_list_item *curr; + if (classperms == NULL) { + if (flavor == CIL_MAP_PERM) { + cil_tree_log(NODE(cur), CIL_ERR, "Map class %s does not have a classmapping for %s", parent->name, cur->name); + } else { + cil_tree_log(NODE(cur), CIL_ERR, "Classpermission %s does not have a classpermissionset", cur->name); + } + goto exit; + } + + if (steps > 0 && orig == cur) { + if (flavor == CIL_MAP_PERM) { + cil_tree_log(NODE(cur), CIL_ERR, "Found circular class permissions involving the map class %s and permission %s", parent->name, cur->name); + } else { + cil_tree_log(NODE(cur), CIL_ERR, "Found circular class permissions involving the set %s", cur->name); + } + goto exit; + } else { + steps++; + if (steps > limit) { + steps = 1; + limit *= 2; + orig = cur; + } + } + cil_list_for_each(curr, classperms) { if (curr->flavor == CIL_CLASSPERMS) { struct cil_classperms *cp = curr->data; - if (FLAVOR(cp->class) == CIL_CLASS) { - return SEPOL_OK; - } else { /* MAP */ + if (FLAVOR(cp->class) != CIL_CLASS) { /* MAP */ struct cil_list_item *i = NULL; cil_list_for_each(i, cp->perms) { struct cil_perm *cmp = i->data; - if (&cmp->datum == orig) { - rc = SEPOL_ERR; - goto exit; - } - rc = __cil_verify_classperms(cmp->classperms, orig); + rc = __cil_verify_classperms(cmp->classperms, orig, &cp->class->datum, &cmp->datum, CIL_MAP_PERM, steps, limit); if (rc != SEPOL_OK) { goto exit; } @@ -1572,11 +1595,7 @@ static int __cil_verify_classperms(struct cil_list *classperms, struct cil_symta } else { /* SET */ struct cil_classperms_set *cp_set = curr->data; struct cil_classpermission *cp = cp_set->set; - if (&cp->datum == orig) { - rc = SEPOL_ERR; - goto exit; - } - rc = __cil_verify_classperms(cp->classperms, orig); + rc = __cil_verify_classperms(cp->classperms, orig, NULL, &cp->datum, CIL_CLASSPERMISSION, steps, limit); if (rc != SEPOL_OK) { goto exit; } @@ -1586,30 +1605,14 @@ static int __cil_verify_classperms(struct cil_list *classperms, struct cil_symta return SEPOL_OK; exit: - return rc; + return SEPOL_ERR; } static int __cil_verify_classpermission(struct cil_tree_node *node) { - int rc = SEPOL_ERR; struct cil_classpermission *cp = node->data; - if (cp->classperms == NULL) { - cil_tree_log(node, CIL_ERR, "Classpermission %s does not have a classpermissionset", cp->datum.name); - rc = SEPOL_ERR; - goto exit; - } - - rc = __cil_verify_classperms(cp->classperms, &cp->datum); - if (rc != SEPOL_OK) { - cil_tree_log(node, CIL_ERR, "Found circular class permissions involving the set %s",cp->datum.name); - goto exit; - } - - rc = SEPOL_OK; - -exit: - return rc; + return __cil_verify_classperms(cp->classperms, &cp->datum, NULL, &cp->datum, CIL_CLASSPERMISSION, 0, 2); } struct cil_verify_map_args { @@ -1620,24 +1623,11 @@ struct cil_verify_map_args { static int __verify_map_perm_classperms(__attribute__((unused)) hashtab_key_t k, hashtab_datum_t d, void *args) { - int rc = SEPOL_ERR; struct cil_verify_map_args *map_args = args; struct cil_perm *cmp = (struct cil_perm *)d; - if (cmp->classperms == NULL) { - cil_tree_log(map_args->node, CIL_ERR, "Map class %s does not have a classmapping for %s", map_args->class->datum.name, cmp->datum.name); - map_args->rc = SEPOL_ERR; - goto exit; - } - - rc = __cil_verify_classperms(cmp->classperms, &cmp->datum); - if (rc != SEPOL_OK) { - cil_tree_log(map_args->node, CIL_ERR, "Found circular class permissions involving the map class %s and permission %s", map_args->class->datum.name, cmp->datum.name); - map_args->rc = SEPOL_ERR; - goto exit; - } + map_args->rc = __cil_verify_classperms(cmp->classperms, &cmp->datum, &map_args->class->datum, &cmp->datum, CIL_MAP_PERM, 0, 2); -exit: return SEPOL_OK; } diff --git a/libsepol/include/sepol/policydb/polcaps.h b/libsepol/include/sepol/policydb/polcaps.h index dc9356a6..40669fb5 100644 --- a/libsepol/include/sepol/policydb/polcaps.h +++ b/libsepol/include/sepol/policydb/polcaps.h @@ -13,6 +13,7 @@ enum { POLICYDB_CAPABILITY_ALWAYSNETWORK, POLICYDB_CAPABILITY_CGROUPSECLABEL, POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION, + POLICYDB_CAPABILITY_GENFS_SECLABEL_SYMLINKS, __POLICYDB_CAPABILITY_MAX }; #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c index 796121cf..5738b598 100644 --- a/libsepol/src/expand.c +++ b/libsepol/src/expand.c @@ -2093,6 +2093,12 @@ static int ocontext_copy_xen(expand_state_t *state) for (i = 0; i < OCON_NUM; i++) { l = NULL; for (c = state->base->ocontexts[i]; c; c = c->next) { + if (i == OCON_XEN_ISID && !c->context[0].user) { + INFO(state->handle, + "No context assigned to SID %s, omitting from policy", + c->u.name); + continue; + } n = malloc(sizeof(ocontext_t)); if (!n) { ERR(state->handle, "Out of memory!"); @@ -2106,12 +2112,6 @@ static int ocontext_copy_xen(expand_state_t *state) l = n; switch (i) { case OCON_XEN_ISID: - if (c->context[0].user == 0) { - ERR(state->handle, - "Missing context for %s initial sid", - c->u.name); - return -1; - } n->sid[0] = c->sid[0]; break; case OCON_XEN_PIRQ: @@ -2159,6 +2159,12 @@ static int ocontext_copy_selinux(expand_state_t *state) for (i = 0; i < OCON_NUM; i++) { l = NULL; for (c = state->base->ocontexts[i]; c; c = c->next) { + if (i == OCON_ISID && !c->context[0].user) { + INFO(state->handle, + "No context assigned to SID %s, omitting from policy", + c->u.name); + continue; + } n = malloc(sizeof(ocontext_t)); if (!n) { ERR(state->handle, "Out of memory!"); @@ -2172,12 +2178,6 @@ static int ocontext_copy_selinux(expand_state_t *state) l = n; switch (i) { case OCON_ISID: - if (c->context[0].user == 0) { - ERR(state->handle, - "Missing context for %s initial sid", - c->u.name); - return -1; - } n->sid[0] = c->sid[0]; break; case OCON_FS: /* FALLTHROUGH */ diff --git a/libsepol/src/polcaps.c b/libsepol/src/polcaps.c index b9dc3526..67ed5786 100644 --- a/libsepol/src/polcaps.c +++ b/libsepol/src/polcaps.c @@ -12,6 +12,7 @@ static const char *polcap_names[] = { "always_check_network", /* POLICYDB_CAPABILITY_ALWAYSNETWORK */ "cgroup_seclabel", /* POLICYDB_CAPABILITY_SECLABEL */ "nnp_nosuid_transition", /* POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION */ + "genfs_seclabel_symlinks", /* POLICYDB_CAPABILITY_GENFS_SECLABEL_SYMLINKS */ NULL }; diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c index 67037b6d..2c69a609 100644 --- a/libsepol/src/policydb.c +++ b/libsepol/src/policydb.c @@ -1611,10 +1611,6 @@ int policydb_load_isids(policydb_t * p, sidtab_t * s) head = p->ocontexts[OCON_ISID]; for (c = head; c; c = c->next) { - if (!c->context[0].user) { - ERR(NULL, "SID %s was never defined", c->u.name); - return -1; - } if (sepol_sidtab_insert(s, c->sid[0], &c->context[0])) { ERR(NULL, "unable to load initial SID %s", c->u.name); return -1; diff --git a/libsepol/src/write.c b/libsepol/src/write.c index b9890b4c..65aba32a 100644 --- a/libsepol/src/write.c +++ b/libsepol/src/write.c @@ -1294,8 +1294,15 @@ static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p, ocontext_t *c; for (i = 0; i < info->ocon_num; i++) { nel = 0; - for (c = p->ocontexts[i]; c; c = c->next) + for (c = p->ocontexts[i]; c; c = c->next) { + if (i == OCON_XEN_ISID && !c->context[0].user) { + INFO(fp->handle, + "No context assigned to SID %s, omitting from policy", + c->u.name); + continue; + } nel++; + } buf[0] = cpu_to_le32(nel); items = put_entry(buf, sizeof(uint32_t), 1, fp); if (items != 1) @@ -1303,6 +1310,8 @@ static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p, for (c = p->ocontexts[i]; c; c = c->next) { switch (i) { case OCON_XEN_ISID: + if (!c->context[0].user) + break; buf[0] = cpu_to_le32(c->sid[0]); items = put_entry(buf, sizeof(uint32_t), 1, fp); if (items != 1) @@ -1393,8 +1402,15 @@ static int ocontext_write_selinux(struct policydb_compat_info *info, ocontext_t *c; for (i = 0; i < info->ocon_num; i++) { nel = 0; - for (c = p->ocontexts[i]; c; c = c->next) + for (c = p->ocontexts[i]; c; c = c->next) { + if (i == OCON_ISID && !c->context[0].user) { + INFO(fp->handle, + "No context assigned to SID %s, omitting from policy", + c->u.name); + continue; + } nel++; + } buf[0] = cpu_to_le32(nel); items = put_entry(buf, sizeof(uint32_t), 1, fp); if (items != 1) @@ -1402,6 +1418,8 @@ static int ocontext_write_selinux(struct policydb_compat_info *info, for (c = p->ocontexts[i]; c; c = c->next) { switch (i) { case OCON_ISID: + if (!c->context[0].user) + break; buf[0] = cpu_to_le32(c->sid[0]); items = put_entry(buf, sizeof(uint32_t), 1, fp); if (items != 1) |