diff --git a/libsepol-fedora.patch b/libsepol-fedora.patch index 0a5c4d8..b0e52c3 100644 --- a/libsepol-fedora.patch +++ b/libsepol-fedora.patch @@ -1,8 +1,24 @@ +diff --git libsepol-2.5/Android.mk libsepol-2.5/Android.mk +index a43b343..5d2c96b 100644 +--- libsepol-2.5/Android.mk ++++ libsepol-2.5/Android.mk +@@ -64,6 +64,7 @@ cil_src_files := \ + cil/src/cil_verify.c + + common_cflags := \ ++ -D_GNU_SOURCE \ + -Wall -W -Wundef \ + -Wshadow -Wmissing-noreturn \ + -Wmissing-format-attribute diff --git libsepol-2.5/ChangeLog libsepol-2.5/ChangeLog -index ace3d54..41bf8c0 100644 +index ace3d54..9348d70 100644 --- libsepol-2.5/ChangeLog +++ libsepol-2.5/ChangeLog -@@ -1,3 +1,6 @@ +@@ -1,3 +1,10 @@ ++ * Build policy on systems not supporting DCCP protocol, from Richard Haines. ++ * Fix extended permissions neverallow checking, from Jeff Vander Stoep. ++ * Fix CIL neverallow and bounds checking, from James Carter ++ * Android.mk: Add -D_GNU_SOURCE to common_cflags, from Nick Kralevich. + * Add support for portcon dccp protocol, from Richard Haines + * Fix bug in CIL when resetting classes, from Steve Lawrence + @@ -22,10 +38,20 @@ index afdc240..de7033a 100644 CIL_KEY_TUNABLEIF = cil_strpool_add("tunableif"); CIL_KEY_ALLOW = cil_strpool_add("allow"); diff --git libsepol-2.5/cil/src/cil_binary.c libsepol-2.5/cil/src/cil_binary.c -index f749e53..5d7e52e 100644 +index f749e53..b8437c9 100644 --- libsepol-2.5/cil/src/cil_binary.c +++ libsepol-2.5/cil/src/cil_binary.c -@@ -3035,6 +3035,9 @@ int cil_portcon_to_policydb(policydb_t *pdb, struct cil_sort *portcons) +@@ -31,6 +31,9 @@ + #include + #include + #include ++#ifndef IPPROTO_DCCP ++#define IPPROTO_DCCP 33 ++#endif + + #include + #include +@@ -3035,6 +3038,9 @@ int cil_portcon_to_policydb(policydb_t *pdb, struct cil_sort *portcons) case CIL_PROTOCOL_TCP: new_ocon->u.port.protocol = IPPROTO_TCP; break; @@ -35,6 +61,183 @@ index f749e53..5d7e52e 100644 default: /* should not get here */ rc = SEPOL_ERR; +@@ -4380,10 +4386,9 @@ exit: + return rc; + } + +-static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct cil_tree_node *node) ++static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct cil_tree_node *node, int *violation) + { +- int rc = SEPOL_ERR; +- int ret = CIL_FALSE; ++ int rc = SEPOL_OK; + struct cil_avrule *cil_rule = node->data; + struct cil_symtab_datum *tgt = cil_rule->tgt; + uint32_t kind; +@@ -4422,11 +4427,11 @@ static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct + + rc = check_assertion(pdb, rule); + if (rc == CIL_TRUE) { ++ *violation = CIL_TRUE; + rc = __cil_print_neverallow_failure(db, node); + if (rc != SEPOL_OK) { + goto exit; + } +- ret = CIL_TRUE; + } + + } else { +@@ -4444,12 +4449,11 @@ static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct + rule->xperms = item->data; + rc = check_assertion(pdb, rule); + if (rc == CIL_TRUE) { ++ *violation = CIL_TRUE; + rc = __cil_print_neverallow_failure(db, node); + if (rc != SEPOL_OK) { + goto exit; + } +- ret = CIL_TRUE; +- goto exit; + } + } + } +@@ -4466,34 +4470,23 @@ exit: + rule->xperms = NULL; + __cil_destroy_sepol_avrules(rule); + +- if (rc) { +- return rc; +- } else { +- return ret; +- } ++ return rc; + } + +-static int cil_check_neverallows(const struct cil_db *db, policydb_t *pdb, struct cil_list *neverallows) ++static int cil_check_neverallows(const struct cil_db *db, policydb_t *pdb, struct cil_list *neverallows, int *violation) + { + int rc = SEPOL_OK; +- int ret = CIL_FALSE; + struct cil_list_item *item; + + cil_list_for_each(item, neverallows) { +- rc = cil_check_neverallow(db, pdb, item->data); +- if (rc < 0) { ++ rc = cil_check_neverallow(db, pdb, item->data, violation); ++ if (rc != SEPOL_OK) { + goto exit; +- } else if (rc > 0) { +- ret = CIL_TRUE; + } + } + + exit: +- if (rc || ret) { +- return SEPOL_ERR; +- } else { +- return SEPOL_OK; +- } ++ return rc; + } + + static struct cil_list *cil_classperms_from_sepol(policydb_t *pdb, uint16_t class, uint32_t data, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[]) +@@ -4548,7 +4541,7 @@ exit: + return rc; + } + +-static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void *type_value_to_cil, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[]) ++static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void *type_value_to_cil, struct cil_class *class_value_to_cil[], struct cil_perm **perm_value_to_cil[], int *violation) + { + int rc = SEPOL_OK; + int i; +@@ -4574,6 +4567,9 @@ static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void + if (bad) { + avtab_ptr_t cur; + struct cil_avrule target; ++ struct cil_tree_node *n1 = NULL; ++ ++ *violation = CIL_TRUE; + + target.is_extended = 0; + target.rule_kind = CIL_AVRULE_ALLOWED; +@@ -4585,7 +4581,6 @@ static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void + for (cur = bad; cur; cur = cur->next) { + struct cil_list_item *i2; + struct cil_list *matching; +- struct cil_tree_node *n; + + rc = cil_avrule_from_sepol(pdb, cur, &target, type_value_to_cil, class_value_to_cil, perm_value_to_cil); + if (rc != SEPOL_OK) { +@@ -4594,7 +4589,7 @@ static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void + } + __cil_print_rule(" ", "allow", &target); + cil_list_init(&matching, CIL_NODE); +- rc = cil_find_matching_avrule_in_ast(db->ast->root, CIL_AVRULE, &target, matching, CIL_FALSE); ++ rc = cil_find_matching_avrule_in_ast(db->ast->root, CIL_AVRULE, &target, matching, CIL_TRUE); + if (rc) { + cil_log(CIL_ERR, "Error occurred while checking type bounds\n"); + cil_list_destroy(&matching, CIL_FALSE); +@@ -4602,14 +4597,17 @@ static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void + bounds_destroy_bad(bad); + goto exit; + } +- + cil_list_for_each(i2, matching) { +- __cil_print_parents(" ", (struct cil_tree_node *)i2->data); ++ struct cil_tree_node *n2 = i2->data; ++ struct cil_avrule *r2 = n2->data; ++ if (n1 == n2) { ++ cil_log(CIL_ERR, " \n"); ++ } else { ++ n1 = n2; ++ __cil_print_parents(" ", n2); ++ __cil_print_rule(" ", "allow", r2); ++ } + } +- i2 = matching->tail; +- n = i2->data; +- __cil_print_rule(" ", "allow", n->data); +- cil_log(CIL_ERR,"\n"); + cil_list_destroy(&matching, CIL_FALSE); + cil_list_destroy(&target.perms.classperms, CIL_TRUE); + } +@@ -4753,20 +4751,32 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p + __cil_set_conditional_state_and_flags(pdb); + + if (db->disable_neverallow != CIL_TRUE) { ++ int violation = CIL_FALSE; + cil_log(CIL_INFO, "Checking Neverallows\n"); +- rc = cil_check_neverallows(db, pdb, neverallows); ++ rc = cil_check_neverallows(db, pdb, neverallows, &violation); + if (rc != SEPOL_OK) goto exit; + + cil_log(CIL_INFO, "Checking User Bounds\n"); +- bounds_check_users(NULL, pdb); ++ rc = bounds_check_users(NULL, pdb); ++ if (rc) { ++ violation = CIL_TRUE; ++ } + + cil_log(CIL_INFO, "Checking Role Bounds\n"); +- bounds_check_roles(NULL, pdb); ++ rc = bounds_check_roles(NULL, pdb); ++ if (rc) { ++ violation = CIL_TRUE; ++ } + + cil_log(CIL_INFO, "Checking Type Bounds\n"); +- rc = cil_check_type_bounds(db, pdb, type_value_to_cil, class_value_to_cil, perm_value_to_cil); ++ rc = cil_check_type_bounds(db, pdb, type_value_to_cil, class_value_to_cil, perm_value_to_cil, &violation); + if (rc != SEPOL_OK) goto exit; + ++ if (violation == CIL_TRUE) { ++ rc = SEPOL_ERR; ++ goto exit; ++ } ++ + } + + 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..90fee8e 100644 --- libsepol-2.5/cil/src/cil_build_ast.c @@ -48,6 +251,23 @@ index 1135e06..90fee8e 100644 } else { cil_log(CIL_ERR, "Invalid protocol\n"); rc = SEPOL_ERR; +diff --git libsepol-2.5/cil/src/cil_find.c libsepol-2.5/cil/src/cil_find.c +index 75de886..8e0688c 100644 +--- libsepol-2.5/cil/src/cil_find.c ++++ libsepol-2.5/cil/src/cil_find.c +@@ -69,7 +69,11 @@ static int cil_type_match_any(struct cil_symtab_datum *d1, struct cil_symtab_dat + /* Both are attributes */ + struct cil_typeattribute *a1 = (struct cil_typeattribute *)d1; + struct cil_typeattribute *a2 = (struct cil_typeattribute *)d2; +- return ebitmap_match_any(a1->types, a2->types); ++ if (d1 == d2) { ++ return CIL_TRUE; ++ } else if (ebitmap_match_any(a1->types, a2->types)) { ++ return CIL_TRUE; ++ } + } + return CIL_FALSE; + } diff --git libsepol-2.5/cil/src/cil_internal.h libsepol-2.5/cil/src/cil_internal.h index a0a5480..a75ddf8 100644 --- libsepol-2.5/cil/src/cil_internal.h @@ -121,11 +341,159 @@ index 697cea4..c07d1fa 100644 /* Key */ extern int sepol_port_compare(const sepol_port_t * port, +diff --git libsepol-2.5/src/assertion.c libsepol-2.5/src/assertion.c +index fbf397f..f4429ad 100644 +--- libsepol-2.5/src/assertion.c ++++ libsepol-2.5/src/assertion.c +@@ -147,36 +147,49 @@ static int report_assertion_extended_permissions(sepol_handle_t *handle, + avtab_key_t tmp_key; + avtab_extended_perms_t *xperms; + avtab_extended_perms_t error; ++ ebitmap_t *sattr = &p->type_attr_map[k->source_type - 1]; ++ ebitmap_t *tattr = &p->type_attr_map[k->target_type - 1]; ++ ebitmap_node_t *snode, *tnode; ++ unsigned int i, j; + int rc = 1; + int ret = 0; + + memcpy(&tmp_key, k, sizeof(avtab_key_t)); + tmp_key.specified = AVTAB_XPERMS_ALLOWED; + +- for (node = avtab_search_node(avtab, &tmp_key); +- node; +- node = avtab_search_node_next(node, tmp_key.specified)) { +- xperms = node->datum.xperms; +- if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) +- && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)) ++ ebitmap_for_each_bit(sattr, snode, i) { ++ if (!ebitmap_node_get_bit(snode, i)) + continue; ++ ebitmap_for_each_bit(tattr, tnode, j) { ++ if (!ebitmap_node_get_bit(tnode, j)) ++ continue; ++ tmp_key.source_type = i + 1; ++ tmp_key.target_type = j + 1; ++ for (node = avtab_search_node(avtab, &tmp_key); ++ node; ++ node = avtab_search_node_next(node, tmp_key.specified)) { ++ xperms = node->datum.xperms; ++ if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) ++ && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)) ++ continue; + +- rc = check_extended_permissions(avrule->xperms, xperms); +- /* failure on the extended permission check_extended_permissionss */ +- if (rc) { +- extended_permissions_violated(&error, avrule->xperms, xperms); +- ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of policy.conf) violated by\n" +- "allowxperm %s %s:%s %s;", +- avrule->source_line, avrule->source_filename, avrule->line, +- p->p_type_val_to_name[stype], +- p->p_type_val_to_name[ttype], +- p->p_class_val_to_name[curperm->tclass - 1], +- sepol_extended_perms_to_string(&error)); +- +- rc = 0; +- ret++; ++ rc = check_extended_permissions(avrule->xperms, xperms); ++ /* failure on the extended permission check_extended_permissionss */ ++ if (rc) { ++ extended_permissions_violated(&error, avrule->xperms, xperms); ++ ERR(handle, "neverallowxperm on line %lu of %s (or line %lu of policy.conf) violated by\n" ++ "allowxperm %s %s:%s %s;", ++ avrule->source_line, avrule->source_filename, avrule->line, ++ p->p_type_val_to_name[stype], ++ p->p_type_val_to_name[ttype], ++ p->p_class_val_to_name[curperm->tclass - 1], ++ sepol_extended_perms_to_string(&error)); ++ ++ rc = 0; ++ ret++; ++ } ++ } + } +- + } + + /* failure on the regular permissions */ +@@ -319,28 +332,42 @@ oom: + * granted + */ + static int check_assertion_extended_permissions(avrule_t *avrule, avtab_t *avtab, +- avtab_key_t *k) ++ avtab_key_t *k, policydb_t *p) + { + avtab_ptr_t node; + avtab_key_t tmp_key; + avtab_extended_perms_t *xperms; + av_extended_perms_t *neverallow_xperms = avrule->xperms; ++ ebitmap_t *sattr = &p->type_attr_map[k->source_type - 1]; ++ ebitmap_t *tattr = &p->type_attr_map[k->target_type - 1]; ++ ebitmap_node_t *snode, *tnode; ++ unsigned int i, j; + int rc = 1; + + memcpy(&tmp_key, k, sizeof(avtab_key_t)); + tmp_key.specified = AVTAB_XPERMS_ALLOWED; + +- for (node = avtab_search_node(avtab, &tmp_key); +- node; +- node = avtab_search_node_next(node, tmp_key.specified)) { +- xperms = node->datum.xperms; +- if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) +- && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)) ++ ebitmap_for_each_bit(sattr, snode, i) { ++ if (!ebitmap_node_get_bit(snode, i)) + continue; +- +- rc = check_extended_permissions(neverallow_xperms, xperms); +- if (rc) +- break; ++ ebitmap_for_each_bit(tattr, tnode, j) { ++ if (!ebitmap_node_get_bit(tnode, j)) ++ continue; ++ tmp_key.source_type = i + 1; ++ tmp_key.target_type = j + 1; ++ for (node = avtab_search_node(avtab, &tmp_key); ++ node; ++ node = avtab_search_node_next(node, tmp_key.specified)) { ++ xperms = node->datum.xperms; ++ ++ if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) ++ && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)) ++ continue; ++ rc = check_extended_permissions(neverallow_xperms, xperms); ++ if (rc) ++ break; ++ } ++ } + } + + return rc; +@@ -386,7 +413,7 @@ static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *a + goto exit; + + if (avrule->specified == AVRULE_XPERMS_NEVERALLOW) { +- rc = check_assertion_extended_permissions(avrule, avtab, k); ++ rc = check_assertion_extended_permissions(avrule, avtab, k, p); + if (rc == 0) + goto exit; + } diff --git libsepol-2.5/src/module_to_cil.c libsepol-2.5/src/module_to_cil.c -index 18ec6b9..b478d9f 100644 +index 18ec6b9..38f0dc3 100644 --- libsepol-2.5/src/module_to_cil.c +++ libsepol-2.5/src/module_to_cil.c -@@ -2537,6 +2537,7 @@ static int ocontext_selinux_port_to_cil(struct policydb *pdb, struct ocontext *p +@@ -26,6 +26,9 @@ + #include + #include + #include ++#ifndef IPPROTO_DCCP ++#define IPPROTO_DCCP 33 ++#endif + #include + #include + #include +@@ -2537,6 +2540,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; @@ -147,10 +515,18 @@ index 6a33d93..ed9093b 100644 return "???"; } diff --git libsepol-2.5/src/ports.c libsepol-2.5/src/ports.c -index 607a629..b1ee094 100644 +index 607a629..62ec602 100644 --- libsepol-2.5/src/ports.c +++ libsepol-2.5/src/ports.c -@@ -16,6 +16,8 @@ static inline int sepol2ipproto(sepol_handle_t * handle, int proto) +@@ -1,4 +1,7 @@ + #include ++#ifndef IPPROTO_DCCP ++#define IPPROTO_DCCP 33 ++#endif + #include + + #include "debug.h" +@@ -16,6 +19,8 @@ static inline int sepol2ipproto(sepol_handle_t * handle, int proto) return IPPROTO_TCP; case SEPOL_PROTO_UDP: return IPPROTO_UDP; @@ -159,7 +535,7 @@ index 607a629..b1ee094 100644 default: ERR(handle, "unsupported protocol %u", proto); return STATUS_ERR; -@@ -30,6 +32,8 @@ static inline int ipproto2sepol(sepol_handle_t * handle, int proto) +@@ -30,6 +35,8 @@ static inline int ipproto2sepol(sepol_handle_t * handle, int proto) return SEPOL_PROTO_TCP; case IPPROTO_UDP: return SEPOL_PROTO_UDP; diff --git a/libsepol.spec b/libsepol.spec index 529f6a5..09c8e74 100644 --- a/libsepol.spec +++ b/libsepol.spec @@ -1,15 +1,15 @@ Summary: SELinux binary policy manipulation library Name: libsepol Version: 2.5 -Release: 3%{?dist} +Release: 4%{?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/4bfb84c7ff7b33cf06b9a6b2317d24054b9db562 -# Patch1: libsepol-fedora.patch +# HEAD https://github.com/fedora-selinux/selinux/commit/f900ff37022119de47d516f103ccfd339d52c861 +Patch1: libsepol-fedora.patch URL: https://github.com/SELinuxProject/selinux/wiki BuildRequires: flex @@ -106,6 +106,12 @@ exit 0 %{_libdir}/libsepol.so.1 %changelog +* Fri Apr 29 2016 Petr Lautrbach - 2.5-4 +- Build policy on systems not supporting DCCP protocol +- Fix extended permissions neverallow checking +- Fix CIL neverallow and bounds checking +- Android.mk: Add -D_GNU_SOURCE to common_cflags + * Fri Apr 08 2016 Petr Lautrbach - 2.5-3 - Fix bug in CIL when resetting classes - Add support for portcon dccp protocol