diff --git a/libsepol-fedora.patch b/libsepol-fedora.patch index 23df58b..c5f587a 100644 --- a/libsepol-fedora.patch +++ b/libsepol-fedora.patch @@ -19,10 +19,24 @@ index a43b343..6d89f17 100644 $(LOCAL_PATH)/include/ \ $(LOCAL_PATH)/src/ \ diff --git libsepol-2.5/ChangeLog libsepol-2.5/ChangeLog -index ace3d54..b45f3ad 100644 +index ace3d54..1e35c49 100644 --- libsepol-2.5/ChangeLog +++ libsepol-2.5/ChangeLog -@@ -1,3 +1,23 @@ +@@ -1,3 +1,37 @@ ++ * Check for too many permissions in classes and commons in CIL, from James Carter. ++ * Fix xperm mapping between avrule and avtab, from Jeff Vander Stoep. ++ * tests: Fix mispelling of optimization option, from Nicolas Iooss. ++ * Fix unused/uninitialized variables on mac build, from William Roberts. ++ * Produce more meaningful error messages for conflicting type rules in CIL, from Guido Trentalancia. ++ * make "make test" fail when a CUnit test fails, from Nicolas Iooss. ++ * tests: fix g_b_role_2 test, from Nicolas Iooss. ++ * Change which attributes CIL keeps in the binary policy, from James Carter. ++ * Port str_read() from kernel and remove multiple occurances of similar code, from William Roberts. ++ * Use calloc instead of malloc for all the *_to_val_structs, from William Roberts. ++ * Fix bugs found by AFL, from William Roberts. ++ * Fix memory leak in expand.c, from William Roberts. ++ * Fix invalid read when policy file is corrupt, from William Roberts. ++ * Fix possible use of uninitialized variables, from William Roberts. + * Warn instead of fail if permission is not resolved, from James Carter. + * Ignore object_r when adding userrole mappings to policydb, from Steve Lawrence. + * Add missing return to sepol_node_query(), from Petr Lautrbach. @@ -120,7 +134,7 @@ index afdc240..929ab19 100644 + (*info)->path = NULL; +} diff --git libsepol-2.5/cil/src/cil_binary.c libsepol-2.5/cil/src/cil_binary.c -index f749e53..46fea4b 100644 +index f749e53..cc73648 100644 --- libsepol-2.5/cil/src/cil_binary.c +++ libsepol-2.5/cil/src/cil_binary.c @@ -31,6 +31,9 @@ @@ -161,6 +175,42 @@ index f749e53..46fea4b 100644 if (ebitmap_set_bit(&sepol_user->roles.roles, sepol_role->s.value - 1, 1)) { cil_log(CIL_INFO, "Failed to set role bit for user\n"); rc = SEPOL_ERR; +@@ -973,7 +984,7 @@ avtab_datum_t *cil_cond_av_list_search(avtab_key_t *key, cond_av_list_t *cond_li + return NULL; + } + +-int __cil_insert_type_rule(policydb_t *pdb, uint32_t kind, uint32_t src, uint32_t tgt, uint32_t obj, uint32_t res, cond_node_t *cond_node, enum cil_flavor cond_flavor) ++int __cil_insert_type_rule(policydb_t *pdb, uint32_t kind, uint32_t src, uint32_t tgt, uint32_t obj, uint32_t res, struct cil_type_rule *cil_rule, cond_node_t *cond_node, enum cil_flavor cond_flavor) + { + int rc = SEPOL_OK; + avtab_key_t avtab_key; +@@ -1008,7 +1019,7 @@ int __cil_insert_type_rule(policydb_t *pdb, uint32_t kind, uint32_t src, uint32_ + * non-duplicate rule using the same key. + */ + if (existing->datum.data != res) { +- cil_log(CIL_ERR, "Conflicting type rules\n"); ++ cil_log(CIL_ERR, "Conflicting type rules (scontext=%s tcontext=%s tclass=%s result=%s)\n", cil_rule->src_str, cil_rule->tgt_str, cil_rule->obj_str, cil_rule->result_str); + rc = SEPOL_ERR; + } + goto exit; +@@ -1034,7 +1045,7 @@ int __cil_insert_type_rule(policydb_t *pdb, uint32_t kind, uint32_t src, uint32_ + search_datum = cil_cond_av_list_search(&avtab_key, other_list); + if (search_datum == NULL) { + if (existing->datum.data != res) { +- cil_log(CIL_ERR, "Conflicting type rules\n"); ++ cil_log(CIL_ERR, "Conflicting type rules (scontext=%s tcontext=%s tclass=%s result=%s)\n", cil_rule->src_str, cil_rule->tgt_str, cil_rule->obj_str, cil_rule->result_str); + rc = SEPOL_ERR; + goto exit; + } +@@ -1093,7 +1104,7 @@ int __cil_type_rule_to_avtab(policydb_t *pdb, const struct cil_db *db, struct ci + rc = __cil_get_sepol_class_datum(pdb, DATUM(c->data), &sepol_obj); + if (rc != SEPOL_OK) goto exit; + +- rc = __cil_insert_type_rule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, sepol_result->s.value, cond_node, cond_flavor); ++ rc = __cil_insert_type_rule(pdb, kind, sepol_src->s.value, sepol_tgt->s.value, sepol_obj->s.value, sepol_result->s.value, cil_rule, cond_node, cond_flavor); + if (rc != SEPOL_OK) goto exit; + } + } @@ -1770,13 +1781,12 @@ int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unu cil_typetrans = (struct cil_nametypetransition*)node->data; if (DATUM(cil_typetrans->name)->fqn != CIL_KEY_STAR) { @@ -488,7 +538,7 @@ index f749e53..46fea4b 100644 rc = SEPOL_OK; diff --git libsepol-2.5/cil/src/cil_build_ast.c libsepol-2.5/cil/src/cil_build_ast.c -index 1135e06..1505873 100644 +index 1135e06..a96c2a9 100644 --- libsepol-2.5/cil/src/cil_build_ast.c +++ libsepol-2.5/cil/src/cil_build_ast.c @@ -108,8 +108,7 @@ int cil_gen_node(__attribute__((unused)) struct cil_db *db, struct cil_tree_node @@ -541,7 +591,17 @@ index 1135e06..1505873 100644 cil_destroy_in(in); return rc; } -@@ -387,8 +382,7 @@ int cil_gen_class(struct cil_db *db, struct cil_tree_node *parse_current, struct +@@ -382,13 +377,17 @@ int cil_gen_class(struct cil_db *db, struct cil_tree_node *parse_current, struct + if (rc != SEPOL_OK) { + goto exit; + } ++ if (class->num_perms > CIL_PERMS_PER_CLASS) { ++ cil_tree_log(parse_current, CIL_ERR, "Too many permissions in class '%s'", class->datum.name); ++ goto exit; ++ } ++ + } + return SEPOL_OK; exit: @@ -551,7 +611,7 @@ index 1135e06..1505873 100644 cil_destroy_class(class); cil_clear_node(ast_node); return rc; -@@ -456,8 +450,7 @@ int cil_gen_classorder(struct cil_db *db, struct cil_tree_node *parse_current, s +@@ -456,8 +455,7 @@ int cil_gen_classorder(struct cil_db *db, struct cil_tree_node *parse_current, s return SEPOL_OK; exit: @@ -561,7 +621,7 @@ index 1135e06..1505873 100644 cil_destroy_classorder(classorder); return rc; } -@@ -527,7 +520,7 @@ int cil_gen_perm_nodes(struct cil_db *db, struct cil_tree_node *current_perm, st +@@ -527,7 +525,7 @@ int cil_gen_perm_nodes(struct cil_db *db, struct cil_tree_node *current_perm, st cil_tree_node_init(&new_ast); new_ast->parent = ast_node; new_ast->line = current_perm->line; @@ -570,7 +630,7 @@ index 1135e06..1505873 100644 rc = cil_gen_perm(db, current_perm, new_ast, flavor, num_perms); if (rc != SEPOL_OK) { -@@ -738,8 +731,7 @@ int cil_gen_classpermission(struct cil_db *db, struct cil_tree_node *parse_curre +@@ -738,8 +736,7 @@ int cil_gen_classpermission(struct cil_db *db, struct cil_tree_node *parse_curre return SEPOL_OK; exit: @@ -580,7 +640,7 @@ index 1135e06..1505873 100644 cil_destroy_classpermission(cp); cil_clear_node(ast_node); return rc; -@@ -800,8 +792,7 @@ int cil_gen_classpermissionset(struct cil_db *db, struct cil_tree_node *parse_cu +@@ -800,8 +797,7 @@ int cil_gen_classpermissionset(struct cil_db *db, struct cil_tree_node *parse_cu return SEPOL_OK; exit: @@ -590,7 +650,7 @@ index 1135e06..1505873 100644 cil_destroy_classpermissionset(cps); return rc; } -@@ -852,8 +843,7 @@ int cil_gen_map_class(struct cil_db *db, struct cil_tree_node *parse_current, st +@@ -852,8 +848,7 @@ int cil_gen_map_class(struct cil_db *db, struct cil_tree_node *parse_current, st return SEPOL_OK; exit: @@ -600,7 +660,7 @@ index 1135e06..1505873 100644 cil_destroy_class(map); cil_clear_node(ast_node); return rc; -@@ -897,8 +887,7 @@ int cil_gen_classmapping(struct cil_db *db, struct cil_tree_node *parse_current, +@@ -897,8 +892,7 @@ int cil_gen_classmapping(struct cil_db *db, struct cil_tree_node *parse_current, return SEPOL_OK; exit: @@ -610,7 +670,15 @@ index 1135e06..1505873 100644 cil_destroy_classmapping(mapping); return rc; } -@@ -954,8 +943,7 @@ int cil_gen_common(struct cil_db *db, struct cil_tree_node *parse_current, struc +@@ -950,12 +944,15 @@ int cil_gen_common(struct cil_db *db, struct cil_tree_node *parse_current, struc + if (rc != SEPOL_OK) { + goto exit; + } ++ if (common->num_perms > CIL_PERMS_PER_CLASS) { ++ cil_tree_log(parse_current, CIL_ERR, "Too many permissions in common '%s'", common->datum.name); ++ goto exit; ++ } + return SEPOL_OK; exit: @@ -620,7 +688,7 @@ index 1135e06..1505873 100644 cil_destroy_class(common); cil_clear_node(ast_node); return rc; -@@ -994,8 +982,7 @@ int cil_gen_classcommon(struct cil_db *db, struct cil_tree_node *parse_current, +@@ -994,8 +991,7 @@ int cil_gen_classcommon(struct cil_db *db, struct cil_tree_node *parse_current, return SEPOL_OK; exit: @@ -630,7 +698,7 @@ index 1135e06..1505873 100644 cil_destroy_classcommon(clscom); return rc; -@@ -1043,8 +1030,7 @@ int cil_gen_sid(struct cil_db *db, struct cil_tree_node *parse_current, struct c +@@ -1043,8 +1039,7 @@ int cil_gen_sid(struct cil_db *db, struct cil_tree_node *parse_current, struct c return SEPOL_OK; exit: @@ -640,7 +708,7 @@ index 1135e06..1505873 100644 cil_destroy_sid(sid); cil_clear_node(ast_node); return rc; -@@ -1102,8 +1088,7 @@ int cil_gen_sidcontext(struct cil_db *db, struct cil_tree_node *parse_current, s +@@ -1102,8 +1097,7 @@ int cil_gen_sidcontext(struct cil_db *db, struct cil_tree_node *parse_current, s return SEPOL_OK; exit: @@ -650,7 +718,7 @@ index 1135e06..1505873 100644 cil_destroy_sidcontext(sidcon); return rc; } -@@ -1163,8 +1148,7 @@ int cil_gen_sidorder(struct cil_db *db, struct cil_tree_node *parse_current, str +@@ -1163,8 +1157,7 @@ int cil_gen_sidorder(struct cil_db *db, struct cil_tree_node *parse_current, str return SEPOL_OK; exit: @@ -660,7 +728,7 @@ index 1135e06..1505873 100644 cil_destroy_sidorder(sidorder); return rc; } -@@ -1215,8 +1199,7 @@ int cil_gen_user(struct cil_db *db, struct cil_tree_node *parse_current, struct +@@ -1215,8 +1208,7 @@ int cil_gen_user(struct cil_db *db, struct cil_tree_node *parse_current, struct return SEPOL_OK; exit: @@ -670,7 +738,7 @@ index 1135e06..1505873 100644 cil_destroy_user(user); cil_clear_node(ast_node); return rc; -@@ -1265,8 +1248,7 @@ int cil_gen_userattribute(struct cil_db *db, struct cil_tree_node *parse_current +@@ -1265,8 +1257,7 @@ int cil_gen_userattribute(struct cil_db *db, struct cil_tree_node *parse_current return SEPOL_OK; exit: @@ -680,7 +748,7 @@ index 1135e06..1505873 100644 cil_destroy_userattribute(attr); cil_clear_node(ast_node); return rc; -@@ -1336,8 +1318,7 @@ int cil_gen_userattributeset(struct cil_db *db, struct cil_tree_node *parse_curr +@@ -1336,8 +1327,7 @@ int cil_gen_userattributeset(struct cil_db *db, struct cil_tree_node *parse_curr return SEPOL_OK; exit: @@ -690,7 +758,7 @@ index 1135e06..1505873 100644 cil_destroy_userattributeset(attrset); return rc; -@@ -1397,8 +1378,7 @@ int cil_gen_userlevel(struct cil_db *db, struct cil_tree_node *parse_current, st +@@ -1397,8 +1387,7 @@ int cil_gen_userlevel(struct cil_db *db, struct cil_tree_node *parse_current, st return SEPOL_OK; exit: @@ -700,7 +768,7 @@ index 1135e06..1505873 100644 cil_destroy_userlevel(usrlvl); return rc; } -@@ -1458,8 +1438,7 @@ int cil_gen_userrange(struct cil_db *db, struct cil_tree_node *parse_current, st +@@ -1458,8 +1447,7 @@ int cil_gen_userrange(struct cil_db *db, struct cil_tree_node *parse_current, st return SEPOL_OK; exit: @@ -710,7 +778,7 @@ index 1135e06..1505873 100644 cil_destroy_userrange(userrange); return rc; } -@@ -1508,8 +1487,7 @@ int cil_gen_userprefix(struct cil_db *db, struct cil_tree_node *parse_current, s +@@ -1508,8 +1496,7 @@ int cil_gen_userprefix(struct cil_db *db, struct cil_tree_node *parse_current, s return SEPOL_OK; exit: @@ -720,7 +788,7 @@ index 1135e06..1505873 100644 cil_destroy_userprefix(userprefix); return rc; } -@@ -1566,8 +1544,7 @@ int cil_gen_selinuxuser(struct cil_db *db, struct cil_tree_node *parse_current, +@@ -1566,8 +1553,7 @@ int cil_gen_selinuxuser(struct cil_db *db, struct cil_tree_node *parse_current, return SEPOL_OK; exit: @@ -730,7 +798,7 @@ index 1135e06..1505873 100644 cil_destroy_selinuxuser(selinuxuser); return rc; } -@@ -1614,8 +1591,7 @@ int cil_gen_selinuxuserdefault(struct cil_db *db, struct cil_tree_node *parse_cu +@@ -1614,8 +1600,7 @@ int cil_gen_selinuxuserdefault(struct cil_db *db, struct cil_tree_node *parse_cu return SEPOL_OK; exit: @@ -740,7 +808,7 @@ index 1135e06..1505873 100644 cil_destroy_selinuxuser(selinuxuser); return rc; } -@@ -1666,8 +1642,7 @@ int cil_gen_role(struct cil_db *db, struct cil_tree_node *parse_current, struct +@@ -1666,8 +1651,7 @@ int cil_gen_role(struct cil_db *db, struct cil_tree_node *parse_current, struct return SEPOL_OK; exit: @@ -750,7 +818,7 @@ index 1135e06..1505873 100644 cil_destroy_role(role); cil_clear_node(ast_node); return rc; -@@ -1717,8 +1692,7 @@ int cil_gen_roletype(struct cil_db *db, struct cil_tree_node *parse_current, str +@@ -1717,8 +1701,7 @@ int cil_gen_roletype(struct cil_db *db, struct cil_tree_node *parse_current, str return SEPOL_OK; exit: @@ -760,7 +828,7 @@ index 1135e06..1505873 100644 cil_destroy_roletype(roletype); return rc; } -@@ -1764,8 +1738,7 @@ int cil_gen_userrole(struct cil_db *db, struct cil_tree_node *parse_current, str +@@ -1764,8 +1747,7 @@ int cil_gen_userrole(struct cil_db *db, struct cil_tree_node *parse_current, str return SEPOL_OK; exit: @@ -770,7 +838,7 @@ index 1135e06..1505873 100644 cil_destroy_userrole(userrole); return rc; } -@@ -1815,8 +1788,7 @@ int cil_gen_roletransition(struct cil_tree_node *parse_current, struct cil_tree_ +@@ -1815,8 +1797,7 @@ int cil_gen_roletransition(struct cil_tree_node *parse_current, struct cil_tree_ return SEPOL_OK; exit: @@ -780,7 +848,7 @@ index 1135e06..1505873 100644 cil_destroy_roletransition(roletrans); return rc; } -@@ -1862,8 +1834,7 @@ int cil_gen_roleallow(struct cil_db *db, struct cil_tree_node *parse_current, st +@@ -1862,8 +1843,7 @@ int cil_gen_roleallow(struct cil_db *db, struct cil_tree_node *parse_current, st return SEPOL_OK; exit: @@ -790,7 +858,7 @@ index 1135e06..1505873 100644 cil_destroy_roleallow(roleallow); return rc; } -@@ -1914,8 +1885,7 @@ int cil_gen_roleattribute(struct cil_db *db, struct cil_tree_node *parse_current +@@ -1914,8 +1894,7 @@ int cil_gen_roleattribute(struct cil_db *db, struct cil_tree_node *parse_current return SEPOL_OK; exit: @@ -800,7 +868,7 @@ index 1135e06..1505873 100644 cil_destroy_roleattribute(attr); cil_clear_node(ast_node); return rc; -@@ -1982,8 +1952,7 @@ int cil_gen_roleattributeset(struct cil_db *db, struct cil_tree_node *parse_curr +@@ -1982,8 +1961,7 @@ int cil_gen_roleattributeset(struct cil_db *db, struct cil_tree_node *parse_curr return SEPOL_OK; exit: @@ -810,7 +878,7 @@ index 1135e06..1505873 100644 cil_destroy_roleattributeset(attrset); return rc; -@@ -2042,8 +2011,7 @@ int cil_gen_avrule(struct cil_tree_node *parse_current, struct cil_tree_node *as +@@ -2042,8 +2020,7 @@ int cil_gen_avrule(struct cil_tree_node *parse_current, struct cil_tree_node *as return SEPOL_OK; exit: @@ -820,7 +888,7 @@ index 1135e06..1505873 100644 cil_destroy_avrule(rule); return rc; } -@@ -2099,8 +2067,7 @@ int cil_fill_permissionx(struct cil_tree_node *parse_current, struct cil_permiss +@@ -2099,8 +2076,7 @@ int cil_fill_permissionx(struct cil_tree_node *parse_current, struct cil_permiss return SEPOL_OK; exit: @@ -830,7 +898,7 @@ index 1135e06..1505873 100644 return rc; } -@@ -2143,8 +2110,7 @@ int cil_gen_permissionx(struct cil_db *db, struct cil_tree_node *parse_current, +@@ -2143,8 +2119,7 @@ int cil_gen_permissionx(struct cil_db *db, struct cil_tree_node *parse_current, return SEPOL_OK; exit: @@ -840,7 +908,7 @@ index 1135e06..1505873 100644 cil_destroy_permissionx(permx); cil_clear_node(ast_node); return rc; -@@ -2210,8 +2176,7 @@ int cil_gen_avrulex(struct cil_tree_node *parse_current, struct cil_tree_node *a +@@ -2210,8 +2185,7 @@ int cil_gen_avrulex(struct cil_tree_node *parse_current, struct cil_tree_node *a return SEPOL_OK; exit: @@ -850,7 +918,7 @@ index 1135e06..1505873 100644 cil_destroy_avrule(rule); return rc; } -@@ -2253,8 +2218,7 @@ int cil_gen_type_rule(struct cil_tree_node *parse_current, struct cil_tree_node +@@ -2253,8 +2227,7 @@ int cil_gen_type_rule(struct cil_tree_node *parse_current, struct cil_tree_node return SEPOL_OK; exit: @@ -860,7 +928,7 @@ index 1135e06..1505873 100644 cil_destroy_type_rule(rule); return rc; } -@@ -2306,8 +2270,7 @@ int cil_gen_type(struct cil_db *db, struct cil_tree_node *parse_current, struct +@@ -2306,8 +2279,7 @@ int cil_gen_type(struct cil_db *db, struct cil_tree_node *parse_current, struct return SEPOL_OK; exit: @@ -870,7 +938,7 @@ index 1135e06..1505873 100644 cil_destroy_type(type); cil_clear_node(ast_node); return rc; -@@ -2361,8 +2324,7 @@ int cil_gen_typeattribute(struct cil_db *db, struct cil_tree_node *parse_current +@@ -2361,8 +2333,7 @@ int cil_gen_typeattribute(struct cil_db *db, struct cil_tree_node *parse_current return SEPOL_OK; exit: @@ -880,7 +948,7 @@ index 1135e06..1505873 100644 cil_destroy_typeattribute(attr); cil_clear_node(ast_node); return rc; -@@ -2439,11 +2401,9 @@ int cil_gen_bool(struct cil_db *db, struct cil_tree_node *parse_current, struct +@@ -2439,11 +2410,9 @@ int cil_gen_bool(struct cil_db *db, struct cil_tree_node *parse_current, struct exit: if (tunableif) { @@ -894,7 +962,7 @@ index 1135e06..1505873 100644 } cil_destroy_bool(boolean); cil_clear_node(ast_node); -@@ -2504,8 +2464,7 @@ int cil_gen_tunable(struct cil_db *db, struct cil_tree_node *parse_current, stru +@@ -2504,8 +2473,7 @@ int cil_gen_tunable(struct cil_db *db, struct cil_tree_node *parse_current, stru return SEPOL_OK; exit: @@ -904,7 +972,7 @@ index 1135e06..1505873 100644 cil_destroy_tunable(tunable); cil_clear_node(ast_node); return rc; -@@ -2880,11 +2839,9 @@ int cil_gen_boolif(struct cil_db *db, struct cil_tree_node *parse_current, struc +@@ -2880,11 +2848,9 @@ int cil_gen_boolif(struct cil_db *db, struct cil_tree_node *parse_current, struc exit: if (tunableif) { @@ -918,7 +986,7 @@ index 1135e06..1505873 100644 } cil_destroy_boolif(bif); return rc; -@@ -2964,8 +2921,7 @@ int cil_gen_tunif(struct cil_db *db, struct cil_tree_node *parse_current, struct +@@ -2964,8 +2930,7 @@ int cil_gen_tunif(struct cil_db *db, struct cil_tree_node *parse_current, struct return SEPOL_OK; exit: @@ -928,7 +996,7 @@ index 1135e06..1505873 100644 cil_destroy_tunif(tif); return rc; } -@@ -3018,8 +2974,8 @@ int cil_gen_condblock(struct cil_db *db, struct cil_tree_node *parse_current, st +@@ -3018,8 +2983,8 @@ int cil_gen_condblock(struct cil_db *db, struct cil_tree_node *parse_current, st return SEPOL_OK; exit: @@ -939,7 +1007,7 @@ index 1135e06..1505873 100644 cil_destroy_condblock(cb); return rc; } -@@ -3079,8 +3035,7 @@ int cil_gen_alias(struct cil_db *db, struct cil_tree_node *parse_current, struct +@@ -3079,8 +3044,7 @@ int cil_gen_alias(struct cil_db *db, struct cil_tree_node *parse_current, struct return SEPOL_OK; exit: @@ -949,7 +1017,7 @@ index 1135e06..1505873 100644 cil_destroy_alias(alias); cil_clear_node(ast_node); return rc; -@@ -3137,8 +3092,7 @@ int cil_gen_aliasactual(struct cil_db *db, struct cil_tree_node *parse_current, +@@ -3137,8 +3101,7 @@ int cil_gen_aliasactual(struct cil_db *db, struct cil_tree_node *parse_current, return SEPOL_OK; exit: @@ -959,7 +1027,7 @@ index 1135e06..1505873 100644 cil_clear_node(ast_node); return rc; } -@@ -3187,8 +3141,7 @@ int cil_gen_typeattributeset(struct cil_db *db, struct cil_tree_node *parse_curr +@@ -3187,8 +3150,7 @@ int cil_gen_typeattributeset(struct cil_db *db, struct cil_tree_node *parse_curr return SEPOL_OK; exit: @@ -969,7 +1037,7 @@ index 1135e06..1505873 100644 cil_destroy_typeattributeset(attrset); return rc; } -@@ -3235,8 +3188,7 @@ int cil_gen_typepermissive(struct cil_db *db, struct cil_tree_node *parse_curren +@@ -3235,8 +3197,7 @@ int cil_gen_typepermissive(struct cil_db *db, struct cil_tree_node *parse_curren return SEPOL_OK; exit: @@ -979,7 +1047,7 @@ index 1135e06..1505873 100644 cil_destroy_typepermissive(typeperm); return rc; } -@@ -3319,8 +3271,7 @@ int cil_gen_typetransition(struct cil_db *db, struct cil_tree_node *parse_curren +@@ -3319,8 +3280,7 @@ int cil_gen_typetransition(struct cil_db *db, struct cil_tree_node *parse_curren return SEPOL_OK; exit: @@ -989,7 +1057,7 @@ index 1135e06..1505873 100644 return rc; } -@@ -3391,8 +3342,7 @@ int cil_gen_rangetransition(struct cil_db *db, struct cil_tree_node *parse_curre +@@ -3391,8 +3351,7 @@ int cil_gen_rangetransition(struct cil_db *db, struct cil_tree_node *parse_curre return SEPOL_OK; exit: @@ -999,7 +1067,7 @@ index 1135e06..1505873 100644 cil_destroy_rangetransition(rangetrans); return rc; } -@@ -3443,8 +3393,7 @@ int cil_gen_sensitivity(struct cil_db *db, struct cil_tree_node *parse_current, +@@ -3443,8 +3402,7 @@ int cil_gen_sensitivity(struct cil_db *db, struct cil_tree_node *parse_current, return SEPOL_OK; exit: @@ -1009,7 +1077,7 @@ index 1135e06..1505873 100644 cil_destroy_sensitivity(sens); cil_clear_node(ast_node); return rc; -@@ -3496,8 +3445,7 @@ int cil_gen_category(struct cil_db *db, struct cil_tree_node *parse_current, str +@@ -3496,8 +3454,7 @@ int cil_gen_category(struct cil_db *db, struct cil_tree_node *parse_current, str return SEPOL_OK; exit: @@ -1019,7 +1087,7 @@ index 1135e06..1505873 100644 cil_destroy_category(cat); cil_clear_node(ast_node); return rc; -@@ -3552,8 +3500,7 @@ int cil_gen_catset(struct cil_db *db, struct cil_tree_node *parse_current, struc +@@ -3552,8 +3509,7 @@ int cil_gen_catset(struct cil_db *db, struct cil_tree_node *parse_current, struc return SEPOL_OK; exit: @@ -1029,7 +1097,7 @@ index 1135e06..1505873 100644 cil_destroy_catset(catset); cil_clear_node(ast_node); return rc; -@@ -3614,8 +3561,7 @@ int cil_gen_catorder(struct cil_db *db, struct cil_tree_node *parse_current, str +@@ -3614,8 +3570,7 @@ int cil_gen_catorder(struct cil_db *db, struct cil_tree_node *parse_current, str return SEPOL_OK; exit: @@ -1039,7 +1107,7 @@ index 1135e06..1505873 100644 cil_destroy_catorder(catorder); return rc; } -@@ -3675,8 +3621,7 @@ int cil_gen_sensitivityorder(struct cil_db *db, struct cil_tree_node *parse_curr +@@ -3675,8 +3630,7 @@ int cil_gen_sensitivityorder(struct cil_db *db, struct cil_tree_node *parse_curr return SEPOL_OK; exit: @@ -1049,7 +1117,7 @@ index 1135e06..1505873 100644 cil_destroy_sensitivityorder(sensorder); return rc; } -@@ -3730,8 +3675,7 @@ int cil_gen_senscat(struct cil_db *db, struct cil_tree_node *parse_current, stru +@@ -3730,8 +3684,7 @@ int cil_gen_senscat(struct cil_db *db, struct cil_tree_node *parse_current, stru return SEPOL_OK; exit: @@ -1059,7 +1127,7 @@ index 1135e06..1505873 100644 cil_destroy_senscat(senscat); return rc; } -@@ -3786,8 +3730,7 @@ int cil_gen_level(struct cil_db *db, struct cil_tree_node *parse_current, struct +@@ -3786,8 +3739,7 @@ int cil_gen_level(struct cil_db *db, struct cil_tree_node *parse_current, struct return SEPOL_OK; exit: @@ -1069,7 +1137,7 @@ index 1135e06..1505873 100644 cil_destroy_level(level); cil_clear_node(ast_node); return rc; -@@ -3893,8 +3836,7 @@ int cil_gen_levelrange(struct cil_db *db, struct cil_tree_node *parse_current, s +@@ -3893,8 +3845,7 @@ int cil_gen_levelrange(struct cil_db *db, struct cil_tree_node *parse_current, s return SEPOL_OK; exit: @@ -1079,7 +1147,7 @@ index 1135e06..1505873 100644 cil_destroy_levelrange(lvlrange); cil_clear_node(ast_node); return rc; -@@ -3958,8 +3900,7 @@ int cil_gen_constrain(struct cil_db *db, struct cil_tree_node *parse_current, st +@@ -3958,8 +3909,7 @@ int cil_gen_constrain(struct cil_db *db, struct cil_tree_node *parse_current, st return SEPOL_OK; exit: @@ -1089,7 +1157,7 @@ index 1135e06..1505873 100644 cil_destroy_constrain(cons); return rc; } -@@ -4013,8 +3954,7 @@ int cil_gen_validatetrans(struct cil_db *db, struct cil_tree_node *parse_current +@@ -4013,8 +3963,7 @@ int cil_gen_validatetrans(struct cil_db *db, struct cil_tree_node *parse_current return SEPOL_OK; exit: @@ -1099,7 +1167,7 @@ index 1135e06..1505873 100644 cil_destroy_validatetrans(validtrans); return rc; -@@ -4118,8 +4058,7 @@ int cil_gen_context(struct cil_db *db, struct cil_tree_node *parse_current, stru +@@ -4118,8 +4067,7 @@ int cil_gen_context(struct cil_db *db, struct cil_tree_node *parse_current, stru return SEPOL_OK; exit: @@ -1109,7 +1177,7 @@ index 1135e06..1505873 100644 cil_destroy_context(context); cil_clear_node(ast_node); return SEPOL_ERR; -@@ -4211,8 +4150,7 @@ int cil_gen_filecon(struct cil_db *db, struct cil_tree_node *parse_current, stru +@@ -4211,8 +4159,7 @@ int cil_gen_filecon(struct cil_db *db, struct cil_tree_node *parse_current, stru return SEPOL_OK; exit: @@ -1119,7 +1187,7 @@ index 1135e06..1505873 100644 cil_destroy_filecon(filecon); return rc; } -@@ -4261,6 +4199,8 @@ int cil_gen_portcon(struct cil_db *db, struct cil_tree_node *parse_current, stru +@@ -4261,6 +4208,8 @@ int cil_gen_portcon(struct cil_db *db, struct cil_tree_node *parse_current, stru portcon->proto = CIL_PROTOCOL_UDP; } else if (proto == CIL_KEY_TCP) { portcon->proto = CIL_PROTOCOL_TCP; @@ -1128,7 +1196,7 @@ index 1135e06..1505873 100644 } else { cil_log(CIL_ERR, "Invalid protocol\n"); rc = SEPOL_ERR; -@@ -4311,8 +4251,7 @@ int cil_gen_portcon(struct cil_db *db, struct cil_tree_node *parse_current, stru +@@ -4311,8 +4260,7 @@ int cil_gen_portcon(struct cil_db *db, struct cil_tree_node *parse_current, stru return SEPOL_OK; exit: @@ -1138,7 +1206,7 @@ index 1135e06..1505873 100644 cil_destroy_portcon(portcon); return rc; } -@@ -4393,8 +4332,7 @@ int cil_gen_nodecon(struct cil_db *db, struct cil_tree_node *parse_current, stru +@@ -4393,8 +4341,7 @@ int cil_gen_nodecon(struct cil_db *db, struct cil_tree_node *parse_current, stru return SEPOL_OK; exit: @@ -1148,7 +1216,7 @@ index 1135e06..1505873 100644 cil_destroy_nodecon(nodecon); return rc; } -@@ -4464,8 +4402,7 @@ int cil_gen_genfscon(struct cil_db *db, struct cil_tree_node *parse_current, str +@@ -4464,8 +4411,7 @@ int cil_gen_genfscon(struct cil_db *db, struct cil_tree_node *parse_current, str return SEPOL_OK; exit: @@ -1158,7 +1226,7 @@ index 1135e06..1505873 100644 cil_destroy_genfscon(genfscon); return SEPOL_ERR; } -@@ -4538,8 +4475,7 @@ int cil_gen_netifcon(struct cil_db *db, struct cil_tree_node *parse_current, str +@@ -4538,8 +4484,7 @@ int cil_gen_netifcon(struct cil_db *db, struct cil_tree_node *parse_current, str return SEPOL_OK; exit: @@ -1168,7 +1236,7 @@ index 1135e06..1505873 100644 cil_destroy_netifcon(netifcon); return SEPOL_ERR; } -@@ -4606,8 +4542,7 @@ int cil_gen_pirqcon(struct cil_db *db, struct cil_tree_node *parse_current, stru +@@ -4606,8 +4551,7 @@ int cil_gen_pirqcon(struct cil_db *db, struct cil_tree_node *parse_current, stru return SEPOL_OK; exit: @@ -1178,7 +1246,7 @@ index 1135e06..1505873 100644 cil_destroy_pirqcon(pirqcon); return rc; } -@@ -4692,8 +4627,7 @@ int cil_gen_iomemcon(struct cil_db *db, struct cil_tree_node *parse_current, str +@@ -4692,8 +4636,7 @@ int cil_gen_iomemcon(struct cil_db *db, struct cil_tree_node *parse_current, str return SEPOL_OK; exit: @@ -1188,7 +1256,7 @@ index 1135e06..1505873 100644 cil_destroy_iomemcon(iomemcon); return rc; } -@@ -4778,8 +4712,7 @@ int cil_gen_ioportcon(struct cil_db *db, struct cil_tree_node *parse_current, st +@@ -4778,8 +4721,7 @@ int cil_gen_ioportcon(struct cil_db *db, struct cil_tree_node *parse_current, st return SEPOL_OK; exit: @@ -1198,7 +1266,7 @@ index 1135e06..1505873 100644 cil_destroy_ioportcon(ioportcon); return rc; } -@@ -4842,8 +4775,7 @@ int cil_gen_pcidevicecon(struct cil_db *db, struct cil_tree_node *parse_current, +@@ -4842,8 +4784,7 @@ int cil_gen_pcidevicecon(struct cil_db *db, struct cil_tree_node *parse_current, return SEPOL_OK; exit: @@ -1208,7 +1276,7 @@ index 1135e06..1505873 100644 cil_destroy_pcidevicecon(pcidevicecon); return rc; } -@@ -4903,8 +4835,7 @@ int cil_gen_devicetreecon(struct cil_db *db, struct cil_tree_node *parse_current +@@ -4903,8 +4844,7 @@ int cil_gen_devicetreecon(struct cil_db *db, struct cil_tree_node *parse_current return SEPOL_OK; exit: @@ -1218,7 +1286,7 @@ index 1135e06..1505873 100644 cil_destroy_devicetreecon(devicetreecon); return rc; } -@@ -4979,8 +4910,7 @@ int cil_gen_fsuse(struct cil_db *db, struct cil_tree_node *parse_current, struct +@@ -4979,8 +4919,7 @@ int cil_gen_fsuse(struct cil_db *db, struct cil_tree_node *parse_current, struct return SEPOL_OK; exit: @@ -1228,7 +1296,7 @@ index 1135e06..1505873 100644 cil_destroy_fsuse(fsuse); return SEPOL_ERR; } -@@ -5137,8 +5067,7 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct +@@ -5137,8 +5076,7 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct return SEPOL_OK; exit: @@ -1238,7 +1306,7 @@ index 1135e06..1505873 100644 cil_destroy_macro(macro); cil_clear_node(ast_node); return SEPOL_ERR; -@@ -5196,8 +5125,7 @@ int cil_gen_call(struct cil_db *db, struct cil_tree_node *parse_current, struct +@@ -5196,8 +5134,7 @@ int cil_gen_call(struct cil_db *db, struct cil_tree_node *parse_current, struct return SEPOL_OK; exit: @@ -1248,7 +1316,7 @@ index 1135e06..1505873 100644 cil_destroy_call(call); return rc; } -@@ -5299,8 +5227,7 @@ int cil_gen_optional(struct cil_db *db, struct cil_tree_node *parse_current, str +@@ -5299,8 +5236,7 @@ int cil_gen_optional(struct cil_db *db, struct cil_tree_node *parse_current, str return SEPOL_OK; exit: @@ -1258,7 +1326,7 @@ index 1135e06..1505873 100644 cil_destroy_optional(optional); cil_clear_node(ast_node); return rc; -@@ -5348,8 +5275,7 @@ int cil_gen_policycap(struct cil_db *db, struct cil_tree_node *parse_current, st +@@ -5348,8 +5284,7 @@ int cil_gen_policycap(struct cil_db *db, struct cil_tree_node *parse_current, st return SEPOL_OK; exit: @@ -1268,7 +1336,7 @@ index 1135e06..1505873 100644 cil_destroy_policycap(polcap); cil_clear_node(ast_node); return rc; -@@ -5404,8 +5330,7 @@ int cil_gen_ipaddr(struct cil_db *db, struct cil_tree_node *parse_current, struc +@@ -5404,8 +5339,7 @@ int cil_gen_ipaddr(struct cil_db *db, struct cil_tree_node *parse_current, struc return SEPOL_OK; exit: @@ -1278,7 +1346,7 @@ index 1135e06..1505873 100644 cil_destroy_ipaddr(ipaddr); cil_clear_node(ast_node); return rc; -@@ -5609,8 +5534,7 @@ int cil_gen_bounds(struct cil_db *db, struct cil_tree_node *parse_current, struc +@@ -5609,8 +5543,7 @@ int cil_gen_bounds(struct cil_db *db, struct cil_tree_node *parse_current, struc return SEPOL_OK; exit: @@ -1288,7 +1356,7 @@ index 1135e06..1505873 100644 cil_destroy_bounds(bounds); return rc; } -@@ -5671,8 +5595,7 @@ int cil_gen_default(struct cil_tree_node *parse_current, struct cil_tree_node *a +@@ -5671,8 +5604,7 @@ int cil_gen_default(struct cil_tree_node *parse_current, struct cil_tree_node *a return SEPOL_OK; exit: @@ -1298,7 +1366,7 @@ index 1135e06..1505873 100644 cil_destroy_default(def); return rc; } -@@ -5758,8 +5681,7 @@ int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_no +@@ -5758,8 +5690,7 @@ int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_no return SEPOL_OK; exit: @@ -1308,7 +1376,7 @@ index 1135e06..1505873 100644 cil_destroy_defaultrange(def); return rc; } -@@ -5819,8 +5741,7 @@ int cil_gen_handleunknown(struct cil_tree_node *parse_current, struct cil_tree_n +@@ -5819,8 +5750,7 @@ int cil_gen_handleunknown(struct cil_tree_node *parse_current, struct cil_tree_n return SEPOL_OK; exit: @@ -1318,7 +1386,7 @@ index 1135e06..1505873 100644 cil_destroy_handleunknown(unknown); return rc; } -@@ -5868,8 +5789,7 @@ int cil_gen_mls(struct cil_tree_node *parse_current, struct cil_tree_node *ast_n +@@ -5868,8 +5798,7 @@ int cil_gen_mls(struct cil_tree_node *parse_current, struct cil_tree_node *ast_n return SEPOL_OK; exit: @@ -1328,7 +1396,7 @@ index 1135e06..1505873 100644 cil_destroy_mls(mls); return rc; } -@@ -5879,6 +5799,27 @@ void cil_destroy_mls(struct cil_mls *mls) +@@ -5879,6 +5808,27 @@ void cil_destroy_mls(struct cil_mls *mls) free(mls); } @@ -1356,7 +1424,7 @@ index 1135e06..1505873 100644 int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *finished, void *extra_args) { struct cil_args_build *args = NULL; -@@ -5913,7 +5854,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f +@@ -5913,7 +5863,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f if (parse_current->parent->parent == NULL) { rc = SEPOL_OK; } else { @@ -1365,7 +1433,7 @@ index 1135e06..1505873 100644 } goto exit; } -@@ -5926,7 +5867,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f +@@ -5926,7 +5876,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f parse_current->data == CIL_KEY_BLOCKINHERIT || parse_current->data == CIL_KEY_BLOCKABSTRACT) { rc = SEPOL_ERR; @@ -1374,7 +1442,7 @@ index 1135e06..1505873 100644 goto exit; } } -@@ -5942,8 +5883,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f +@@ -5942,8 +5892,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f parse_current->data != CIL_KEY_TYPECHANGE && parse_current->data != CIL_KEY_CALL) { rc = SEPOL_ERR; @@ -1384,7 +1452,7 @@ index 1135e06..1505873 100644 if (((struct cil_booleanif*)boolif->data)->preserved_tunable) { cil_log(CIL_ERR, "%s cannot be defined within tunableif statement (treated as a booleanif due to preserve-tunables)\n", (char*)parse_current->data); -@@ -5958,8 +5898,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f +@@ -5958,8 +5907,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f if (tunif != NULL) { if (parse_current->data == CIL_KEY_TUNABLE) { rc = SEPOL_ERR; @@ -1394,7 +1462,7 @@ index 1135e06..1505873 100644 cil_log(CIL_ERR, "Tunables cannot be defined within tunableif statement\n"); goto exit; } -@@ -5968,8 +5907,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f +@@ -5968,8 +5916,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f if (in != NULL) { if (parse_current->data == CIL_KEY_IN) { rc = SEPOL_ERR; @@ -1404,7 +1472,7 @@ index 1135e06..1505873 100644 cil_log(CIL_ERR, "in-statements cannot be defined within in-statements\n"); goto exit; } -@@ -5979,7 +5917,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f +@@ -5979,7 +5926,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f ast_node->parent = ast_current; ast_node->line = parse_current->line; @@ -1413,7 +1481,7 @@ index 1135e06..1505873 100644 if (parse_current->data == CIL_KEY_BLOCK) { rc = cil_gen_block(db, parse_current, ast_node, 0); -@@ -6242,8 +6180,10 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f +@@ -6242,8 +6189,10 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f } else if (parse_current->data == CIL_KEY_MLS) { rc = cil_gen_mls(parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; @@ -1425,7 +1493,7 @@ index 1135e06..1505873 100644 rc = SEPOL_ERR; } -@@ -6264,7 +6204,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f +@@ -6264,7 +6213,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f if (ast_current->flavor == CIL_IN) { args->in = ast_current; } @@ -1555,10 +1623,18 @@ index 865bd7d..dad1347 100644 return rc; diff --git libsepol-2.5/cil/src/cil_internal.h libsepol-2.5/cil/src/cil_internal.h -index a0a5480..5875dc9 100644 +index a0a5480..03672bb 100644 --- libsepol-2.5/cil/src/cil_internal.h +++ libsepol-2.5/cil/src/cil_internal.h -@@ -101,6 +101,7 @@ char *CIL_KEY_OBJECT_R; +@@ -37,6 +37,7 @@ + + #include + #include ++#include + + #include + +@@ -101,6 +102,7 @@ char *CIL_KEY_OBJECT_R; char *CIL_KEY_STAR; char *CIL_KEY_TCP; char *CIL_KEY_UDP; @@ -1566,7 +1642,7 @@ index a0a5480..5875dc9 100644 char *CIL_KEY_AUDITALLOW; char *CIL_KEY_TUNABLEIF; char *CIL_KEY_ALLOW; -@@ -225,6 +226,9 @@ char *CIL_KEY_NEVERALLOWX; +@@ -225,6 +227,9 @@ char *CIL_KEY_NEVERALLOWX; char *CIL_KEY_PERMISSIONX; char *CIL_KEY_IOCTL; char *CIL_KEY_UNORDERED; @@ -1576,7 +1652,15 @@ index a0a5480..5875dc9 100644 /* Symbol Table Array Indices -@@ -713,7 +717,8 @@ struct cil_filecon { +@@ -266,6 +271,7 @@ enum cil_sym_array { + extern int cil_sym_sizes[CIL_SYM_ARRAY_NUM][CIL_SYM_NUM]; + + #define CIL_CLASS_SYM_SIZE 256 ++#define CIL_PERMS_PER_CLASS (sizeof(sepol_access_vector_t) * 8) + + struct cil_db { + struct cil_tree *parse; +@@ -713,7 +719,8 @@ struct cil_filecon { enum cil_protocol { CIL_PROTOCOL_UDP = 1, @@ -1586,7 +1670,7 @@ index a0a5480..5875dc9 100644 }; struct cil_portcon { -@@ -915,6 +920,11 @@ struct cil_mls { +@@ -915,6 +922,11 @@ struct cil_mls { int value; }; @@ -1598,7 +1682,7 @@ index a0a5480..5875dc9 100644 void cil_db_init(struct cil_db **db); void cil_db_destroy(struct cil_db **db); -@@ -1017,6 +1027,7 @@ void cil_default_init(struct cil_default **def); +@@ -1017,6 +1029,7 @@ void cil_default_init(struct cil_default **def); void cil_defaultrange_init(struct cil_defaultrange **def); void cil_handleunknown_init(struct cil_handleunknown **unk); void cil_mls_init(struct cil_mls **mls); @@ -2015,6 +2099,58 @@ index 2c9b158..382129b 100644 } fprintf(file_arr[NETIFCONS], "%d ", portcon->port_low); fprintf(file_arr[NETIFCONS], "%d ", portcon->port_high); +diff --git libsepol-2.5/cil/src/cil_post.c libsepol-2.5/cil/src/cil_post.c +index a694b33..f8447c9 100644 +--- libsepol-2.5/cil/src/cil_post.c ++++ libsepol-2.5/cil/src/cil_post.c +@@ -47,6 +47,9 @@ + #include "cil_verify.h" + #include "cil_symtab.h" + ++#define GEN_REQUIRE_ATTR "cil_gen_require" /* Also in libsepol/src/module_to_cil.c */ ++#define TYPEATTR_INFIX "_typeattr_" /* Also in libsepol/src/module_to_cil.c */ ++ + static int __cil_expr_to_bitmap(struct cil_list *expr, ebitmap_t *out, int max, struct cil_db *db); + static int __cil_expr_list_to_bitmap(struct cil_list *expr_list, ebitmap_t *out, int max, struct cil_db *db); + +@@ -1186,6 +1189,27 @@ exit: + return SEPOL_ERR; + } + ++static int cil_typeattribute_used(struct cil_typeattribute *cil_attr) ++{ ++ if (cil_attr->used) { ++ return CIL_TRUE; ++ } ++ ++ if (strcmp(DATUM(cil_attr)->name, GEN_REQUIRE_ATTR) == 0) { ++ return CIL_FALSE; ++ } ++ ++ if (strstr(DATUM(cil_attr)->name,TYPEATTR_INFIX) != NULL) { ++ return CIL_FALSE; ++ } ++ ++ if (ebitmap_cardinality(cil_attr->types) == 0) { ++ return CIL_FALSE; ++ } ++ ++ return CIL_TRUE; ++} ++ + static int __cil_post_db_attr_helper(struct cil_tree_node *node, uint32_t *finished, void *extra_args) + { + int rc = SEPOL_ERR; +@@ -1208,6 +1232,9 @@ static int __cil_post_db_attr_helper(struct cil_tree_node *node, uint32_t *finis + if (attr->types == NULL) { + rc = __evaluate_type_expression(attr, db); + if (rc != SEPOL_OK) goto exit; ++ if (cil_typeattribute_used(attr)) { ++ attr->used = CIL_TRUE; ++ } + } + break; + } diff --git libsepol-2.5/cil/src/cil_reset_ast.c libsepol-2.5/cil/src/cil_reset_ast.c index 06146ca..de00679 100644 --- libsepol-2.5/cil/src/cil_reset_ast.c @@ -2029,7 +2165,7 @@ index 06146ca..de00679 100644 * statement isn't seen as a duplicate */ class->num_perms -= common->num_perms; diff --git libsepol-2.5/cil/src/cil_resolve_ast.c libsepol-2.5/cil/src/cil_resolve_ast.c -index 1489680..8348d57 100644 +index 1489680..917adf8 100644 --- libsepol-2.5/cil/src/cil_resolve_ast.c +++ libsepol-2.5/cil/src/cil_resolve_ast.c @@ -131,10 +131,10 @@ static int __cil_resolve_perms(symtab_t *class_symtab, symtab_t *common_symtab, @@ -2055,7 +2191,18 @@ index 1489680..8348d57 100644 return SEPOL_ERR; } -@@ -1380,7 +1380,7 @@ struct cil_list *__cil_ordered_lists_merge_all(struct cil_list **ordered_lists, +@@ -717,6 +717,10 @@ int cil_resolve_classcommon(struct cil_tree_node *current, void *extra_args) + cil_symtab_map(&class->perms, __class_update_perm_values, &common->num_perms); + + class->num_perms += common->num_perms; ++ if (class->num_perms > CIL_PERMS_PER_CLASS) { ++ cil_tree_log(current, CIL_ERR, "Too many permissions in class '%s' when including common permissions", class->datum.name); ++ goto exit; ++ } + + return SEPOL_OK; + +@@ -1380,7 +1384,7 @@ struct cil_list *__cil_ordered_lists_merge_all(struct cil_list **ordered_lists, cil_list_for_each(curr, *ordered_lists) { struct cil_ordered_list *ordered_list = curr->data; if (ordered_list->merged == CIL_FALSE) { @@ -2064,7 +2211,15 @@ index 1489680..8348d57 100644 } } goto exit; -@@ -2252,12 +2252,10 @@ void cil_print_recursive_blockinherit(struct cil_tree_node *bi_node, struct cil_ +@@ -1447,6 +1451,7 @@ int cil_resolve_classorder(struct cil_tree_node *current, void *extra_args) + return SEPOL_OK; + + exit: ++ cil_list_destroy(&new, CIL_FALSE); + return rc; + } + +@@ -2252,12 +2257,10 @@ void cil_print_recursive_blockinherit(struct cil_tree_node *bi_node, struct cil_ cil_list_for_each(item, trace) { curr = item->data; @@ -2079,7 +2234,7 @@ index 1489680..8348d57 100644 } } -@@ -2442,7 +2440,7 @@ int cil_resolve_in_list(void *extra_args) +@@ -2442,7 +2445,7 @@ int cil_resolve_in_list(void *extra_args) } if (unresolved > 0 && resolved == 0) { @@ -2088,7 +2243,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -2485,7 +2483,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil +@@ -2485,7 +2488,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil if (user->bounds != NULL) { struct cil_tree_node *node = user->bounds->datum.nodes->head->data; @@ -2097,7 +2252,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -2498,7 +2496,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil +@@ -2498,7 +2501,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil if (role->bounds != NULL) { struct cil_tree_node *node = role->bounds->datum.nodes->head->data; @@ -2106,7 +2261,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -2512,8 +2510,8 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil +@@ -2512,8 +2515,8 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil if (type->bounds != NULL) { node = ((struct cil_symtab_datum *)type->bounds)->nodes->head->data; @@ -2117,7 +2272,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -2542,7 +2540,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil +@@ -2542,7 +2545,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil return SEPOL_OK; exit: @@ -2126,7 +2281,7 @@ index 1489680..8348d57 100644 return rc; } -@@ -2617,12 +2615,10 @@ void cil_print_recursive_call(struct cil_tree_node *call_node, struct cil_tree_n +@@ -2617,12 +2620,10 @@ void cil_print_recursive_call(struct cil_tree_node *call_node, struct cil_tree_n cil_list_for_each(item, trace) { curr = item->data; @@ -2141,7 +2296,7 @@ index 1489680..8348d57 100644 } } -@@ -2700,7 +2696,7 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args) +@@ -2700,7 +2701,7 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args) struct cil_tree_node *pc = NULL; if (new_call->args_tree == NULL) { @@ -2150,7 +2305,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -2713,7 +2709,7 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args) +@@ -2713,7 +2714,7 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args) enum cil_flavor flavor = ((struct cil_param*)item->data)->flavor; if (pc == NULL) { @@ -2159,7 +2314,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -2890,12 +2886,12 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args) +@@ -2890,12 +2891,12 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args) } if (pc != NULL) { @@ -2174,7 +2329,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -3593,7 +3589,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished +@@ -3593,7 +3594,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished if (optstack != NULL) { if (node->flavor == CIL_TUNABLE || node->flavor == CIL_MACRO) { /* tuanbles and macros are not allowed in optionals*/ @@ -2183,7 +2338,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -3601,7 +3597,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished +@@ -3601,7 +3602,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished if (blockstack != NULL) { if (node->flavor == CIL_CAT || node->flavor == CIL_SENS) { @@ -2192,7 +2347,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -3612,7 +3608,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished +@@ -3612,7 +3613,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished node->flavor == CIL_BLOCK || node->flavor == CIL_BLOCKABSTRACT || node->flavor == CIL_MACRO) { @@ -2201,7 +2356,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -3626,9 +3622,9 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished +@@ -3626,9 +3627,9 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished node->flavor == CIL_TUNABLEIF || node->flavor == CIL_NAMETYPETRANSITION)) { if (((struct cil_booleanif*)boolif->data)->preserved_tunable) { @@ -2213,7 +2368,7 @@ index 1489680..8348d57 100644 } rc = SEPOL_ERR; goto exit; -@@ -3658,14 +3654,13 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished +@@ -3658,14 +3659,13 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished struct cil_optional *opt = (struct cil_optional *)optstack->data; struct cil_tree_node *opt_node = opt->datum.nodes->head->data; @@ -2230,6 +2385,14 @@ index 1489680..8348d57 100644 goto exit; } +@@ -3924,6 +3924,7 @@ exit: + __cil_ordered_lists_destroy(&extra_args.catorder_lists); + __cil_ordered_lists_destroy(&extra_args.sensitivityorder_lists); + cil_list_destroy(&extra_args.in_list, CIL_FALSE); ++ cil_list_destroy(&extra_args.unordered_classorder_lists, CIL_FALSE); + + return rc; + } diff --git libsepol-2.5/cil/src/cil_tree.c libsepol-2.5/cil/src/cil_tree.c index 1c23efc..9ff9d4b 100644 --- libsepol-2.5/cil/src/cil_tree.c @@ -3012,11 +3175,362 @@ index fbf397f..a4be880 100644 if (rc == 0) goto exit; } +diff --git libsepol-2.5/src/conditional.c libsepol-2.5/src/conditional.c +index ea47cdd..e1bc961 100644 +--- libsepol-2.5/src/conditional.c ++++ libsepol-2.5/src/conditional.c +@@ -589,14 +589,8 @@ int cond_read_bool(policydb_t * p, + goto err; + + len = le32_to_cpu(buf[2]); +- +- key = malloc(len + 1); +- if (!key) +- goto err; +- rc = next_entry(key, fp, len); +- if (rc < 0) ++ if (str_read(&key, fp, len)) + goto err; +- key[len] = 0; + + if (p->policy_type != POLICY_KERN && + p->policyvers >= MOD_POLICYDB_VERSION_TUNABLE_SEP) { +diff --git libsepol-2.5/src/context.c libsepol-2.5/src/context.c +index 84dad34..a88937f 100644 +--- libsepol-2.5/src/context.c ++++ libsepol-2.5/src/context.c +@@ -10,6 +10,7 @@ + #include "context.h" + #include "handle.h" + #include "mls.h" ++#include "private.h" + + /* ----- Compatibility ---- */ + int policydb_context_isvalid(const policydb_t * p, const context_struct_t * c) +@@ -55,7 +56,7 @@ int context_is_valid(const policydb_t * p, const context_struct_t * c) + * Role must be authorized for the type. + */ + role = p->role_val_to_struct[c->role - 1]; +- if (!ebitmap_get_bit(&role->cache, c->type - 1)) ++ if (!role || !ebitmap_get_bit(&role->cache, c->type - 1)) + /* role may not be associated with type */ + return 0; + +@@ -297,10 +298,18 @@ int context_from_string(sepol_handle_t * handle, + char *con_cpy = NULL; + sepol_context_t *ctx_record = NULL; + ++ if (zero_or_saturated(con_str_len)) { ++ ERR(handle, "Invalid context length"); ++ goto err; ++ } ++ + /* sepol_context_from_string expects a NULL-terminated string */ + con_cpy = malloc(con_str_len + 1); +- if (!con_cpy) +- goto omem; ++ if (!con_cpy) { ++ ERR(handle, "out of memory"); ++ goto err; ++ } ++ + memcpy(con_cpy, con_str, con_str_len); + con_cpy[con_str_len] = '\0'; + +@@ -315,9 +324,6 @@ int context_from_string(sepol_handle_t * handle, + sepol_context_free(ctx_record); + return STATUS_SUCCESS; + +- omem: +- ERR(handle, "out of memory"); +- + err: + ERR(handle, "could not create context structure"); + free(con_cpy); +diff --git libsepol-2.5/src/context_record.c libsepol-2.5/src/context_record.c +index ac2884a..0a8bbf6 100644 +--- libsepol-2.5/src/context_record.c ++++ libsepol-2.5/src/context_record.c +@@ -5,6 +5,7 @@ + + #include "context_internal.h" + #include "debug.h" ++#include "private.h" + + struct sepol_context { + +@@ -279,44 +280,69 @@ int sepol_context_from_string(sepol_handle_t * handle, + + hidden_def(sepol_context_from_string) + ++static inline int safe_sum(size_t *sum, const size_t augends[], const size_t cnt) { ++ ++ size_t a, i; ++ ++ *sum = 0; ++ for(i=0; i < cnt; i++) { ++ /* sum should not be smaller than the addend */ ++ a = augends[i]; ++ *sum += a; ++ if (*sum < a) { ++ return i; ++ } ++ } ++ ++ return 0; ++} ++ + int sepol_context_to_string(sepol_handle_t * handle, + const sepol_context_t * con, char **str_ptr) + { + + int rc; +- const int user_sz = strlen(con->user); +- const int role_sz = strlen(con->role); +- const int type_sz = strlen(con->type); +- const int mls_sz = (con->mls) ? strlen(con->mls) : 0; +- const int total_sz = user_sz + role_sz + type_sz + +- mls_sz + ((con->mls) ? 3 : 2); +- +- char *str = (char *)malloc(total_sz + 1); +- if (!str) +- goto omem; ++ char *str = NULL; ++ size_t total_sz, err; ++ const size_t sizes[] = { ++ strlen(con->user), /* user length */ ++ strlen(con->role), /* role length */ ++ strlen(con->type), /* type length */ ++ (con->mls) ? strlen(con->mls) : 0, /* mls length */ ++ ((con->mls) ? 3 : 2) + 1 /* mls has extra ":" also null byte */ ++ }; ++ ++ err = safe_sum(&total_sz, sizes, ARRAY_SIZE(sizes)); ++ if (err) { ++ ERR(handle, "invalid size, overflow at position: %zu", err); ++ goto err; ++ } + ++ str = (char *)malloc(total_sz); ++ if (!str) { ++ ERR(handle, "out of memory"); ++ goto err; ++ } + if (con->mls) { +- rc = snprintf(str, total_sz + 1, "%s:%s:%s:%s", ++ rc = snprintf(str, total_sz, "%s:%s:%s:%s", + con->user, con->role, con->type, con->mls); +- if (rc < 0 || (rc >= total_sz + 1)) { +- ERR(handle, "print error"); +- goto err; +- } + } else { +- rc = snprintf(str, total_sz + 1, "%s:%s:%s", ++ rc = snprintf(str, total_sz, "%s:%s:%s", + con->user, con->role, con->type); +- if (rc < 0 || (rc >= total_sz + 1)) { +- ERR(handle, "print error"); +- goto err; +- } ++ } ++ ++ /* ++ * rc is >= 0 on the size_t cast and is safe to promote ++ * to an unsigned value. ++ */ ++ if (rc < 0 || (size_t)rc >= total_sz) { ++ ERR(handle, "print error"); ++ goto err; + } + + *str_ptr = str; + return STATUS_SUCCESS; + +- omem: +- ERR(handle, "out of memory"); +- + err: + ERR(handle, "could not convert context to string"); + free(str); +diff --git libsepol-2.5/src/ebitmap.c libsepol-2.5/src/ebitmap.c +index 58f2fc4..fe8beb8 100644 +--- libsepol-2.5/src/ebitmap.c ++++ libsepol-2.5/src/ebitmap.c +@@ -394,6 +394,10 @@ int ebitmap_read(ebitmap_t * e, void *fp) + e->highbit, MAPSIZE); + goto bad; + } ++ ++ if (e->highbit && !count) ++ goto bad; ++ + l = NULL; + for (i = 0; i < count; i++) { + rc = next_entry(buf, fp, sizeof(uint32_t)); +diff --git libsepol-2.5/src/expand.c libsepol-2.5/src/expand.c +index 9cb7965..004a029 100644 +--- libsepol-2.5/src/expand.c ++++ libsepol-2.5/src/expand.c +@@ -1855,20 +1855,31 @@ static int expand_avrule_helper(sepol_handle_t * handle, + else + avdatump->data = ~cur->data; + } else if (specified & AVRULE_XPERMS) { +- if (!avdatump->xperms) { ++ xperms = avdatump->xperms; ++ if (!xperms) { + xperms = (avtab_extended_perms_t *) + calloc(1, sizeof(avtab_extended_perms_t)); + if (!xperms) { + ERR(handle, "Out of memory!"); + return -1; + } +- node->datum.xperms = xperms; ++ avdatump->xperms = xperms; + } +- node->datum.xperms->specified = extended_perms->specified; +- node->datum.xperms->driver = extended_perms->driver; + ++ switch (extended_perms->specified) { ++ case AVRULE_XPERMS_IOCTLFUNCTION: ++ xperms->specified = AVTAB_XPERMS_IOCTLFUNCTION; ++ break; ++ case AVRULE_XPERMS_IOCTLDRIVER: ++ xperms->specified = AVTAB_XPERMS_IOCTLDRIVER; ++ break; ++ default: ++ return -1; ++ } ++ ++ xperms->driver = extended_perms->driver; + for (i = 0; i < ARRAY_SIZE(xperms->perms); i++) +- node->datum.xperms->perms[i] |= extended_perms->perms[i]; ++ xperms->perms[i] |= extended_perms->perms[i]; + } else { + assert(0); /* should never occur */ + } +@@ -2497,6 +2508,7 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, + unsigned int i; + ebitmap_t types, neg_types; + ebitmap_node_t *tnode; ++ int rc =-1; + + ebitmap_init(&types); + ebitmap_init(t); +@@ -2505,17 +2517,29 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, + /* First go through the types and OR all the attributes to types */ + ebitmap_for_each_bit(&set->types, tnode, i) { + if (ebitmap_node_get_bit(tnode, i)) { ++ ++ /* ++ * invalid policies might have more types set in the ebitmap than ++ * what's available in the type_val_to_struct mapping ++ */ ++ if (i > p->p_types.nprim - 1) ++ goto err_types; ++ ++ if (!p->type_val_to_struct[i]) { ++ goto err_types; ++ } ++ + if (p->type_val_to_struct[i]->flavor == + TYPE_ATTRIB) { + if (ebitmap_union + (&types, + &p->type_val_to_struct[i]-> + types)) { +- return -1; ++ goto err_types; + } + } else { + if (ebitmap_set_bit(&types, i, 1)) { +- return -1; ++ goto err_types; + } + } + } +@@ -2523,7 +2547,7 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, + } else { + /* No expansion of attributes, just copy the set as is. */ + if (ebitmap_cpy(&types, &set->types)) +- return -1; ++ goto err_types; + } + + /* Now do the same thing for negset */ +@@ -2535,11 +2559,11 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, + if (ebitmap_union + (&neg_types, + &p->type_val_to_struct[i]->types)) { +- return -1; ++ goto err_neg; + } + } else { + if (ebitmap_set_bit(&neg_types, i, 1)) { +- return -1; ++ goto err_neg; + } + } + } +@@ -2554,7 +2578,7 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, + p->type_val_to_struct[i]->flavor == TYPE_ATTRIB) + continue; + if (ebitmap_set_bit(t, i, 1)) +- return -1; ++ goto err_neg; + } + goto out; + } +@@ -2563,7 +2587,7 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, + if (ebitmap_node_get_bit(tnode, i) + && (!ebitmap_get_bit(&neg_types, i))) + if (ebitmap_set_bit(t, i, 1)) +- return -1; ++ goto err_neg; + } + + if (set->flags & TYPE_COMP) { +@@ -2575,20 +2599,23 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, + } + if (ebitmap_get_bit(t, i)) { + if (ebitmap_set_bit(t, i, 0)) +- return -1; ++ goto err_neg; + } else { + if (ebitmap_set_bit(t, i, 1)) +- return -1; ++ goto err_neg; + } + } + } + +- out: ++ out: ++ rc = 0; + +- ebitmap_destroy(&types); ++ err_neg: + ebitmap_destroy(&neg_types); ++ err_types: ++ ebitmap_destroy(&types); + +- return 0; ++ return rc; + } + + static int copy_neverallow(policydb_t * dest_pol, uint32_t * typemap, diff --git libsepol-2.5/src/genbools.c libsepol-2.5/src/genbools.c -index 6a06ec9..c81e848 100644 +index 6a06ec9..c1f5405 100644 --- libsepol-2.5/src/genbools.c +++ libsepol-2.5/src/genbools.c -@@ -79,7 +79,7 @@ static int load_booleans(struct policydb *policydb, const char *path, +@@ -68,7 +68,6 @@ static int load_booleans(struct policydb *policydb, const char *path, + { + FILE *boolf; + char *buffer = NULL; +- size_t size = 0; + char localbools[BUFSIZ]; + char name[BUFSIZ]; + int val; +@@ -79,7 +78,7 @@ static int load_booleans(struct policydb *policydb, const char *path, if (boolf == NULL) goto localbool; @@ -3025,6 +3539,14 @@ index 6a06ec9..c81e848 100644 if ((buffer = (char *)malloc(255 * sizeof(char))) == NULL) { ERR(NULL, "out of memory"); return -1; +@@ -87,6 +86,7 @@ static int load_booleans(struct policydb *policydb, const char *path, + + while(fgets(buffer, 255, boolf) != NULL) { + #else ++ size_t size = 0; + while (getline(&buffer, &size, boolf) > 0) { + #endif + int ret = process_boolean(buffer, name, sizeof(name), &val); @@ -111,7 +111,7 @@ static int load_booleans(struct policydb *policydb, const char *path, boolf = fopen(localbools, "r"); if (boolf != NULL) { @@ -3035,7 +3557,7 @@ index 6a06ec9..c81e848 100644 while(fgets(buffer, 255, boolf) != NULL) { #else diff --git libsepol-2.5/src/genusers.c libsepol-2.5/src/genusers.c -index 7826b71..0b98a76 100644 +index 7826b71..5568210 100644 --- libsepol-2.5/src/genusers.c +++ libsepol-2.5/src/genusers.c @@ -7,7 +7,7 @@ @@ -3047,7 +3569,15 @@ index 7826b71..0b98a76 100644 #include #endif -@@ -47,7 +47,7 @@ static int load_users(struct policydb *policydb, const char *path) +@@ -36,7 +36,6 @@ static int load_users(struct policydb *policydb, const char *path) + { + FILE *fp; + char *buffer = NULL, *p, *q, oldc; +- size_t len = 0; + ssize_t nread; + unsigned lineno = 0, islist = 0, bit; + user_datum_t *usrdatum; +@@ -47,14 +46,16 @@ static int load_users(struct policydb *policydb, const char *path) if (fp == NULL) return -1; @@ -3056,6 +3586,15 @@ index 7826b71..0b98a76 100644 if ((buffer = (char *)malloc(255 * sizeof(char))) == NULL) { ERR(NULL, "out of memory"); return -1; + } + + while(fgets(buffer, 255, fp) != NULL) { ++ nread = strlen(buffer); + #else ++ size_t len = 0; + __fsetlocking(fp, FSETLOCKING_BYCALLER); + while ((nread = getline(&buffer, &len, fp)) > 0) { + #endif diff --git libsepol-2.5/src/hierarchy.c libsepol-2.5/src/hierarchy.c index 6f73195..778541a 100644 --- libsepol-2.5/src/hierarchy.c @@ -3132,8 +3671,106 @@ index 6f73195..778541a 100644 } } +diff --git libsepol-2.5/src/mls.c libsepol-2.5/src/mls.c +index 1e84bb7..8047d91 100644 +--- libsepol-2.5/src/mls.c ++++ libsepol-2.5/src/mls.c +@@ -262,6 +262,7 @@ int mls_context_isvalid(const policydb_t * p, const context_struct_t * c) + user_datum_t *usrdatum; + unsigned int i, l; + ebitmap_node_t *cnode; ++ hashtab_key_t key; + + if (!p->mls) + return 1; +@@ -279,11 +280,12 @@ int mls_context_isvalid(const policydb_t * p, const context_struct_t * c) + if (!c->range.level[l].sens + || c->range.level[l].sens > p->p_levels.nprim) + return 0; +- levdatum = (level_datum_t *) hashtab_search(p->p_levels.table, +- p-> +- p_sens_val_to_name +- [c->range.level[l]. +- sens - 1]); ++ ++ key = p->p_sens_val_to_name[c->range.level[l].sens - 1]; ++ if (!key) ++ return 0; ++ ++ levdatum = (level_datum_t *) hashtab_search(p->p_levels.table, key); + if (!levdatum) + return 0; + +@@ -310,7 +312,7 @@ int mls_context_isvalid(const policydb_t * p, const context_struct_t * c) + if (!c->user || c->user > p->p_users.nprim) + return 0; + usrdatum = p->user_val_to_struct[c->user - 1]; +- if (!mls_range_contains(usrdatum->exp_range, c->range)) ++ if (!usrdatum || !mls_range_contains(usrdatum->exp_range, c->range)) + return 0; /* user may not be associated with range */ + + return 1; +diff --git libsepol-2.5/src/module.c libsepol-2.5/src/module.c +index 1665ede..1c2bece 100644 +--- libsepol-2.5/src/module.c ++++ libsepol-2.5/src/module.c +@@ -30,6 +30,7 @@ + #include + #include + #include ++#include + + #define SEPOL_PACKAGE_SECTION_FC 0xf97cff90 + #define SEPOL_PACKAGE_SECTION_SEUSER 0x97cff91 +@@ -792,20 +793,13 @@ int sepol_module_package_info(struct sepol_policy_file *spf, int *type, + i); + goto cleanup; + } ++ + len = le32_to_cpu(buf[0]); +- *name = malloc(len + 1); +- if (!*name) { +- ERR(file->handle, "out of memory"); +- goto cleanup; +- } +- rc = next_entry(*name, file, len); +- if (rc < 0) { +- ERR(file->handle, +- "cannot get module name string (at section %u)", +- i); ++ if (str_read(name, file, len)) { ++ ERR(file->handle, "%s", strerror(errno)); + goto cleanup; + } +- (*name)[len] = '\0'; ++ + rc = next_entry(buf, file, sizeof(uint32_t)); + if (rc < 0) { + ERR(file->handle, +@@ -814,19 +808,10 @@ int sepol_module_package_info(struct sepol_policy_file *spf, int *type, + goto cleanup; + } + len = le32_to_cpu(buf[0]); +- *version = malloc(len + 1); +- if (!*version) { +- ERR(file->handle, "out of memory"); +- goto cleanup; +- } +- rc = next_entry(*version, file, len); +- if (rc < 0) { +- ERR(file->handle, +- "cannot get module version string (at section %u)", +- i); ++ if (str_read(version, file, len)) { ++ ERR(file->handle, "%s", strerror(errno)); + goto cleanup; + } +- (*version)[len] = '\0'; + seen |= SEEN_MOD; + break; + default: diff --git libsepol-2.5/src/module_to_cil.c libsepol-2.5/src/module_to_cil.c -index 18ec6b9..b9a4af7 100644 +index 18ec6b9..508a861 100644 --- libsepol-2.5/src/module_to_cil.c +++ libsepol-2.5/src/module_to_cil.c @@ -26,6 +26,9 @@ @@ -3146,7 +3783,48 @@ index 18ec6b9..b9a4af7 100644 #include #include #include -@@ -1070,6 +1073,10 @@ static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *a +@@ -44,6 +47,8 @@ + #include + #include + ++#include "private.h" ++ + #ifdef __GNUC__ + # define UNUSED(x) UNUSED_ ## x __attribute__((__unused__)) + #else +@@ -55,7 +60,9 @@ FILE *out_file; + #define STACK_SIZE 16 + #define DEFAULT_LEVEL "systemlow" + #define DEFAULT_OBJECT "object_r" +-#define GEN_REQUIRE_ATTR "cil_gen_require" ++#define GEN_REQUIRE_ATTR "cil_gen_require" /* Also in libsepol/cil/src/cil_post.c */ ++#define TYPEATTR_INFIX "_typeattr_" /* Also in libsepol/cil/src/cil_post.c */ ++#define ROLEATTR_INFIX "_roleattr_" + + __attribute__ ((format(printf, 1, 2))) + static void log_err(const char *fmt, ...) +@@ -121,7 +128,7 @@ static int get_line(char **start, char *end, char **line) + + for (len = 0; p < end && *p != '\n' && *p != '\0'; p++, len++); + +- if (len == 0) { ++ if (zero_or_saturated(len)) { + rc = 0; + goto exit; + } +@@ -623,9 +630,9 @@ static int set_to_cil_attr(struct policydb *pdb, int is_type, char ***names, uin + num_attrs++; + + if (is_type) { +- attr_infix = "_typeattr_"; ++ attr_infix = TYPEATTR_INFIX; + } else { +- attr_infix = "_roleattr_"; ++ attr_infix = ROLEATTR_INFIX; + } + + len = strlen(pdb->name) + strlen(attr_infix) + num_digits(num_attrs) + 1; +@@ -1070,6 +1077,10 @@ static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *a struct type_set *ts; for (avrule = avrule_list; avrule != NULL; avrule = avrule->next) { @@ -3157,7 +3835,7 @@ index 18ec6b9..b9a4af7 100644 ts = &avrule->stypes; rc = process_typeset(indent, pdb, ts, attr_list, &snames, &num_snames); if (rc != 0) { -@@ -1100,6 +1107,10 @@ static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *a +@@ -1100,6 +1111,10 @@ static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *a names_destroy(&snames, &num_snames); names_destroy(&tnames, &num_tnames); @@ -3168,7 +3846,16 @@ index 18ec6b9..b9a4af7 100644 } return 0; -@@ -2537,6 +2548,7 @@ static int ocontext_selinux_port_to_cil(struct policydb *pdb, struct ocontext *p +@@ -1292,7 +1307,7 @@ static int cond_list_to_cil(int indent, struct policydb *pdb, struct cond_node * + { + int rc = -1; + struct cond_node *cond; +- struct list *attr_list; ++ struct list *attr_list = NULL; + + rc = list_init(&attr_list); + if (rc != 0) { +@@ -2537,6 +2552,7 @@ static int ocontext_selinux_port_to_cil(struct policydb *pdb, struct ocontext *p switch (portcon->u.port.protocol) { case IPPROTO_TCP: protocol = "tcp"; break; case IPPROTO_UDP: protocol = "udp"; break; @@ -3176,6 +3863,33 @@ index 18ec6b9..b9a4af7 100644 default: log_err("Unknown portcon protocol: %i", portcon->u.port.protocol); rc = -1; +@@ -3470,7 +3486,7 @@ static int block_to_cil(struct policydb *pdb, struct avrule_block *block, struct + { + int rc = -1; + struct avrule_decl *decl; +- struct list *attr_list; ++ struct list *attr_list = NULL; + + decl = block->branch_list; + +@@ -3619,7 +3635,7 @@ static int blocks_to_cil(struct policydb *pdb) + int rc = -1; + struct avrule_block *block; + int indent = 0; +- struct stack *stack; ++ struct stack *stack = NULL; + + rc = stack_init(&stack); + if (rc != 0) { +@@ -3687,7 +3703,7 @@ static int linked_blocks_to_cil(struct policydb *pdb) + // Since it is linked, all optional blocks have been resolved + int rc = -1; + struct avrule_block *block; +- struct stack *stack; ++ struct stack *stack = NULL; + + rc = stack_init(&stack); + if (rc != 0) { diff --git libsepol-2.5/src/node_record.c libsepol-2.5/src/node_record.c index bd48ba0..21043b6 100644 --- libsepol-2.5/src/node_record.c @@ -3210,6 +3924,263 @@ index 50cf21d..820346d 100644 } } break; +diff --git libsepol-2.5/src/policydb.c libsepol-2.5/src/policydb.c +index 6a80f94..cdb3cde 100644 +--- libsepol-2.5/src/policydb.c ++++ libsepol-2.5/src/policydb.c +@@ -1068,13 +1068,13 @@ int policydb_index_others(sepol_handle_t * handle, + + free(p->role_val_to_struct); + p->role_val_to_struct = (role_datum_t **) +- malloc(p->p_roles.nprim * sizeof(role_datum_t *)); ++ calloc(p->p_roles.nprim, sizeof(role_datum_t *)); + if (!p->role_val_to_struct) + return -1; + + free(p->user_val_to_struct); + p->user_val_to_struct = (user_datum_t **) +- malloc(p->p_users.nprim * sizeof(user_datum_t *)); ++ calloc(p->p_users.nprim, sizeof(user_datum_t *)); + if (!p->user_val_to_struct) + return -1; + +@@ -1911,15 +1911,10 @@ static int perm_read(policydb_t * p + goto bad; + + len = le32_to_cpu(buf[0]); +- perdatum->s.value = le32_to_cpu(buf[1]); +- +- key = malloc(len + 1); +- if (!key) +- goto bad; +- rc = next_entry(key, fp, len); +- if (rc < 0) ++ if(str_read(&key, fp, len)) + goto bad; +- key[len] = 0; ++ ++ perdatum->s.value = le32_to_cpu(buf[1]); + + if (hashtab_insert(h, key, perdatum)) + goto bad; +@@ -1949,6 +1944,9 @@ static int common_read(policydb_t * p, hashtab_t h, struct policy_file *fp) + goto bad; + + len = le32_to_cpu(buf[0]); ++ if (zero_or_saturated(len)) ++ goto bad; ++ + comdatum->s.value = le32_to_cpu(buf[1]); + + if (symtab_init(&comdatum->permissions, PERM_SYMTAB_SIZE)) +@@ -2092,7 +2090,11 @@ static int class_read(policydb_t * p, hashtab_t h, struct policy_file *fp) + goto bad; + + len = le32_to_cpu(buf[0]); ++ if (zero_or_saturated(len)) ++ goto bad; + len2 = le32_to_cpu(buf[1]); ++ if (is_saturated(len2)) ++ goto bad; + cladatum->s.value = le32_to_cpu(buf[2]); + + if (symtab_init(&cladatum->permissions, PERM_SYMTAB_SIZE)) +@@ -2199,6 +2201,9 @@ static int role_read(policydb_t * p, hashtab_t h, struct policy_file *fp) + goto bad; + + len = le32_to_cpu(buf[0]); ++ if (zero_or_saturated(len)) ++ goto bad; ++ + role->s.value = le32_to_cpu(buf[1]); + if (policydb_has_boundary_feature(p)) + role->bounds = le32_to_cpu(buf[2]); +@@ -2287,6 +2292,9 @@ static int type_read(policydb_t * p, hashtab_t h, struct policy_file *fp) + goto bad; + + len = le32_to_cpu(buf[pos]); ++ if (zero_or_saturated(len)) ++ goto bad; ++ + typdatum->s.value = le32_to_cpu(buf[++pos]); + if (policydb_has_boundary_feature(p)) { + uint32_t properties; +@@ -2447,6 +2455,8 @@ int filename_trans_read(filename_trans_t **t, struct policy_file *fp) + 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) +@@ -2556,6 +2566,9 @@ static int ocontext_read_xen(struct policydb_compat_info *info, + if (rc < 0) + return -1; + len = le32_to_cpu(buf[0]); ++ if (zero_or_saturated(len)) ++ return -1; ++ + c->u.name = malloc(len + 1); + if (!c->u.name) + return -1; +@@ -2618,6 +2631,8 @@ static int ocontext_read_selinux(struct policydb_compat_info *info, + if (rc < 0) + return -1; + len = le32_to_cpu(buf[0]); ++ if (zero_or_saturated(len)) ++ return -1; + c->u.name = malloc(len + 1); + if (!c->u.name) + return -1; +@@ -2659,6 +2674,8 @@ static int ocontext_read_selinux(struct policydb_compat_info *info, + return -1; + c->v.behavior = le32_to_cpu(buf[0]); + len = le32_to_cpu(buf[1]); ++ if (zero_or_saturated(len)) ++ return -1; + c->u.name = malloc(len + 1); + if (!c->u.name) + return -1; +@@ -2719,7 +2736,7 @@ static int genfs_read(policydb_t * p, struct policy_file *fp) + uint32_t buf[1]; + size_t nel, nel2, len, len2; + genfs_t *genfs_p, *newgenfs, *genfs; +- unsigned int i, j; ++ size_t i, j; + ocontext_t *l, *c, *newc = NULL; + int rc; + +@@ -2733,6 +2750,8 @@ static int genfs_read(policydb_t * p, struct policy_file *fp) + if (rc < 0) + goto bad; + len = le32_to_cpu(buf[0]); ++ if (zero_or_saturated(len)) ++ goto bad; + newgenfs = calloc(1, sizeof(genfs_t)); + if (!newgenfs) + goto bad; +@@ -2778,6 +2797,8 @@ static int genfs_read(policydb_t * p, struct policy_file *fp) + if (rc < 0) + goto bad; + len = le32_to_cpu(buf[0]); ++ if (zero_or_saturated(len)) ++ goto bad; + newc->u.name = malloc(len + 1); + if (!newc->u.name) { + goto bad; +@@ -2812,6 +2833,8 @@ static int genfs_read(policydb_t * p, struct policy_file *fp) + l->next = newc; + else + newgenfs->head = newc; ++ /* clear newc after a new owner has the pointer */ ++ newc = NULL; + } + } + +@@ -2875,6 +2898,9 @@ static int user_read(policydb_t * p, hashtab_t h, struct policy_file *fp) + goto bad; + + len = le32_to_cpu(buf[0]); ++ if (zero_or_saturated(len)) ++ goto bad; ++ + usrdatum->s.value = le32_to_cpu(buf[1]); + if (policydb_has_boundary_feature(p)) + usrdatum->bounds = le32_to_cpu(buf[2]); +@@ -2958,6 +2984,9 @@ static int sens_read(policydb_t * p + goto bad; + + len = le32_to_cpu(buf[0]); ++ if (zero_or_saturated(len)) ++ goto bad; ++ + levdatum->isalias = le32_to_cpu(buf[1]); + + key = malloc(len + 1); +@@ -3001,6 +3030,9 @@ static int cat_read(policydb_t * p + goto bad; + + len = le32_to_cpu(buf[0]); ++ if(zero_or_saturated(len)) ++ goto bad; ++ + catdatum->s.value = le32_to_cpu(buf[1]); + catdatum->isalias = le32_to_cpu(buf[2]); + +@@ -3337,6 +3369,8 @@ static int filename_trans_rule_read(filename_trans_rule_t ** r, struct policy_fi + return -1; + + len = le32_to_cpu(buf[0]); ++ if (zero_or_saturated(len)) ++ return -1; + + ftr->name = malloc(len + 1); + if (!ftr->name) +@@ -3578,6 +3612,8 @@ static int scope_read(policydb_t * p, int symnum, struct policy_file *fp) + if (rc < 0) + goto cleanup; + key_len = le32_to_cpu(buf[0]); ++ if (zero_or_saturated(key_len)) ++ goto cleanup; + key = malloc(key_len + 1); + if (!key) + goto cleanup; +@@ -3662,8 +3698,8 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) + } + + len = buf[1]; +- if (len > POLICYDB_STRING_MAX_LENGTH) { +- ERR(fp->handle, "policydb string length too long "); ++ if (len == 0 || len > POLICYDB_STRING_MAX_LENGTH) { ++ ERR(fp->handle, "policydb string length %s ", len ? "too long" : "zero"); + return POLICYDB_ERROR; + } + +@@ -3796,6 +3832,8 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) + goto bad; + } + len = le32_to_cpu(buf[0]); ++ if (zero_or_saturated(len)) ++ goto bad; + if ((p->name = malloc(len + 1)) == NULL) { + goto bad; + } +@@ -3807,6 +3845,8 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) + goto bad; + } + len = le32_to_cpu(buf[0]); ++ if (zero_or_saturated(len)) ++ goto bad; + if ((p->version = malloc(len + 1)) == NULL) { + goto bad; + } +@@ -3924,6 +3964,10 @@ int policydb_read(policydb_t * p, struct policy_file *fp, unsigned verbose) + if (!ebitmap_node_get_bit(tnode, j) + || i == j) + continue; ++ ++ if (j >= p->p_types.nprim) ++ goto bad; ++ + if (ebitmap_set_bit + (&p->attr_type_map[j], i, 1)) + goto bad; +@@ -3954,12 +3998,12 @@ int policydb_reindex_users(policydb_t * p) + free(p->sym_val_to_name[i]); + + p->user_val_to_struct = (user_datum_t **) +- malloc(p->p_users.nprim * sizeof(user_datum_t *)); ++ calloc(p->p_users.nprim, sizeof(user_datum_t *)); + if (!p->user_val_to_struct) + return -1; + + p->sym_val_to_name[i] = (char **) +- malloc(p->symtab[i].nprim * sizeof(char *)); ++ calloc(p->symtab[i].nprim, sizeof(char *)); + if (!p->sym_val_to_name[i]) + return -1; + diff --git libsepol-2.5/src/port_record.c libsepol-2.5/src/port_record.c index 6a33d93..ed9093b 100644 --- libsepol-2.5/src/port_record.c @@ -3254,7 +4225,7 @@ index 607a629..62ec602 100644 ERR(handle, "invalid protocol %u " "found in policy", proto); return STATUS_ERR; diff --git libsepol-2.5/src/private.h libsepol-2.5/src/private.h -index 8a6d4bb..9c700c9 100644 +index 8a6d4bb..b884c23 100644 --- libsepol-2.5/src/private.h +++ libsepol-2.5/src/private.h @@ -5,7 +5,7 @@ @@ -3275,8 +4246,23 @@ index 8a6d4bb..9c700c9 100644 #define __BYTE_ORDER BYTE_ORDER #define __LITTLE_ENDIAN LITTLE_ENDIAN #endif +@@ -45,6 +45,9 @@ + + #define ARRAY_SIZE(x) (sizeof(x)/sizeof((x)[0])) + ++#define is_saturated(x) (x == (typeof(x))-1) ++#define zero_or_saturated(x) ((x == 0) || is_saturated(x)) ++ + /* Policy compatibility information. */ + struct policydb_compat_info { + unsigned int type; +@@ -62,3 +65,4 @@ extern struct policydb_compat_info *policydb_lookup_compat(unsigned int version, + extern int next_entry(void *buf, struct policy_file *fp, size_t bytes) hidden; + extern size_t put_entry(const void *ptr, size_t size, size_t n, + struct policy_file *fp) hidden; ++extern int str_read(char **strp, struct policy_file *fp, size_t len) hidden; diff --git libsepol-2.5/src/services.c libsepol-2.5/src/services.c -index d64a8e8..d2b80b4 100644 +index d64a8e8..068759d 100644 --- libsepol-2.5/src/services.c +++ libsepol-2.5/src/services.c @@ -1152,20 +1152,16 @@ int hidden sepol_compute_av(sepol_security_id_t ssid, @@ -3309,6 +4295,104 @@ index d64a8e8..d2b80b4 100644 } /* +@@ -1643,13 +1639,16 @@ int hidden next_entry(void *buf, struct policy_file *fp, size_t bytes) + return -1; + break; + case PF_USE_MEMORY: +- if (bytes > fp->len) ++ if (bytes > fp->len) { ++ errno = EOVERFLOW; + return -1; ++ } + memcpy(buf, fp->data, bytes); + fp->data += bytes; + fp->len -= bytes; + break; + default: ++ errno = EINVAL; + return -1; + } + return 0; +@@ -1683,6 +1682,40 @@ size_t hidden put_entry(const void *ptr, size_t size, size_t n, + } + + /* ++ * Reads a string and null terminates it from the policy file. ++ * This is a port of str_read from the SE Linux kernel code. ++ * ++ * It returns: ++ * 0 - Success ++ * -1 - Failure with errno set ++ */ ++int hidden str_read(char **strp, struct policy_file *fp, size_t len) ++{ ++ int rc; ++ char *str; ++ ++ if (zero_or_saturated(len)) { ++ errno = EINVAL; ++ return -1; ++ } ++ ++ str = malloc(len + 1); ++ if (!str) ++ return -1; ++ ++ /* it's expected the caller should free the str */ ++ *strp = str; ++ ++ /* next_entry sets errno */ ++ rc = next_entry(str, fp, len); ++ if (rc) ++ return rc; ++ ++ str[len] = '\0'; ++ return 0; ++} ++ ++/* + * Read a new set of configuration data from + * a policy database binary representation file. + * +diff --git libsepol-2.5/src/users.c libsepol-2.5/src/users.c +index ce54c2b..3ffb166 100644 +--- libsepol-2.5/src/users.c ++++ libsepol-2.5/src/users.c +@@ -19,12 +19,17 @@ static int user_to_record(sepol_handle_t * handle, + + const char *name = policydb->p_user_val_to_name[user_idx]; + user_datum_t *usrdatum = policydb->user_val_to_struct[user_idx]; +- ebitmap_t *roles = &(usrdatum->roles.roles); ++ ebitmap_t *roles; + ebitmap_node_t *rnode; + unsigned bit; + + sepol_user_t *tmp_record = NULL; + ++ if (!usrdatum) ++ goto err; ++ ++ roles = &(usrdatum->roles.roles); ++ + if (sepol_user_create(handle, &tmp_record) < 0) + goto err; + +@@ -234,6 +239,7 @@ int sepol_user_modify(sepol_handle_t * handle, + if (!tmp_ptr) + goto omem; + policydb->user_val_to_struct = tmp_ptr; ++ policydb->user_val_to_struct[policydb->p_users.nprim] = NULL; + + tmp_ptr = realloc(policydb->sym_val_to_name[SYM_USERS], + (policydb->p_users.nprim + +@@ -241,6 +247,7 @@ int sepol_user_modify(sepol_handle_t * handle, + if (!tmp_ptr) + goto omem; + policydb->sym_val_to_name[SYM_USERS] = tmp_ptr; ++ policydb->p_user_val_to_name[policydb->p_users.nprim] = NULL; + + /* Need to copy the user name */ + name = strdup(cname); diff --git libsepol-2.5/tests/.gitignore libsepol-2.5/tests/.gitignore new file mode 100644 index 0000000..c3f60fd @@ -3316,6 +4400,69 @@ index 0000000..c3f60fd +++ libsepol-2.5/tests/.gitignore @@ -0,0 +1 @@ +libsepol-tests +diff --git libsepol-2.5/tests/Makefile libsepol-2.5/tests/Makefile +index dd7bd33..60b3e83 100644 +--- libsepol-2.5/tests/Makefile ++++ libsepol-2.5/tests/Makefile +@@ -2,7 +2,7 @@ M4 ?= m4 + MKDIR ?= mkdir + EXE ?= libsepol-tests + +-CFLAGS += -g3 -gdwarf-2 -o0 -Wall -W -Wundef -Wmissing-noreturn -Wmissing-format-attribute -Wno-unused-parameter -Werror ++CFLAGS += -g3 -gdwarf-2 -O0 -Wall -W -Wundef -Wmissing-noreturn -Wmissing-format-attribute -Wno-unused-parameter -Werror + + # Statically link libsepol on the assumption that we are going to + # be testing internal functions. +diff --git libsepol-2.5/tests/libsepol-tests.c libsepol-2.5/tests/libsepol-tests.c +index 9302f72..544c792 100644 +--- libsepol-2.5/tests/libsepol-tests.c ++++ libsepol-2.5/tests/libsepol-tests.c +@@ -28,6 +28,7 @@ + #include + #include + ++#include + #include + #include + #include +@@ -51,9 +52,10 @@ static void usage(char *progname) + printf("\t-i, --interactive\t\tinteractive console\n"); + } + +-static int do_tests(int interactive, int verbose) ++static bool do_tests(int interactive, int verbose) + { + CU_pSuite suite = NULL; ++ unsigned int num_failures; + + if (CUE_SUCCESS != CU_initialize_registry()) + return CU_get_error(); +@@ -73,8 +75,9 @@ static int do_tests(int interactive, int verbose) + CU_console_run_tests(); + else + CU_basic_run_tests(); ++ num_failures = CU_get_number_of_tests_failed(); + CU_cleanup_registry(); +- return CU_get_error(); ++ return CU_get_error() == CUE_SUCCESS && num_failures == 0; + + } + +@@ -106,12 +109,12 @@ int main(int argc, char **argv) + + /* first do the non-mls tests */ + mls = 0; +- if (do_tests(interactive, verbose)) ++ if (!do_tests(interactive, verbose)) + return -1; + + /* then with mls */ + mls = 1; +- if (do_tests(interactive, verbose)) ++ if (!do_tests(interactive, verbose)) + return -1; + + return 0; diff --git libsepol-2.5/tests/policies/.gitignore libsepol-2.5/tests/policies/.gitignore new file mode 100644 index 0000000..5a547a8 @@ -3325,3 +4472,17 @@ index 0000000..5a547a8 +test-downgrade/ +test-*/*.mls +test-*/*.std +diff --git libsepol-2.5/tests/test-linker-roles.c libsepol-2.5/tests/test-linker-roles.c +index 2c4a804..569e2cc 100644 +--- libsepol-2.5/tests/test-linker-roles.c ++++ libsepol-2.5/tests/test-linker-roles.c +@@ -132,8 +132,7 @@ void module_role_tests(policydb_t * base) + + /**** test for type added to base role in module 1 (global) ****/ + decls[0] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_b"))->decl_id; +- decls[1] = (test_find_decl_by_sym(base, SYM_TYPES, "tag_g_m1"))->decl_id; +- test_sym_presence(base, "g_b_role_2", SYM_ROLES, SCOPE_DECL, decls, 2); ++ test_sym_presence(base, "g_b_role_2", SYM_ROLES, SCOPE_DECL, decls, 1); + /* make sure it has the correct type set (g_m1_type_1, no negset, no flags) */ + types[0] = "g_b_type_2"; /* added in base when declared */ + types[1] = "g_m1_type_1"; /* added in module */ diff --git a/libsepol.spec b/libsepol.spec index df3df84..b08b66f 100644 --- a/libsepol.spec +++ b/libsepol.spec @@ -1,14 +1,14 @@ Summary: SELinux binary policy manipulation library Name: libsepol Version: 2.5 -Release: 9%{?dist} +Release: 10%{?dist} License: LGPLv2+ Group: System Environment/Libraries Source: https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases/20160223/libsepol-2.5.tar.gz # download https://raw.githubusercontent.com/fedora-selinux/scripts/master/selinux/make-fedora-selinux-patch.sh # run: # $ VERSION=2.5 ./make-fedora-selinux-patch.sh libsepol -# HEAD https://github.com/fedora-selinux/selinux/commit/dbf42c22e798a5e2cf9c1fc711c803e7da20cfb4 +# HEAD https://github.com/fedora-selinux/selinux/commit/caefad506ca46db441952ab64ebfc6202897516b Patch1: libsepol-fedora.patch URL: https://github.com/SELinuxProject/selinux/wiki BuildRequires: flex @@ -106,6 +106,22 @@ exit 0 %{_libdir}/libsepol.so.1 %changelog +* Mon Oct 03 2016 Petr Lautrbach 2.5-10 +- Check for too many permissions in classes and commons in CIL +- Fix xperm mapping between avrule and avtab +- tests: Fix mispelling of optimization option +- Fix unused/uninitialized variables on mac build +- Produce more meaningful error messages for conflicting type rules in CIL +- make "make test" fail when a CUnit test fails +- tests: fix g_b_role_2 test +- Change which attributes CIL keeps in the binary policy +- Port str_read() from kernel and remove multiple occurances of similar code +- Use calloc instead of malloc for all the *_to_val_structs +- Fix bugs found by AFL +- Fix memory leak in expand.c +- Fix invalid read when policy file is corrupt +- Fix possible use of uninitialized variables + * Mon Aug 01 2016 Petr Lautrbach 2.5-9 - Warn instead of fail if permission is not resolved - Ignore object_r when adding userrole mappings to policydb