diff --git libsepol-2.5/Android.mk libsepol-2.5/Android.mk index a43b343..21c1af8 100644 --- libsepol-2.5/Android.mk +++ libsepol-2.5/Android.mk @@ -68,10 +68,6 @@ common_cflags := \ -Wshadow -Wmissing-noreturn \ -Wmissing-format-attribute -ifeq ($(HOST_OS), darwin) -common_cflags += -DDARWIN -endif - common_includes := \ $(LOCAL_PATH)/include/ \ $(LOCAL_PATH)/src/ \ diff --git libsepol-2.5/ChangeLog libsepol-2.5/ChangeLog index ace3d54..c7cc464 100644 --- libsepol-2.5/ChangeLog +++ libsepol-2.5/ChangeLog @@ -1,3 +1,25 @@ + * 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. + * Correctly detect unknown classes in sepol_string_to_security_class, from Joshua Brindle. + * Sort object files for deterministic linking order, from Laurent Bigonville. + * Fix neverallowxperm checking on attributes, from Jeff Vander Stoep. + * Remove libsepol.map when cleaning, from Nicolas Iooss. + * Add high-level language line marking support to CIL, from James Carter. + * Change logic of bounds checking to match change in kernel, from James Carter. + * Fix multiple spelling errors, from Laurent Bigonville. + * Only apply bounds checking to source types in rules, from Stephen Smalley. + * Fix CIL and not add an attribute as a type in the attr_type_map, from James Carter + * 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 + 2.5 2016-02-23 * Fix unused variable annotations, from Nicolas Iooss. * Fix uninitialized variable in CIL, from Nicolas Iooss. diff --git libsepol-2.5/cil/src/cil.c libsepol-2.5/cil/src/cil.c index afdc240..9b2c45b 100644 --- libsepol-2.5/cil/src/cil.c +++ libsepol-2.5/cil/src/cil.c @@ -108,6 +108,7 @@ static void cil_init_keys(void) CIL_KEY_STAR = cil_strpool_add("*"); CIL_KEY_UDP = cil_strpool_add("udp"); CIL_KEY_TCP = cil_strpool_add("tcp"); + CIL_KEY_DCCP = cil_strpool_add("dccp"); CIL_KEY_AUDITALLOW = cil_strpool_add("auditallow"); CIL_KEY_TUNABLEIF = cil_strpool_add("tunableif"); CIL_KEY_ALLOW = cil_strpool_add("allow"); @@ -186,6 +187,8 @@ static void cil_init_keys(void) CIL_KEY_MLSVALIDATETRANS = cil_strpool_add("mlsvalidatetrans"); CIL_KEY_CONTEXT = cil_strpool_add("context"); CIL_KEY_FILECON = cil_strpool_add("filecon"); + CIL_KEY_IBPKEYCON = cil_strpool_add("ibpkeycon"); + CIL_KEY_IBENDPORTCON = cil_strpool_add("ibendportcon"); CIL_KEY_PORTCON = cil_strpool_add("portcon"); CIL_KEY_NODECON = cil_strpool_add("nodecon"); CIL_KEY_GENFSCON = cil_strpool_add("genfscon"); @@ -232,6 +235,9 @@ static void cil_init_keys(void) CIL_KEY_PERMISSIONX = cil_strpool_add("permissionx"); CIL_KEY_IOCTL = cil_strpool_add("ioctl"); CIL_KEY_UNORDERED = cil_strpool_add("unordered"); + CIL_KEY_SRC_INFO = cil_strpool_add(""); + CIL_KEY_SRC_CIL = cil_strpool_add(""); + CIL_KEY_SRC_HLL = cil_strpool_add(""); } void cil_db_init(struct cil_db **db) @@ -252,6 +258,8 @@ void cil_db_init(struct cil_db **db) cil_sort_init(&(*db)->genfscon); cil_sort_init(&(*db)->filecon); cil_sort_init(&(*db)->nodecon); + cil_sort_init(&(*db)->ibpkeycon); + cil_sort_init(&(*db)->ibendportcon); cil_sort_init(&(*db)->portcon); cil_sort_init(&(*db)->pirqcon); cil_sort_init(&(*db)->iomemcon); @@ -301,6 +309,8 @@ void cil_db_destroy(struct cil_db **db) cil_sort_destroy(&(*db)->genfscon); cil_sort_destroy(&(*db)->filecon); cil_sort_destroy(&(*db)->nodecon); + cil_sort_destroy(&(*db)->ibpkeycon); + cil_sort_destroy(&(*db)->ibendportcon); cil_sort_destroy(&(*db)->portcon); cil_sort_destroy(&(*db)->pirqcon); cil_sort_destroy(&(*db)->iomemcon); @@ -712,9 +722,15 @@ void cil_destroy_data(void **data, enum cil_flavor flavor) case CIL_FILECON: cil_destroy_filecon(*data); break; + case CIL_IBPKEYCON: + cil_destroy_ibpkeycon(*data); + break; case CIL_PORTCON: cil_destroy_portcon(*data); break; + case CIL_IBENDPORTCON: + cil_destroy_ibendportcon(*data); + break; case CIL_NODECON: cil_destroy_nodecon(*data); break; @@ -756,6 +772,9 @@ void cil_destroy_data(void **data, enum cil_flavor flavor) case CIL_MLS: cil_destroy_mls(*data); break; + case CIL_SRC_INFO: + cil_destroy_src_info(*data); + break; case CIL_OP: case CIL_CONS_OPERAND: break; @@ -763,8 +782,8 @@ void cil_destroy_data(void **data, enum cil_flavor flavor) cil_log(CIL_INFO, "Unknown data flavor: %d\n", flavor); break; } - - *data = NULL; + + *data = NULL; } int cil_flavor_to_symtab_index(enum cil_flavor flavor, enum cil_sym_index *sym_index) @@ -1076,6 +1095,10 @@ const char * cil_node_to_string(struct cil_tree_node *node) return CIL_KEY_FSUSE; case CIL_FILECON: return CIL_KEY_FILECON; + case CIL_IBPKEYCON: + return CIL_KEY_IBPKEYCON; + case CIL_IBENDPORTCON: + return CIL_KEY_IBENDPORTCON; case CIL_PORTCON: return CIL_KEY_PORTCON; case CIL_NODECON: @@ -1108,6 +1131,8 @@ const char * cil_node_to_string(struct cil_tree_node *node) return CIL_KEY_HANDLEUNKNOWN; case CIL_MLS: return CIL_KEY_MLS; + case CIL_SRC_INFO: + return CIL_KEY_SRC_INFO; case CIL_ALL: return CIL_KEY_ALL; case CIL_RANGE: @@ -1755,8 +1780,7 @@ int cil_get_symtab(struct cil_tree_node *ast_node, symtab_t **symtab, enum cil_s return SEPOL_OK; exit: - cil_log(CIL_ERR, "Failed to get symtab from node at line %d of %s\n", - ast_node->line, ast_node->path); + cil_tree_log(ast_node, CIL_ERR, "Failed to get symtab from node"); return SEPOL_ERR; } @@ -1796,6 +1820,16 @@ void cil_netifcon_init(struct cil_netifcon **netifcon) (*netifcon)->context_str = NULL; } +void cil_ibendportcon_init(struct cil_ibendportcon **ibendportcon) +{ + *ibendportcon = cil_malloc(sizeof(**ibendportcon)); + + (*ibendportcon)->dev_name_str = NULL; + (*ibendportcon)->port = 0; + (*ibendportcon)->context_str = NULL; + (*ibendportcon)->context = NULL; +} + void cil_context_init(struct cil_context **context) { *context = cil_malloc(sizeof(**context)); @@ -2212,6 +2246,17 @@ void cil_filecon_init(struct cil_filecon **filecon) (*filecon)->context = NULL; } +void cil_ibpkeycon_init(struct cil_ibpkeycon **ibpkeycon) +{ + *ibpkeycon = cil_malloc(sizeof(**ibpkeycon)); + + (*ibpkeycon)->subnet_prefix_str = NULL; + (*ibpkeycon)->pkey_low = 0; + (*ibpkeycon)->pkey_high = 0; + (*ibpkeycon)->context_str = NULL; + (*ibpkeycon)->context = NULL; +} + void cil_portcon_init(struct cil_portcon **portcon) { *portcon = cil_malloc(sizeof(**portcon)); @@ -2553,3 +2598,10 @@ void cil_mls_init(struct cil_mls **mls) *mls = cil_malloc(sizeof(**mls)); (*mls)->value = 0; } + +void cil_src_info_init(struct cil_src_info **info) +{ + *info = cil_malloc(sizeof(**info)); + (*info)->is_cil = 0; + (*info)->path = NULL; +} diff --git libsepol-2.5/cil/src/cil_binary.c libsepol-2.5/cil/src/cil_binary.c index f749e53..c507124 100644 --- libsepol-2.5/cil/src/cil_binary.c +++ libsepol-2.5/cil/src/cil_binary.c @@ -31,6 +31,9 @@ #include #include #include +#ifndef IPPROTO_DCCP +#define IPPROTO_DCCP 33 +#endif #include #include @@ -606,9 +609,11 @@ int __cil_typeattr_bitmap_init(policydb_t *pdb) rc = SEPOL_ERR; goto exit; } - if (ebitmap_set_bit(&pdb->attr_type_map[i], i, 1)) { - rc = SEPOL_ERR; - goto exit; + if (pdb->type_val_to_struct[i] && pdb->type_val_to_struct[i]->flavor != TYPE_ATTRIB) { + if (ebitmap_set_bit(&pdb->attr_type_map[i], i, 1)) { + rc = SEPOL_ERR; + goto exit; + } } } @@ -749,6 +754,12 @@ int cil_userrole_to_policydb(policydb_t *pdb, const struct cil_db *db, struct ci goto exit; } + if (sepol_role->s.value == 1) { + // role is object_r, ignore it since it is implicitly associated + // with all users + continue; + } + 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; @@ -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) { cil_log(CIL_ERR, "typetransition with file name not allowed within a booleanif block.\n"); - cil_log(CIL_ERR,"Invalid typetransition statement at line %d of %s\n", - node->line, node->path); + cil_tree_log(node, CIL_ERR,"Invalid typetransition statement"); goto exit; } rc = __cil_typetransition_to_avtab(pdb, db, cil_typetrans, cond_node, cond_flavor, filename_trans_table); if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to insert type transition into avtab at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Failed to insert type transition into avtab"); goto exit; } break; @@ -1784,7 +1794,7 @@ int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unu cil_type_rule = node->data; rc = __cil_type_rule_to_avtab(pdb, db, cil_type_rule, cond_node, cond_flavor); if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to insert typerule into avtab at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Failed to insert typerule into avtab"); goto exit; } break; @@ -1792,7 +1802,7 @@ int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unu cil_avrule = node->data; rc = __cil_avrule_to_avtab(pdb, db, cil_avrule, cond_node, cond_flavor); if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to insert avrule into avtab at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Failed to insert avrule into avtab"); goto exit; } break; @@ -1800,8 +1810,7 @@ int __cil_cond_to_policydb_helper(struct cil_tree_node *node, __attribute__((unu case CIL_TUNABLEIF: break; default: - cil_log(CIL_ERR, "Invalid statement within booleanif at line %d of %s\n", - node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid statement within booleanif"); goto exit; } @@ -2060,14 +2069,13 @@ int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c tmp_cond = cond_node_create(pdb, NULL); if (tmp_cond == NULL) { rc = SEPOL_ERR; - cil_log(CIL_INFO, "Failed to create sepol conditional node at line %d of %s\n", - node->line, node->path); + cil_tree_log(node, CIL_INFO, "Failed to create sepol conditional node"); goto exit; } rc = __cil_cond_expr_to_sepol_expr(pdb, cil_boolif->datum_expr, &tmp_cond->expr); if (rc != SEPOL_OK) { - cil_log(CIL_INFO, "Failed to convert CIL conditional expression to sepol expression at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_INFO, "Failed to convert CIL conditional expression to sepol expression"); goto exit; } @@ -2123,7 +2131,7 @@ int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c bool_args.cond_flavor = CIL_CONDTRUE; rc = cil_tree_walk(true_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args); if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failure while walking true conditional block at line %d of %s\n", true_node->line, true_node->path); + cil_tree_log(true_node, CIL_ERR, "Failure while walking true conditional block"); goto exit; } } @@ -2132,7 +2140,7 @@ int cil_booleanif_to_policydb(policydb_t *pdb, const struct cil_db *db, struct c bool_args.cond_flavor = CIL_CONDFALSE; rc = cil_tree_walk(false_node, __cil_cond_to_policydb_helper, NULL, NULL, &bool_args); if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failure while walking false conditional block at line %d of %s\n", false_node->line, false_node->path); + cil_tree_log(false_node, CIL_ERR, "Failure while walking false conditional block"); goto exit; } } @@ -3018,6 +3026,40 @@ exit: return rc; } +int cil_ibpkeycon_to_policydb(policydb_t *pdb, struct cil_sort *ibpkeycons) +{ + int rc = SEPOL_ERR; + uint32_t i = 0; + ocontext_t *tail = NULL; + struct in6_addr subnet_prefix; + + for (i = 0; i < ibpkeycons->count; i++) { + struct cil_ibpkeycon *cil_ibpkeycon = ibpkeycons->array[i]; + ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_IBPKEY], &tail); + + rc = inet_pton(AF_INET6, cil_ibpkeycon->subnet_prefix_str, &subnet_prefix); + if (rc != 1) { + cil_log(CIL_ERR, "ibpkeycon subnet prefix not in valid IPV6 format\n"); + rc = SEPOL_ERR; + goto exit; + } + + memcpy(&new_ocon->u.ibpkey.subnet_prefix, &subnet_prefix.s6_addr[0], + sizeof(new_ocon->u.ibpkey.subnet_prefix)); + new_ocon->u.ibpkey.low_pkey = cil_ibpkeycon->pkey_low; + new_ocon->u.ibpkey.high_pkey = cil_ibpkeycon->pkey_high; + + rc = __cil_context_to_sepol_context(pdb, cil_ibpkeycon->context, &new_ocon->context[0]); + if (rc != SEPOL_OK) + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + int cil_portcon_to_policydb(policydb_t *pdb, struct cil_sort *portcons) { int rc = SEPOL_ERR; @@ -3035,6 +3077,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; + case CIL_PROTOCOL_DCCP: + new_ocon->u.port.protocol = IPPROTO_DCCP; + break; default: /* should not get here */ rc = SEPOL_ERR; @@ -3086,6 +3131,30 @@ exit: return rc; } +int cil_ibendportcon_to_policydb(policydb_t *pdb, struct cil_sort *ibendportcons) +{ + int rc = SEPOL_ERR; + uint32_t i; + ocontext_t *tail = NULL; + + for (i = 0; i < ibendportcons->count; i++) { + ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_IBENDPORT], &tail); + struct cil_ibendportcon *cil_ibendportcon = ibendportcons->array[i]; + + new_ocon->u.ibendport.dev_name = cil_strdup(cil_ibendportcon->dev_name_str); + new_ocon->u.ibendport.port = cil_ibendportcon->port; + + rc = __cil_context_to_sepol_context(pdb, cil_ibendportcon->context, &new_ocon->context[0]); + if (rc != SEPOL_OK) + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + int cil_nodecon_to_policydb(policydb_t *pdb, struct cil_sort *nodecons) { int rc = SEPOL_ERR; @@ -3583,7 +3652,7 @@ int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args) exit: if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Binary policy creation failed at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Binary policy creation failed"); } return rc; } @@ -3645,6 +3714,16 @@ int __cil_contexts_to_policydb(policydb_t *pdb, const struct cil_db *db) goto exit; } + rc = cil_ibpkeycon_to_policydb(pdb, db->ibpkeycon); + if (rc != SEPOL_OK) { + goto exit; + } + + rc = cil_ibendportcon_to_policydb(pdb, db->ibendportcon); + if (rc != SEPOL_OK) { + goto exit; + } + if (db->target_platform == SEPOL_TARGET_XEN) { rc = cil_pirqcon_to_policydb(pdb, db->pirqcon); if (rc != SEPOL_OK) { @@ -4227,6 +4306,9 @@ exit: static avrule_t *__cil_init_sepol_avrule(uint32_t kind, struct cil_tree_node *node) { avrule_t *avrule; + struct cil_tree_node *source_node; + char *source_path; + int is_cil; avrule = cil_malloc(sizeof(avrule_t)); avrule->specified = kind; @@ -4235,8 +4317,17 @@ static avrule_t *__cil_init_sepol_avrule(uint32_t kind, struct cil_tree_node *no __cil_init_sepol_type_set(&avrule->ttypes); avrule->perms = NULL; avrule->line = node->line; - avrule->source_filename = node->path; + + avrule->source_filename = NULL; avrule->source_line = node->line; + source_node = cil_tree_get_next_path(node, &source_path, &is_cil); + if (source_node) { + avrule->source_filename = source_path; + if (!is_cil) { + avrule->source_line = node->hll_line; + } + } + avrule->next = NULL; return avrule; } @@ -4263,10 +4354,8 @@ static void __cil_print_parents(const char *pad, struct cil_tree_node *n) __cil_print_parents(pad, n->parent); - if (!n->path) { - cil_log(CIL_ERR,"%s%s\n", pad, cil_node_to_string(n)); - } else { - cil_log(CIL_ERR,"%s%s at line %d of %s\n", pad, cil_node_to_string(n), n->line, n->path); + if (n->flavor != CIL_SRC_INFO) { + cil_tree_log(n, CIL_ERR,"%s%s", pad, cil_node_to_string(n)); } } @@ -4357,7 +4446,7 @@ static int __cil_print_neverallow_failure(const struct cil_db *db, struct cil_tr allow_str = CIL_KEY_ALLOWX; avrule_flavor = CIL_AVRULEX; } - cil_log(CIL_ERR, "%s check failed at line %d of %s\n", neverallow_str, node->line, node->path); + cil_tree_log(node, CIL_ERR, "%s check failed", neverallow_str); __cil_print_rule(" ", neverallow_str, cil_rule); cil_list_init(&matching, CIL_NODE); rc = cil_find_matching_avrule_in_ast(db->ast->root, avrule_flavor, &target, matching, CIL_FALSE); @@ -4380,10 +4469,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 +4510,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 +4532,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 +4553,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 +4624,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 +4650,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 +4664,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 +4672,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 +4680,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 +4834,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_binary.h libsepol-2.5/cil/src/cil_binary.h index c59b1e3..5367feb 100644 --- libsepol-2.5/cil/src/cil_binary.h +++ libsepol-2.5/cil/src/cil_binary.h @@ -330,6 +330,30 @@ int cil_sepol_level_define(policydb_t *pdb, struct cil_sens *cil_sens); int cil_rangetransition_to_policydb(policydb_t *pdb, const struct cil_db *db, struct cil_rangetransition *rangetrans, hashtab_t range_trans_table); /** + * Insert cil ibpkeycon structure into sepol policydb. + * The function is given a structure containing the sorted ibpkeycons and + * loops over this structure inserting them into the policy database. + * + * @param[in] pdb The policy database to insert the ibpkeycon into. + * @param[in] node The cil_sort structure that contains the sorted ibpkeycons. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_ibpkeycon_to_policydb(policydb_t *pdb, struct cil_sort *ibpkeycons); + +/** + * Insert cil idbev structure into sepol policydb. + * The function is given a structure containing the sorted ibendportcons and + * loops over this structure inserting them into the policy database. + * + * @param[in] pdb The policy database to insert the pkeycon into. + * @param[in] node The cil_sort structure that contains the sorted ibendportcons. + * + * @return SEPOL_OK upon success or an error otherwise. + */ +int cil_ibendportcon_to_policydb(policydb_t *pdb, struct cil_sort *pkeycons); + +/** * Insert cil portcon structure into sepol policydb. * The function is given a structure containing the sorted portcons and * loops over this structure inserting them into the policy database. diff --git libsepol-2.5/cil/src/cil_build_ast.c libsepol-2.5/cil/src/cil_build_ast.c index 1135e06..855e2b4 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 if (cil_symtab_get_datum(symtab, key, &datum) == SEPOL_OK) { if (sflavor == CIL_SYM_BLOCKS) { struct cil_tree_node *node = datum->nodes->head->data; - cil_log(CIL_ERR, "Previous declaration at line %d of %s\n", - node->line, node->path); + cil_tree_log(node, CIL_ERR, "Previous declaration"); } } goto exit; @@ -186,8 +185,7 @@ int cil_gen_block(struct cil_db *db, struct cil_tree_node *parse_current, struct return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad block declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad block declaration"); cil_destroy_block(block); cil_clear_node(ast_node); return rc; @@ -236,8 +234,7 @@ int cil_gen_blockinherit(struct cil_db *db, struct cil_tree_node *parse_current, return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad blockinherit declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad blockinherit declaration"); cil_destroy_blockinherit(inherit); return rc; } @@ -281,8 +278,7 @@ int cil_gen_blockabstract(struct cil_db *db, struct cil_tree_node *parse_current return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad blockabstract declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad blockabstract declaration"); cil_destroy_blockabstract(abstract); return rc; } @@ -326,8 +322,7 @@ int cil_gen_in(struct cil_db *db, struct cil_tree_node *parse_current, struct ci return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad in statement at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad in statement"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad class declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad class declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad classorder declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad classorder declaration"); 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 cil_tree_node_init(&new_ast); new_ast->parent = ast_node; new_ast->line = current_perm->line; - new_ast->path = current_perm->path; + new_ast->hll_line = current_perm->hll_line; 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad classpermission declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad classpermission declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad classpermissionset at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad classpermissionset"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad map class declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad map class declaration"); 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, return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad classmapping declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad classmapping declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad common declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad common declaration"); 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, return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad classcommon declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad classcommon declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad sid declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad sid declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad sidcontext declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad sidcontext declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad sidorder declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad sidorder declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad user declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad user declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad userattribute declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad userattribute declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad userattributeset declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad userattributeset declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad userlevel declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad userlevel declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad userrange declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad userrange declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad userprefix declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad userprefix declaration"); cil_destroy_userprefix(userprefix); return rc; } @@ -1566,8 +1544,7 @@ int cil_gen_selinuxuser(struct cil_db *db, struct cil_tree_node *parse_current, return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad selinuxuser declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad selinuxuser declaration"); cil_destroy_selinuxuser(selinuxuser); return rc; } @@ -1614,8 +1591,7 @@ int cil_gen_selinuxuserdefault(struct cil_db *db, struct cil_tree_node *parse_cu return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad selinuxuserdefault declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad selinuxuserdefault declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad role declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad role declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad roletype declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad roletype declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad userrole declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad userrole declaration"); cil_destroy_userrole(userrole); return rc; } @@ -1815,8 +1788,7 @@ int cil_gen_roletransition(struct cil_tree_node *parse_current, struct cil_tree_ return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad roletransition rule at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad roletransition rule"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad roleallow rule at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad roleallow rule"); cil_destroy_roleallow(roleallow); return rc; } @@ -1914,8 +1885,7 @@ int cil_gen_roleattribute(struct cil_db *db, struct cil_tree_node *parse_current return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad roleattribute declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad roleattribute declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad roleattributeset declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad roleattributeset declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad allow rule at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad allow rule"); cil_destroy_avrule(rule); return rc; } @@ -2099,8 +2067,7 @@ int cil_fill_permissionx(struct cil_tree_node *parse_current, struct cil_permiss return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad permissionx content at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad permissionx content"); return rc; } @@ -2143,8 +2110,7 @@ int cil_gen_permissionx(struct cil_db *db, struct cil_tree_node *parse_current, return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad permissionx statement at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad permissionx statement"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad allowx rule at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad allowx rule"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad type rule at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad type rule"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad type declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad type declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad typeattribute declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad typeattribute declaration"); 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 exit: if (tunableif) { - cil_log(CIL_ERR, "Bad tunable (treated as a boolean due to preserve-tunables) declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad tunable (treated as a boolean due to preserve-tunables) declaration"); } else { - cil_log(CIL_ERR, "Bad boolean declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad boolean declaration"); } 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad tunable declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad tunable declaration"); 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 exit: if (tunableif) { - cil_log(CIL_ERR, "Bad tunableif (treated as a booleanif due to preserve-tunables) declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad tunableif (treated as a booleanif due to preserve-tunables) declaration"); } else { - cil_log(CIL_ERR, "Bad booleanif declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad booleanif declaration"); } 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad tunableif declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad tunableif declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad %s condition declaration at line %d of %s\n", - (char*)parse_current->data, parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad %s condition declaration", + (char*)parse_current->data); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad %s declaration at line %d of %s\n", - (char*)parse_current->data, parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad %s declaration", (char*)parse_current->data); 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, return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad %s association at line %d of %s\n", - cil_node_to_string(parse_current),parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad %s association", cil_node_to_string(parse_current)); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad typeattributeset statement at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad typeattributeset statement"); cil_destroy_typeattributeset(attrset); return rc; } @@ -3235,8 +3188,7 @@ int cil_gen_typepermissive(struct cil_db *db, struct cil_tree_node *parse_curren return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad typepermissive declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad typepermissive declaration"); cil_destroy_typepermissive(typeperm); return rc; } @@ -3319,8 +3271,7 @@ int cil_gen_typetransition(struct cil_db *db, struct cil_tree_node *parse_curren return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad typetransition declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad typetransition declaration"); return rc; } @@ -3391,8 +3342,7 @@ int cil_gen_rangetransition(struct cil_db *db, struct cil_tree_node *parse_curre return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad rangetransition declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad rangetransition declaration"); cil_destroy_rangetransition(rangetrans); return rc; } @@ -3443,8 +3393,7 @@ int cil_gen_sensitivity(struct cil_db *db, struct cil_tree_node *parse_current, return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad sensitivity declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad sensitivity declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad category declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad category declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad categoryset declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad categoryset declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad categoryorder declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad categoryorder declaration"); cil_destroy_catorder(catorder); return rc; } @@ -3675,8 +3621,7 @@ int cil_gen_sensitivityorder(struct cil_db *db, struct cil_tree_node *parse_curr return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad sensitivityorder declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad sensitivityorder declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad sensitivitycategory declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad sensitivitycategory declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad level declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad level declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad levelrange declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad levelrange declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad constrain declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad constrain declaration"); cil_destroy_constrain(cons); return rc; } @@ -4013,8 +3954,7 @@ int cil_gen_validatetrans(struct cil_db *db, struct cil_tree_node *parse_current return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad validatetrans declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad validatetrans declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad context declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad context declaration"); 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 return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad filecon declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad filecon declaration"); cil_destroy_filecon(filecon); return rc; } @@ -4231,6 +4169,89 @@ void cil_destroy_filecon(struct cil_filecon *filecon) free(filecon); } +int cil_gen_ibpkeycon(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + int syntax_len = sizeof(syntax) / sizeof(*syntax); + int rc = SEPOL_ERR; + struct cil_ibpkeycon *ibpkeycon = NULL; + + if (!db || !parse_current || !ast_node) + goto exit; + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) + goto exit; + + cil_ibpkeycon_init(&ibpkeycon); + + ibpkeycon->subnet_prefix_str = parse_current->next->data; + + if (parse_current->next->next->cl_head) { + if (parse_current->next->next->cl_head->next && + !parse_current->next->next->cl_head->next->next) { + rc = cil_fill_integer(parse_current->next->next->cl_head, &ibpkeycon->pkey_low); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Improper ibpkey specified\n"); + goto exit; + } + rc = cil_fill_integer(parse_current->next->next->cl_head->next, &ibpkeycon->pkey_high); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Improper ibpkey specified\n"); + goto exit; + } + } else { + cil_log(CIL_ERR, "Improper ibpkey range specified\n"); + rc = SEPOL_ERR; + goto exit; + } + } else { + rc = cil_fill_integer(parse_current->next->next, &ibpkeycon->pkey_low); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Improper ibpkey specified\n"); + goto exit; + } + ibpkeycon->pkey_high = ibpkeycon->pkey_low; + } + + if (!parse_current->next->next->next->cl_head) { + ibpkeycon->context_str = parse_current->next->next->next->data; + } else { + cil_context_init(&ibpkeycon->context); + + rc = cil_fill_context(parse_current->next->next->next->cl_head, ibpkeycon->context); + if (rc != SEPOL_OK) + goto exit; + } + + ast_node->data = ibpkeycon; + ast_node->flavor = CIL_IBPKEYCON; + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad ibpkeycon declaration"); + cil_destroy_ibpkeycon(ibpkeycon); + + return rc; +} + +void cil_destroy_ibpkeycon(struct cil_ibpkeycon *ibpkeycon) +{ + if (!ibpkeycon) + return; + + if (!ibpkeycon->context_str && ibpkeycon->context) + cil_destroy_context(ibpkeycon->context); + + free(ibpkeycon); +} + int cil_gen_portcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) { enum cil_syntax syntax[] = { @@ -4261,6 +4282,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; + } else if (proto == CIL_KEY_DCCP) { + portcon->proto = CIL_PROTOCOL_DCCP; } else { cil_log(CIL_ERR, "Invalid protocol\n"); rc = SEPOL_ERR; @@ -4311,8 +4334,7 @@ int cil_gen_portcon(struct cil_db *db, struct cil_tree_node *parse_current, stru return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad portcon declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad portcon declaration"); cil_destroy_portcon(portcon); return rc; } @@ -4393,8 +4415,7 @@ int cil_gen_nodecon(struct cil_db *db, struct cil_tree_node *parse_current, stru return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad nodecon declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad nodecon declaration"); cil_destroy_nodecon(nodecon); return rc; } @@ -4464,8 +4485,7 @@ int cil_gen_genfscon(struct cil_db *db, struct cil_tree_node *parse_current, str return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad genfscon declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad genfscon declaration"); cil_destroy_genfscon(genfscon); return SEPOL_ERR; } @@ -4538,8 +4558,7 @@ int cil_gen_netifcon(struct cil_db *db, struct cil_tree_node *parse_current, str return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad netifcon declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad netifcon declaration"); cil_destroy_netifcon(netifcon); return SEPOL_ERR; } @@ -4561,6 +4580,68 @@ void cil_destroy_netifcon(struct cil_netifcon *netifcon) free(netifcon); } +int cil_gen_ibendportcon(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + enum cil_syntax syntax[] = { + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING, + CIL_SYN_STRING | CIL_SYN_LIST, + CIL_SYN_END + }; + int syntax_len = sizeof(syntax) / sizeof(*syntax); + int rc = SEPOL_ERR; + struct cil_ibendportcon *ibendportcon = NULL; + + if (!db || !parse_current || !ast_node) + goto exit; + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) + goto exit; + + cil_ibendportcon_init(&ibendportcon); + + ibendportcon->dev_name_str = parse_current->next->data; + + rc = cil_fill_integer(parse_current->next->next, &ibendportcon->port); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Improper ibendport port specified\n"); + goto exit; + } + + if (!parse_current->next->next->next->cl_head) { + ibendportcon->context_str = parse_current->next->next->data; + } else { + cil_context_init(&ibendportcon->context); + + rc = cil_fill_context(parse_current->next->next->next->cl_head, ibendportcon->context); + if (rc != SEPOL_OK) + goto exit; + } + + ast_node->data = ibendportcon; + ast_node->flavor = CIL_IBENDPORTCON; + + return SEPOL_OK; + +exit: + cil_tree_log(parse_current, CIL_ERR, "Bad ibendportcon declaration"); + cil_destroy_ibendportcon(ibendportcon); + return SEPOL_ERR; +} + +void cil_destroy_ibendportcon(struct cil_ibendportcon *ibendportcon) +{ + if (!ibendportcon) + return; + + if (!ibendportcon->context_str && ibendportcon->context) + cil_destroy_context(ibendportcon->context); + + free(ibendportcon); +} + int cil_gen_pirqcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) { enum cil_syntax syntax[] = { @@ -4606,8 +4687,7 @@ int cil_gen_pirqcon(struct cil_db *db, struct cil_tree_node *parse_current, stru return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad pirqcon declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad pirqcon declaration"); cil_destroy_pirqcon(pirqcon); return rc; } @@ -4692,8 +4772,7 @@ int cil_gen_iomemcon(struct cil_db *db, struct cil_tree_node *parse_current, str return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad iomemcon declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad iomemcon declaration"); cil_destroy_iomemcon(iomemcon); return rc; } @@ -4778,8 +4857,7 @@ int cil_gen_ioportcon(struct cil_db *db, struct cil_tree_node *parse_current, st return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad ioportcon declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad ioportcon declaration"); cil_destroy_ioportcon(ioportcon); return rc; } @@ -4842,8 +4920,7 @@ int cil_gen_pcidevicecon(struct cil_db *db, struct cil_tree_node *parse_current, return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad pcidevicecon declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad pcidevicecon declaration"); cil_destroy_pcidevicecon(pcidevicecon); return rc; } @@ -4903,8 +4980,7 @@ int cil_gen_devicetreecon(struct cil_db *db, struct cil_tree_node *parse_current return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad devicetreecon declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad devicetreecon declaration"); cil_destroy_devicetreecon(devicetreecon); return rc; } @@ -4979,8 +5055,7 @@ int cil_gen_fsuse(struct cil_db *db, struct cil_tree_node *parse_current, struct return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad fsuse declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad fsuse declaration"); cil_destroy_fsuse(fsuse); return SEPOL_ERR; } @@ -5137,8 +5212,7 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad macro declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad macro declaration"); cil_destroy_macro(macro); cil_clear_node(ast_node); return SEPOL_ERR; @@ -5196,8 +5270,7 @@ int cil_gen_call(struct cil_db *db, struct cil_tree_node *parse_current, struct return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad macro call at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad macro call"); cil_destroy_call(call); return rc; } @@ -5299,8 +5372,7 @@ int cil_gen_optional(struct cil_db *db, struct cil_tree_node *parse_current, str return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad optional at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad optional"); cil_destroy_optional(optional); cil_clear_node(ast_node); return rc; @@ -5348,8 +5420,7 @@ int cil_gen_policycap(struct cil_db *db, struct cil_tree_node *parse_current, st return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad policycap statement at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad policycap statement"); cil_destroy_policycap(polcap); cil_clear_node(ast_node); return rc; @@ -5404,8 +5475,7 @@ int cil_gen_ipaddr(struct cil_db *db, struct cil_tree_node *parse_current, struc return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad ipaddr statement at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad ipaddr statement"); cil_destroy_ipaddr(ipaddr); cil_clear_node(ast_node); return rc; @@ -5609,8 +5679,7 @@ int cil_gen_bounds(struct cil_db *db, struct cil_tree_node *parse_current, struc return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad bounds declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad bounds declaration"); cil_destroy_bounds(bounds); return rc; } @@ -5671,8 +5740,7 @@ int cil_gen_default(struct cil_tree_node *parse_current, struct cil_tree_node *a return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad %s declaration at line %d of %s\n", - cil_node_to_string(parse_current), parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad %s declaration", cil_node_to_string(parse_current)); cil_destroy_default(def); return rc; } @@ -5758,8 +5826,7 @@ int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_no return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad defaultrange declaration at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad defaultrange declaration"); cil_destroy_defaultrange(def); return rc; } @@ -5819,8 +5886,7 @@ int cil_gen_handleunknown(struct cil_tree_node *parse_current, struct cil_tree_n return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad handleunknown at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad handleunknown"); cil_destroy_handleunknown(unknown); return rc; } @@ -5868,8 +5934,7 @@ int cil_gen_mls(struct cil_tree_node *parse_current, struct cil_tree_node *ast_n return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad mls at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Bad mls"); cil_destroy_mls(mls); return rc; } @@ -5879,6 +5944,27 @@ void cil_destroy_mls(struct cil_mls *mls) free(mls); } +int cil_gen_src_info(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) +{ + /* No need to check syntax, because this is auto generated */ + struct cil_src_info *info = NULL; + + cil_src_info_init(&info); + + info->is_cil = (parse_current->next->data == CIL_KEY_SRC_CIL) ? CIL_TRUE : CIL_FALSE; + info->path = parse_current->next->next->data; + + ast_node->data = info; + ast_node->flavor = CIL_SRC_INFO; + + return SEPOL_OK; +} + +void cil_destroy_src_info(struct cil_src_info *info) +{ + free(info); +} + 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 +5999,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 { - cil_log(CIL_ERR, "Keyword expected after open parenthesis in line %d of %s\n", parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Keyword expected after open parenthesis"); } goto exit; } @@ -5926,7 +6012,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; - cil_log(CIL_ERR, "%s is not allowed in macros (%s:%d)\n", (char *)parse_current->data, parse_current->path, parse_current->line); + cil_tree_log(parse_current, CIL_ERR, "%s is not allowed in macros", (char *)parse_current->data); goto exit; } } @@ -5942,8 +6028,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; - cil_log(CIL_ERR, "Found %s at line %d of %s\n", - (char*)parse_current->data, parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Found %s", (char*)parse_current->data); 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 +6043,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; - cil_log(CIL_ERR, "Found tunable at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Found tunable"); cil_log(CIL_ERR, "Tunables cannot be defined within tunableif statement\n"); goto exit; } @@ -5968,8 +6052,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; - cil_log(CIL_ERR, "Found in-statement at line %d of %s\n", - parse_current->line, parse_current->path); + cil_tree_log(parse_current, CIL_ERR, "Found in-statement"); cil_log(CIL_ERR, "in-statements cannot be defined within in-statements\n"); goto exit; } @@ -5979,7 +6062,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; - ast_node->path = parse_current->path; + ast_node->hll_line = parse_current->hll_line; if (parse_current->data == CIL_KEY_BLOCK) { rc = cil_gen_block(db, parse_current, ast_node, 0); @@ -6182,6 +6265,12 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f } else if (parse_current->data == CIL_KEY_FILECON) { rc = cil_gen_filecon(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; + } else if (parse_current->data == CIL_KEY_IBPKEYCON) { + rc = cil_gen_ibpkeycon(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; + } else if (parse_current->data == CIL_KEY_IBENDPORTCON) { + rc = cil_gen_ibendportcon(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_PORTCON) { rc = cil_gen_portcon(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; @@ -6242,8 +6331,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; + } else if (parse_current->data == CIL_KEY_SRC_INFO) { + rc = cil_gen_src_info(parse_current, ast_node); } else { - cil_log(CIL_ERR, "Error: Unknown keyword %s\n", (char*)parse_current->data); + cil_log(CIL_ERR, "Error: Unknown keyword %s\n", (char *)parse_current->data); rc = SEPOL_ERR; } @@ -6264,7 +6355,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; } - + ast_current->cl_head = ast_node; } else { ast_current->cl_tail->next = ast_node; diff --git libsepol-2.5/cil/src/cil_build_ast.h libsepol-2.5/cil/src/cil_build_ast.h index f428394..be76f6c 100644 --- libsepol-2.5/cil/src/cil_build_ast.h +++ libsepol-2.5/cil/src/cil_build_ast.h @@ -173,6 +173,10 @@ int cil_gen_context(struct cil_db *db, struct cil_tree_node *parse_current, stru void cil_destroy_context(struct cil_context *context); int cil_gen_filecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); void cil_destroy_filecon(struct cil_filecon *filecon); +int cil_gen_ibpkeycon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_ibpkeycon(struct cil_ibpkeycon *ibpkeycon); +int cil_gen_ibendportcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_ibendportcon(struct cil_ibendportcon *ibendportcon); int cil_gen_portcon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); void cil_destroy_portcon(struct cil_portcon *portcon); int cil_gen_nodecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); @@ -215,6 +219,8 @@ int cil_gen_mls(struct cil_tree_node *parse_current, struct cil_tree_node *ast_n void cil_destroy_mls(struct cil_mls *mls); int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); void cil_destroy_defaultrange(struct cil_defaultrange *def); +int cil_gen_src_info(struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_src_info(struct cil_src_info *info); int cil_fill_cats(struct cil_tree_node *curr, struct cil_cats **cats); void cil_destroy_cats(struct cil_cats *cats); diff --git libsepol-2.5/cil/src/cil_copy_ast.c libsepol-2.5/cil/src/cil_copy_ast.c index 0be1dda..0e87714 100644 --- libsepol-2.5/cil/src/cil_copy_ast.c +++ libsepol-2.5/cil/src/cil_copy_ast.c @@ -1181,6 +1181,51 @@ int cil_copy_nodecon(struct cil_db *db, void *data, void **copy, __attribute__(( return SEPOL_OK; } +int cil_copy_ibpkeycon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_ibpkeycon *orig = data; + struct cil_ibpkeycon *new = NULL; + + cil_ibpkeycon_init(&new); + + new->subnet_prefix_str = orig->subnet_prefix_str; + new->pkey_low = orig->pkey_low; + new->pkey_high = orig->pkey_high; + + if (orig->context_str) { + new->context_str = orig->context_str; + } else { + cil_context_init(&new->context); + cil_copy_fill_context(db, orig->context, new->context); + } + + *copy = new; + + return SEPOL_OK; +} + +int cil_copy_ibendportcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_ibendportcon *orig = data; + struct cil_ibendportcon *new = NULL; + + cil_ibendportcon_init(&new); + + new->dev_name_str = orig->dev_name_str; + new->port = orig->port; + + if (orig->context_str) { + new->context_str = orig->context_str; + } else { + cil_context_init(&new->context); + cil_copy_fill_context(db, orig->context, new->context); + } + + *copy = new; + + return SEPOL_OK; +} + int cil_copy_portcon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) { struct cil_portcon *orig = data; @@ -1666,6 +1711,21 @@ int cil_copy_bounds(__attribute__((unused)) struct cil_db *db, void *data, void return SEPOL_OK; } +int cil_copy_src_info(__attribute__((unused)) struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_src_info *orig = data; + struct cil_src_info *new = NULL; + + cil_src_info_init(&new); + + new->is_cil = orig->is_cil; + new->path = orig->path; + + *copy = new; + + return SEPOL_OK; +} + int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) uint32_t *finished, void *extra_args) { int rc = SEPOL_ERR; @@ -1875,6 +1935,12 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u case CIL_NODECON: copy_func = &cil_copy_nodecon; break; + case CIL_IBPKEYCON: + copy_func = &cil_copy_ibpkeycon; + break; + case CIL_IBENDPORTCON: + copy_func = &cil_copy_ibendportcon; + break; case CIL_PORTCON: copy_func = &cil_copy_portcon; break; @@ -1942,6 +2008,9 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u case CIL_MLS: copy_func = &cil_copy_mls; break; + case CIL_SRC_INFO: + copy_func = &cil_copy_src_info; + break; default: goto exit; } @@ -1964,7 +2033,7 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u new->parent = parent; new->line = orig->line; - new->path = orig->path; + new->hll_line = orig->hll_line; new->flavor = orig->flavor; new->data = data; @@ -1985,8 +2054,8 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u param = item->data; if (param->flavor == new->flavor) { if (param->str == ((struct cil_symtab_datum*)new->data)->name) { - cil_log(CIL_ERR, "%s %s shadows a macro parameter (%s line:%d)\n", cil_node_to_string(new), ((struct cil_symtab_datum*)orig->data)->name, orig->path, orig->line); - cil_log(CIL_ERR, "Note: macro declaration (%s line:%d)\n", namespace->path, namespace->line); + cil_tree_log(orig, CIL_ERR, "%s %s shadows a macro parameter", cil_node_to_string(new), ((struct cil_symtab_datum*)orig->data)->name); + cil_tree_log(namespace, CIL_ERR, "Note: macro declaration"); rc = SEPOL_ERR; goto exit; } diff --git libsepol-2.5/cil/src/cil_copy_ast.h libsepol-2.5/cil/src/cil_copy_ast.h index 78c34b8..a50c370 100644 --- libsepol-2.5/cil/src/cil_copy_ast.h +++ libsepol-2.5/cil/src/cil_copy_ast.h @@ -99,6 +99,7 @@ int cil_copy_netifcon(struct cil_db *db, void *data, void **copy, symtab_t *symt int cil_copy_genfscon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); int cil_copy_filecon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); int cil_copy_nodecon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); +int cil_copy_ibpkeycon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); int cil_copy_portcon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); int cil_copy_pirqcon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); int cil_copy_iomemcon(struct cil_db *db, void *data, void **copy, symtab_t *symtab); diff --git libsepol-2.5/cil/src/cil_find.c libsepol-2.5/cil/src/cil_find.c index 75de886..4134242 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; } @@ -379,7 +383,7 @@ int cil_find_matching_avrule_in_ast(struct cil_tree_node *current, enum cil_flav rc = cil_tree_walk(current, __cil_find_matching_avrule_in_ast, NULL, NULL, &args); if (rc) { - cil_log(CIL_ERR, "An error occured while searching for avrule in AST\n"); + cil_log(CIL_ERR, "An error occurred while searching for avrule in AST\n"); } return rc; diff --git libsepol-2.5/cil/src/cil_flavor.h libsepol-2.5/cil/src/cil_flavor.h index 9fb5083..04f4abd 100644 --- libsepol-2.5/cil/src/cil_flavor.h +++ libsepol-2.5/cil/src/cil_flavor.h @@ -111,6 +111,9 @@ enum cil_flavor { CIL_DEFAULTRANGE, CIL_HANDLEUNKNOWN, CIL_MLS, + CIL_SRC_INFO, + CIL_IBPKEYCON, + CIL_IBENDPORTCON, /* * boolean constraint set catset diff --git libsepol-2.5/cil/src/cil_fqn.c libsepol-2.5/cil/src/cil_fqn.c index 865bd7d..dad1347 100644 --- libsepol-2.5/cil/src/cil_fqn.c +++ libsepol-2.5/cil/src/cil_fqn.c @@ -121,7 +121,7 @@ static int __cil_fqn_qualify_blocks(__attribute__((unused)) hashtab_key_t k, has exit: if (rc != SEPOL_OK) { - cil_log(CIL_ERR,"Problem qualifying names in block at line %d of %s\n", child_args.node->line, child_args.node->path); + cil_tree_log(child_args.node, CIL_ERR,"Problem qualifying names in block"); } return rc; diff --git libsepol-2.5/cil/src/cil_internal.h libsepol-2.5/cil/src/cil_internal.h index a0a5480..dcc2111 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; char *CIL_KEY_STAR; char *CIL_KEY_TCP; char *CIL_KEY_UDP; +char *CIL_KEY_DCCP; char *CIL_KEY_AUDITALLOW; char *CIL_KEY_TUNABLEIF; char *CIL_KEY_ALLOW; @@ -200,6 +201,8 @@ char *CIL_KEY_VALIDATETRANS; char *CIL_KEY_MLSVALIDATETRANS; char *CIL_KEY_CONTEXT; char *CIL_KEY_FILECON; +char *CIL_KEY_IBPKEYCON; +char *CIL_KEY_IBENDPORTCON; char *CIL_KEY_PORTCON; char *CIL_KEY_NODECON; char *CIL_KEY_GENFSCON; @@ -225,6 +228,9 @@ char *CIL_KEY_NEVERALLOWX; char *CIL_KEY_PERMISSIONX; char *CIL_KEY_IOCTL; char *CIL_KEY_UNORDERED; +char *CIL_KEY_SRC_INFO; +char *CIL_KEY_SRC_CIL; +char *CIL_KEY_SRC_HLL; /* Symbol Table Array Indices @@ -279,6 +285,8 @@ struct cil_db { struct cil_sort *genfscon; struct cil_sort *filecon; struct cil_sort *nodecon; + struct cil_sort *ibpkeycon; + struct cil_sort *ibendportcon; struct cil_sort *portcon; struct cil_sort *pirqcon; struct cil_sort *iomemcon; @@ -713,7 +721,16 @@ struct cil_filecon { enum cil_protocol { CIL_PROTOCOL_UDP = 1, - CIL_PROTOCOL_TCP + CIL_PROTOCOL_TCP, + CIL_PROTOCOL_DCCP +}; + +struct cil_ibpkeycon { + char *subnet_prefix_str; + uint32_t pkey_low; + uint32_t pkey_high; + char *context_str; + struct cil_context *context; }; struct cil_portcon { @@ -758,6 +775,12 @@ struct cil_netifcon { char *context_str; }; +struct cil_ibendportcon { + char *dev_name_str; + uint32_t port; + char *context_str; + struct cil_context *context; +}; struct cil_pirqcon { uint32_t pirq; char *context_str; @@ -915,6 +938,11 @@ struct cil_mls { int value; }; +struct cil_src_info { + int is_cil; + char *path; +}; + void cil_db_init(struct cil_db **db); void cil_db_destroy(struct cil_db **db); @@ -938,6 +966,7 @@ int cil_get_symtab(struct cil_tree_node *ast_node, symtab_t **symtab, enum cil_s void cil_sort_init(struct cil_sort **sort); void cil_sort_destroy(struct cil_sort **sort); void cil_netifcon_init(struct cil_netifcon **netifcon); +void cil_ibendportcon_init(struct cil_ibendportcon **ibendportcon); void cil_context_init(struct cil_context **context); void cil_level_init(struct cil_level **level); void cil_levelrange_init(struct cil_levelrange **lvlrange); @@ -980,6 +1009,7 @@ void cil_catset_init(struct cil_catset **catset); void cil_cats_init(struct cil_cats **cats); void cil_senscat_init(struct cil_senscat **senscat); void cil_filecon_init(struct cil_filecon **filecon); +void cil_ibpkeycon_init(struct cil_ibpkeycon **ibpkeycon); void cil_portcon_init(struct cil_portcon **portcon); void cil_nodecon_init(struct cil_nodecon **nodecon); void cil_genfscon_init(struct cil_genfscon **genfscon); @@ -1017,6 +1047,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); +void cil_src_info_init(struct cil_src_info **info); void cil_userattribute_init(struct cil_userattribute **attribute); void cil_userattributeset_init(struct cil_userattributeset **attrset); diff --git libsepol-2.5/cil/src/cil_lexer.h libsepol-2.5/cil/src/cil_lexer.h index 1537d5e..ab555d8 100644 --- libsepol-2.5/cil/src/cil_lexer.h +++ libsepol-2.5/cil/src/cil_lexer.h @@ -37,8 +37,10 @@ #define SYMBOL 3 #define QSTRING 4 #define COMMENT 5 -#define END_OF_FILE 6 -#define UNKNOWN 7 +#define HLL_LINEMARK 6 +#define NEWLINE 7 +#define END_OF_FILE 8 +#define UNKNOWN 9 struct token { uint32_t type; diff --git libsepol-2.5/cil/src/cil_lexer.l libsepol-2.5/cil/src/cil_lexer.l index 8e4c207..e28c33e 100644 --- libsepol-2.5/cil/src/cil_lexer.l +++ libsepol-2.5/cil/src/cil_lexer.l @@ -50,15 +50,17 @@ symbol ({digit}|{alpha}|{spec_char})+ white [ \t] newline [\n\r] qstring \"[^"\n]*\" -comment ;[^\n]* +hll_lm ^;;\* +comment ; %% -{newline} line++; +{newline} line++; return NEWLINE; +{hll_lm} value=yytext; return HLL_LINEMARK; {comment} value=yytext; return COMMENT; "(" value=yytext; return OPAREN; -")" value=yytext; return CPAREN; +")" value=yytext; return CPAREN; {symbol} value=yytext; return SYMBOL; -{white} //cil_log(CIL_INFO, "white, "); +{white} ; {qstring} value=yytext; return QSTRING; <> return END_OF_FILE; . value=yytext; return UNKNOWN; @@ -73,7 +75,7 @@ int cil_lexer_setup(char *buffer, uint32_t size) } line = 1; - + return SEPOL_OK; } @@ -87,7 +89,6 @@ int cil_lexer_next(struct token *tok) tok->type = yylex(); tok->value = value; tok->line = line; - + return SEPOL_OK; } - diff --git libsepol-2.5/cil/src/cil_parser.c libsepol-2.5/cil/src/cil_parser.c index d0e108c..101520c 100644 --- libsepol-2.5/cil/src/cil_parser.c +++ libsepol-2.5/cil/src/cil_parser.c @@ -36,9 +36,165 @@ #include "cil_internal.h" #include "cil_log.h" #include "cil_mem.h" -#include "cil_tree.h" +#include "cil_tree.h" #include "cil_lexer.h" #include "cil_strpool.h" +#include "cil_stack.h" + +char *CIL_KEY_HLL_LMS; +char *CIL_KEY_HLL_LMX; +char *CIL_KEY_HLL_LME; + +struct hll_info { + int hll_lineno; + int hll_expand; +}; + +static void push_hll_info(struct cil_stack *stack, int hll_lineno, int hll_expand) +{ + struct hll_info *new = cil_malloc(sizeof(*new)); + + new->hll_lineno = hll_lineno; + new->hll_expand = hll_expand; + + cil_stack_push(stack, CIL_NONE, new); +} + +static void pop_hll_info(struct cil_stack *stack, int *hll_lineno, int *hll_expand) +{ + struct cil_stack_item *curr = cil_stack_pop(stack); + struct cil_stack_item *prev = cil_stack_peek(stack); + struct hll_info *old; + + free(curr->data); + + if (!prev) { + *hll_lineno = -1; + *hll_expand = -1; + } else { + old = prev->data; + *hll_lineno = old->hll_lineno; + *hll_expand = old->hll_expand; + } +} + +static void create_node(struct cil_tree_node **node, struct cil_tree_node *current, int line, int hll_line, void *value) +{ + cil_tree_node_init(node); + (*node)->parent = current; + (*node)->flavor = CIL_NODE; + (*node)->line = line; + (*node)->hll_line = hll_line; + (*node)->data = value; +} + +static void insert_node(struct cil_tree_node *node, struct cil_tree_node *current) +{ + if (current->cl_head == NULL) { + current->cl_head = node; + } else { + current->cl_tail->next = node; + } + current->cl_tail = node; +} + +static int add_hll_linemark(struct cil_tree_node **current, int *hll_lineno, int *hll_expand, struct cil_stack *stack, char *path) +{ + char *hll_type; + struct cil_tree_node *node; + struct token tok; + char *hll_file; + char *end = NULL; + + cil_lexer_next(&tok); + hll_type = cil_strpool_add(tok.value); + if (hll_type == CIL_KEY_HLL_LME) { + if (cil_stack_is_empty(stack)) { + cil_log(CIL_ERR, "Line mark end without start\n"); + goto exit; + } + pop_hll_info(stack, hll_lineno, hll_expand); + *current = (*current)->parent; + } else { + create_node(&node, *current, tok.line, *hll_lineno, NULL); + insert_node(node, *current); + *current = node; + + create_node(&node, *current, tok.line, *hll_lineno, CIL_KEY_SRC_INFO); + insert_node(node, *current); + + create_node(&node, *current, tok.line, *hll_lineno, CIL_KEY_SRC_HLL); + insert_node(node, *current); + + if (hll_type == CIL_KEY_HLL_LMS) { + *hll_expand = 0; + } else if (hll_type == CIL_KEY_HLL_LMX) { + *hll_expand = 1; + } else { + cil_log(CIL_ERR, "Invalid line mark syntax\n"); + goto exit; + } + + cil_lexer_next(&tok); + if (tok.type != SYMBOL) { + cil_log(CIL_ERR, "Invalid line mark syntax\n"); + goto exit; + } + *hll_lineno = strtol(tok.value, &end, 10); + if (errno == ERANGE || *end != '\0') { + cil_log(CIL_ERR, "Problem parsing line number for line mark\n"); + goto exit; + } + + push_hll_info(stack, *hll_lineno, *hll_expand); + + cil_lexer_next(&tok); + if (tok.type != SYMBOL && tok.type != QSTRING) { + cil_log(CIL_ERR, "Invalid line mark syntax\n"); + goto exit; + } + + if (tok.type == QSTRING) { + tok.value[strlen(tok.value) - 1] = '\0'; + tok.value = tok.value+1; + } + + hll_file = cil_strpool_add(tok.value); + + create_node(&node, *current, tok.line, *hll_lineno, hll_file); + insert_node(node, *current); + } + + cil_lexer_next(&tok); + if (tok.type != NEWLINE) { + cil_log(CIL_ERR, "Invalid line mark syntax\n"); + goto exit; + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Problem with high-level line mark at line %d of %s\n", tok.line, path); + return SEPOL_ERR; +} + +static void add_cil_path(struct cil_tree_node **current, char *path) +{ + struct cil_tree_node *node; + + create_node(&node, *current, 0, 0, NULL); + insert_node(node, *current); + *current = node; + + create_node(&node, *current, 0, 0, CIL_KEY_SRC_INFO); + insert_node(node, *current); + + create_node(&node, *current, 0, 0, CIL_KEY_SRC_CIL); + insert_node(node, *current); + + create_node(&node, *current, 0, 0, path); + insert_node(node, *current); +} int cil_parser(char *_path, char *buffer, uint32_t size, struct cil_tree **parse_tree) { @@ -47,89 +203,112 @@ int cil_parser(char *_path, char *buffer, uint32_t size, struct cil_tree **parse struct cil_tree *tree = NULL; struct cil_tree_node *node = NULL; - struct cil_tree_node *item = NULL; struct cil_tree_node *current = NULL; char *path = cil_strpool_add(_path); - + struct cil_stack *stack; + int hll_lineno = -1; + int hll_expand = -1; struct token tok; + int rc = SEPOL_OK; + + CIL_KEY_HLL_LMS = cil_strpool_add("lms"); + CIL_KEY_HLL_LMX = cil_strpool_add("lmx"); + CIL_KEY_HLL_LME = cil_strpool_add("lme"); + + cil_stack_init(&stack); cil_lexer_setup(buffer, size); tree = *parse_tree; - current = tree->root; + current = tree->root; + + add_cil_path(¤t, path); do { cil_lexer_next(&tok); switch (tok.type) { + case HLL_LINEMARK: + rc = add_hll_linemark(¤t, &hll_lineno, &hll_expand, stack, path); + if (rc != SEPOL_OK) { + goto exit; + } + break; case OPAREN: paren_count++; - cil_tree_node_init(&node); - node->parent = current; - node->flavor = CIL_NODE; - node->line = tok.line; - node->path = path; - if (current->cl_head == NULL) { - current->cl_head = node; - } else { - current->cl_tail->next = node; - } - current->cl_tail = node; + + create_node(&node, current, tok.line, hll_lineno, NULL); + insert_node(node, current); current = node; break; case CPAREN: paren_count--; if (paren_count < 0) { cil_log(CIL_ERR, "Close parenthesis without matching open at line %d of %s\n", tok.line, path); - return SEPOL_ERR; + goto exit; } current = current->parent; break; - case SYMBOL: case QSTRING: + tok.value[strlen(tok.value) - 1] = '\0'; + tok.value = tok.value+1; + case SYMBOL: if (paren_count == 0) { cil_log(CIL_ERR, "Symbol not inside parenthesis at line %d of %s\n", tok.line, path); - return SEPOL_ERR; + goto exit; } - cil_tree_node_init(&item); - item->parent = current; - if (tok.type == QSTRING) { - tok.value[strlen(tok.value) - 1] = '\0'; - item->data = cil_strpool_add(tok.value + 1); - } else { - item->data = cil_strpool_add(tok.value); - } - item->flavor = CIL_NODE; - item->line = tok.line; - item->path = path; - if (current->cl_head == NULL) { - current->cl_head = item; - } else { - current->cl_tail->next = item; + + create_node(&node, current, tok.line, hll_lineno, cil_strpool_add(tok.value)); + insert_node(node, current); + break; + case NEWLINE : + if (!hll_expand) { + hll_lineno++; } - current->cl_tail = item; break; + case COMMENT: + while (tok.type != NEWLINE && tok.type != END_OF_FILE) { + cil_lexer_next(&tok); + } + if (!hll_expand) { + hll_lineno++; + } + if (tok.type != END_OF_FILE) { + break; + } + // Fall through if EOF case END_OF_FILE: if (paren_count > 0) { cil_log(CIL_ERR, "Open parenthesis without matching close at line %d of %s\n", tok.line, path); - return SEPOL_ERR; + goto exit; + } + if (!cil_stack_is_empty(stack)) { + cil_log(CIL_ERR, "High-level language line marker start without close at line %d of %s\n", tok.line, path); + goto exit; } - break; - case COMMENT: - // ignore break; case UNKNOWN: cil_log(CIL_ERR, "Invalid token '%s' at line %d of %s\n", tok.value, tok.line, path); - return SEPOL_ERR; + goto exit; default: cil_log(CIL_ERR, "Unknown token type '%d' at line %d of %s\n", tok.type, tok.line, path); - return SEPOL_ERR; + goto exit; } } while (tok.type != END_OF_FILE); cil_lexer_destroy(); + cil_stack_destroy(&stack); + *parse_tree = tree; return SEPOL_OK; + +exit: + while (!cil_stack_is_empty(stack)) { + pop_hll_info(stack, &hll_lineno, &hll_expand); + } + cil_stack_destroy(&stack); + + return SEPOL_ERR; } diff --git libsepol-2.5/cil/src/cil_policy.c libsepol-2.5/cil/src/cil_policy.c index 2c9b158..7a57583 100644 --- libsepol-2.5/cil/src/cil_policy.c +++ libsepol-2.5/cil/src/cil_policy.c @@ -123,6 +123,8 @@ int cil_portcon_to_policy(FILE **file_arr, struct cil_sort *sort) fprintf(file_arr[NETIFCONS], "udp "); } else if (portcon->proto == CIL_PROTOCOL_TCP) { fprintf(file_arr[NETIFCONS], "tcp "); + } else if (portcon->proto == CIL_PROTOCOL_DCCP) { + fprintf(file_arr[NETIFCONS], "dccp "); } fprintf(file_arr[NETIFCONS], "%d ", portcon->port_low); fprintf(file_arr[NETIFCONS], "%d ", portcon->port_high); @@ -148,6 +150,39 @@ int cil_genfscon_to_policy(FILE **file_arr, struct cil_sort *sort) return SEPOL_OK; } +int cil_ibpkeycon_to_policy(FILE **file_arr, struct cil_sort *ibpkeycons) +{ + uint32_t i = 0; + + for (i = 0; i < ibpkeycons->count; i++) { + struct cil_ibpkeycon *ibpkeycon = (struct cil_ibpkeycon *)ibpkeycons->array[i]; + + fprintf(file_arr[NETIFCONS], "ibpkeycon %s ", ibpkeycon->subnet_prefix_str); + fprintf(file_arr[NETIFCONS], "%d ", ibpkeycon->pkey_low); + fprintf(file_arr[NETIFCONS], "%d ", ibpkeycon->pkey_high); + cil_context_to_policy(file_arr, NETIFCONS, ibpkeycon->context); + fprintf(file_arr[NETIFCONS], ";\n"); + } + + return SEPOL_OK; +} + +int cil_ibendportcon_to_policy(FILE **file_arr, struct cil_sort *ibendportcons) +{ + uint32_t i; + + for (i = 0; i < ibendportcons->count; i++) { + struct cil_ibendportcon *ibendportcon = (struct cil_ibendportcon *)ibendportcons->array[i]; + + fprintf(file_arr[NETIFCONS], "ibendportcon %s ", ibendportcon->dev_name_str); + fprintf(file_arr[NETIFCONS], "%u ", ibendportcon->port); + cil_context_to_policy(file_arr, NETIFCONS, ibendportcon->context); + fprintf(file_arr[NETIFCONS], ";\n"); + } + + return SEPOL_OK; +} + int cil_netifcon_to_policy(FILE **file_arr, struct cil_sort *sort) { uint32_t i = 0; @@ -1321,6 +1356,18 @@ int cil_gen_policy(struct cil_db *db) cil_log(CIL_ERR, "Error creating policy.conf\n"); return rc; } + + rc = cil_ibpkeycon_to_policy(file_arr, db->ibpkeycon); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Error creating policy.conf\n"); + return rc; + } + + rc = cil_ibendportcon_to_policy(file_arr, db->ibendportcon); + if (rc != SEPOL_OK) { + cil_log(CIL_ERR, "Error creating policy.conf\n"); + return rc; + } rc = cil_genfscon_to_policy(file_arr, db->genfscon); if (rc != SEPOL_OK) { diff --git libsepol-2.5/cil/src/cil_post.c libsepol-2.5/cil/src/cil_post.c index a694b33..26fdc0e 100644 --- libsepol-2.5/cil/src/cil_post.c +++ libsepol-2.5/cil/src/cil_post.c @@ -151,6 +151,28 @@ int cil_post_filecon_compare(const void *a, const void *b) return rc; } +int cil_post_ibpkeycon_compare(const void *a, const void *b) +{ + int rc = SEPOL_ERR; + struct cil_ibpkeycon *aibpkeycon = *(struct cil_ibpkeycon **)a; + struct cil_ibpkeycon *bibpkeycon = *(struct cil_ibpkeycon **)b; + + rc = strcmp(aibpkeycon->subnet_prefix_str, bibpkeycon->subnet_prefix_str); + if (rc) + return rc; + + rc = (aibpkeycon->pkey_high - aibpkeycon->pkey_low) + - (bibpkeycon->pkey_high - bibpkeycon->pkey_low); + if (rc == 0) { + if (aibpkeycon->pkey_low < bibpkeycon->pkey_low) + rc = -1; + else if (bibpkeycon->pkey_low < aibpkeycon->pkey_low) + rc = 1; + } + + return rc; +} + int cil_post_portcon_compare(const void *a, const void *b) { int rc = SEPOL_ERR; @@ -192,6 +214,25 @@ int cil_post_netifcon_compare(const void *a, const void *b) return strcmp(anetifcon->interface_str, bnetifcon->interface_str); } +int cil_post_ibendportcon_compare(const void *a, const void *b) +{ + int rc = SEPOL_ERR; + + struct cil_ibendportcon *aibendportcon = *(struct cil_ibendportcon **)a; + struct cil_ibendportcon *bibendportcon = *(struct cil_ibendportcon **)b; + + rc = strcmp(aibendportcon->dev_name_str, bibendportcon->dev_name_str); + if (rc) + return rc; + + if (aibendportcon->port < bibendportcon->port) + return -1; + else if (bibendportcon->port < aibendportcon->port) + return 1; + + return rc; +} + int cil_post_nodecon_compare(const void *a, const void *b) { struct cil_nodecon *anodecon; @@ -398,6 +439,12 @@ static int __cil_post_db_count_helper(struct cil_tree_node *node, uint32_t *fini case CIL_NODECON: db->nodecon->count++; break; + case CIL_IBPKEYCON: + db->ibpkeycon->count++; + break; + case CIL_IBENDPORTCON: + db->ibendportcon->count++; + break; case CIL_PORTCON: db->portcon->count++; break; @@ -488,6 +535,17 @@ static int __cil_post_db_array_helper(struct cil_tree_node *node, uint32_t *fini sort->index++; break; } + case CIL_IBENDPORTCON: { + struct cil_sort *sort = db->ibendportcon; + uint32_t count = sort->count; + uint32_t i = sort->index; + + if (!sort->array) + sort->array = cil_malloc(sizeof(*sort->array) * count); + sort->array[i] = node->data; + sort->index++; + break; + } case CIL_FSUSE: { struct cil_sort *sort = db->fsuse; uint32_t count = sort->count; @@ -532,6 +590,17 @@ static int __cil_post_db_array_helper(struct cil_tree_node *node, uint32_t *fini sort->index++; break; } + case CIL_IBPKEYCON: { + struct cil_sort *sort = db->ibpkeycon; + uint32_t count = sort->count; + uint32_t i = sort->index; + + if (!sort->array) + sort->array = cil_malloc(sizeof(*sort->array) * count); + sort->array[i] = node->data; + sort->index++; + break; + } case CIL_PORTCON: { struct cil_sort *sort = db->portcon; uint32_t count = sort->count; @@ -1576,6 +1645,22 @@ static int __cil_post_db_cat_helper(struct cil_tree_node *node, uint32_t *finish } break; } + case CIL_IBPKEYCON: { + struct cil_ibpkeycon *ibpkeycon = node->data; + + rc = __evaluate_levelrange_expression(ibpkeycon->context->range, db); + if (rc != SEPOL_OK) + goto exit; + break; + } + case CIL_IBENDPORTCON: { + struct cil_ibendportcon *ibendportcon = node->data; + + rc = __evaluate_levelrange_expression(ibendportcon->context->range, db); + if (rc != SEPOL_OK) + goto exit; + break; + } case CIL_PORTCON: { struct cil_portcon *portcon = node->data; rc = __evaluate_levelrange_expression(portcon->context->range, db); @@ -1935,6 +2020,8 @@ static int cil_post_db(struct cil_db *db) qsort(db->netifcon->array, db->netifcon->count, sizeof(db->netifcon->array), cil_post_netifcon_compare); qsort(db->genfscon->array, db->genfscon->count, sizeof(db->genfscon->array), cil_post_genfscon_compare); + qsort(db->ibpkeycon->array, db->ibpkeycon->count, sizeof(db->ibpkeycon->array), cil_post_ibpkeycon_compare); + qsort(db->ibendportcon->array, db->ibendportcon->count, sizeof(db->ibendportcon->array), cil_post_ibendportcon_compare); qsort(db->portcon->array, db->portcon->count, sizeof(db->portcon->array), cil_post_portcon_compare); qsort(db->nodecon->array, db->nodecon->count, sizeof(db->nodecon->array), cil_post_nodecon_compare); qsort(db->fsuse->array, db->fsuse->count, sizeof(db->fsuse->array), cil_post_fsuse_compare); diff --git libsepol-2.5/cil/src/cil_post.h libsepol-2.5/cil/src/cil_post.h index 74393cc..3d54154 100644 --- libsepol-2.5/cil/src/cil_post.h +++ libsepol-2.5/cil/src/cil_post.h @@ -38,7 +38,9 @@ struct fc_data { void cil_post_fc_fill_data(struct fc_data *fc, char *path); int cil_post_filecon_compare(const void *a, const void *b); +int cil_post_ibpkeycon_compare(const void *a, const void *b); int cil_post_portcon_compare(const void *a, const void *b); +int cil_post_ibendportcon_compare(const void *a, const void *b); int cil_post_genfscon_compare(const void *a, const void *b); int cil_post_netifcon_compare(const void *a, const void *b); int cil_post_nodecon_compare(const void *a, const void *b); diff --git libsepol-2.5/cil/src/cil_reset_ast.c libsepol-2.5/cil/src/cil_reset_ast.c index 06146ca..ff67913 100644 --- libsepol-2.5/cil/src/cil_reset_ast.c +++ libsepol-2.5/cil/src/cil_reset_ast.c @@ -23,7 +23,7 @@ static void cil_reset_class(struct cil_class *class) { if (class->common != NULL) { struct cil_class *common = class->common; - cil_symtab_map(&common->perms, __class_reset_perm_values, &common->num_perms); + cil_symtab_map(&class->perms, __class_reset_perm_values, &common->num_perms); /* during a re-resolve, we need to reset the common, so a classcommon * statement isn't seen as a duplicate */ class->num_perms -= common->num_perms; @@ -288,6 +288,12 @@ static void cil_reset_filecon(struct cil_filecon *filecon) } } +static void cil_reset_ibpkeycon(struct cil_ibpkeycon *ibpkeycon) +{ + if (!ibpkeycon->context) + cil_reset_context(ibpkeycon->context); +} + static void cil_reset_portcon(struct cil_portcon *portcon) { if (portcon->context_str == NULL) { @@ -320,6 +326,13 @@ static void cil_reset_netifcon(struct cil_netifcon *netifcon) } } +static void cil_reset_ibendportcon(struct cil_ibendportcon *ibendportcon) +{ + if (!ibendportcon->context_str) { + cil_reset_context(ibendportcon->context); + } +} + static void cil_reset_pirqcon(struct cil_pirqcon *pirqcon) { if (pirqcon->context_str == NULL) { @@ -489,6 +502,12 @@ int __cil_reset_node(struct cil_tree_node *node, __attribute__((unused)) uint32 case CIL_FILECON: cil_reset_filecon(node->data); break; + case CIL_IBPKEYCON: + cil_reset_ibpkeycon(node->data); + break; + case CIL_IBENDPORTCON: + cil_reset_ibendportcon(node->data); + break; case CIL_PORTCON: cil_reset_portcon(node->data); break; diff --git libsepol-2.5/cil/src/cil_resolve_ast.c libsepol-2.5/cil/src/cil_resolve_ast.c index 1489680..0b48607 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, } } if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Failed to resolve permission %s\n", (char*)curr->data); - goto exit; + cil_log(CIL_WARN, "Failed to resolve permission %s\n", (char*)curr->data); + } else { + cil_list_append(*perm_datums, CIL_DATUM, perm_datum); } - cil_list_append(*perm_datums, CIL_DATUM, perm_datum); } else { cil_list_append(*perm_datums, curr->flavor, curr->data); } @@ -497,7 +497,7 @@ int cil_resolve_alias_to_actual(struct cil_tree_node *current, enum cil_flavor f int limit = 2; if (alias->actual == NULL) { - cil_log(CIL_ERR, "Alias declared but not used at line %d of %s\n",current->line, current->path); + cil_tree_log(current, CIL_ERR, "Alias declared but not used"); return SEPOL_ERR; } @@ -1380,7 +1380,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) { - cil_log(CIL_ERR, "Unable to merge ordered list at line %d of %s\n",ordered_list->node->line, ordered_list->node->path); + cil_tree_log(ordered_list->node, CIL_ERR, "Unable to merge ordered list"); } } goto exit; @@ -1866,6 +1866,30 @@ int cil_resolve_filecon(struct cil_tree_node *current, void *extra_args) return SEPOL_OK; } +int cil_resolve_ibpkeycon(struct cil_tree_node *current, void *extra_args) +{ + struct cil_ibpkeycon *ibpkeycon = current->data; + struct cil_symtab_datum *context_datum = NULL; + int rc = SEPOL_ERR; + + if (ibpkeycon->context_str) { + rc = cil_resolve_name(current, ibpkeycon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); + if (rc != SEPOL_OK) + goto exit; + + ibpkeycon->context = (struct cil_context *)context_datum; + } else { + rc = cil_resolve_context(current, ibpkeycon->context, extra_args); + if (rc != SEPOL_OK) + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + int cil_resolve_portcon(struct cil_tree_node *current, void *extra_args) { struct cil_portcon *portcon = current->data; @@ -2005,6 +2029,31 @@ exit: return rc; } +int cil_resolve_ibendportcon(struct cil_tree_node *current, void *extra_args) +{ + struct cil_ibendportcon *ibendportcon = current->data; + struct cil_symtab_datum *con_datum = NULL; + + int rc = SEPOL_ERR; + + if (ibendportcon->context_str) { + rc = cil_resolve_name(current, ibendportcon->context_str, CIL_SYM_CONTEXTS, extra_args, &con_datum); + if (rc != SEPOL_OK) + goto exit; + + ibendportcon->context = (struct cil_context *)con_datum; + } else { + rc = cil_resolve_context(current, ibendportcon->context, extra_args); + if (rc != SEPOL_OK) + goto exit; + } + + return SEPOL_OK; + +exit: + return rc; +} + int cil_resolve_pirqcon(struct cil_tree_node *current, void *extra_args) { struct cil_pirqcon *pirqcon = current->data; @@ -2252,12 +2301,10 @@ void cil_print_recursive_blockinherit(struct cil_tree_node *bi_node, struct cil_ cil_list_for_each(item, trace) { curr = item->data; - cil_log(CIL_ERR, " %s:%d: ", curr->path, curr->line); - if (curr->flavor == CIL_BLOCK) { - cil_log(CIL_ERR, "block %s\n", DATUM(curr->data)->name); + cil_tree_log(curr, CIL_ERR, "block %s", DATUM(curr->data)->name); } else { - cil_log(CIL_ERR, "blockinherit %s\n", ((struct cil_blockinherit *)curr->data)->block_str); + cil_tree_log(curr, CIL_ERR, "blockinherit %s", ((struct cil_blockinherit *)curr->data)->block_str); } } @@ -2442,7 +2489,7 @@ int cil_resolve_in_list(void *extra_args) } if (unresolved > 0 && resolved == 0) { - cil_log(CIL_ERR, "Failed to resolve in-statement on line %d of %s\n", last_failed_node->line, last_failed_node->path); + cil_tree_log(last_failed_node, CIL_ERR, "Failed to resolve in-statement"); rc = SEPOL_ERR; goto exit; } @@ -2485,7 +2532,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; - cil_log(CIL_ERR, "User %s already bound by parent at line %u of %s\n", bounds->child_str, node->line, node->path); + cil_tree_log(node, CIL_ERR, "User %s already bound by parent", bounds->child_str); rc = SEPOL_ERR; goto exit; } @@ -2498,7 +2545,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; - cil_log(CIL_ERR, "Role %s already bound by parent at line %u of %s\n", bounds->child_str, node->line, node->path); + cil_tree_log(node, CIL_ERR, "Role %s already bound by parent", bounds->child_str); rc = SEPOL_ERR; goto exit; } @@ -2512,8 +2559,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; - cil_log(CIL_ERR, "Type %s already bound by parent at line %u of %s\n", bounds->child_str, node->line, node->path); - cil_log(CIL_ERR, "Now being bound to parent %s at line %u of %s\n", bounds->parent_str, current->line, current->path); + cil_tree_log(node, CIL_ERR, "Type %s already bound by parent", bounds->child_str); + cil_tree_log(current, CIL_ERR, "Now being bound to parent %s", bounds->parent_str); rc = SEPOL_ERR; goto exit; } @@ -2542,7 +2589,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil return SEPOL_OK; exit: - cil_log(CIL_ERR, "Bad bounds statement at line %u of %s\n", current->line, current->path); + cil_tree_log(current, CIL_ERR, "Bad bounds statement"); return rc; } @@ -2617,12 +2664,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; - cil_log(CIL_ERR, " %s:%d: ", curr->path, curr->line); - if (curr->flavor == CIL_MACRO) { - cil_log(CIL_ERR, "macro %s\n", DATUM(curr->data)->name); + cil_tree_log(curr, CIL_ERR, "macro %s", DATUM(curr->data)->name); } else { - cil_log(CIL_ERR, "call %s\n", ((struct cil_call *)curr->data)->macro_str); + cil_tree_log(curr, CIL_ERR, "call %s", ((struct cil_call *)curr->data)->macro_str); } } @@ -2700,7 +2745,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) { - cil_log(CIL_ERR, "Missing arguments (%s, line: %d)\n", current->path, current->line); + cil_tree_log(current, CIL_ERR, "Missing arguments"); rc = SEPOL_ERR; goto exit; } @@ -2713,7 +2758,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) { - cil_log(CIL_ERR, "Missing arguments (%s, line: %d)\n", current->path, current->line); + cil_tree_log(current, CIL_ERR, "Missing arguments"); rc = SEPOL_ERR; goto exit; } @@ -2890,12 +2935,12 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args) } if (pc != NULL) { - cil_log(CIL_ERR, "Unexpected arguments (%s, line: %d)\n", current->path, current->line); + cil_tree_log(current, CIL_ERR, "Unexpected arguments"); rc = SEPOL_ERR; goto exit; } } else if (new_call->args_tree != NULL) { - cil_log(CIL_ERR, "Unexpected arguments (%s, line: %d)\n", current->path, current->line); + cil_tree_log(current, CIL_ERR, "Unexpected arguments"); rc = SEPOL_ERR; goto exit; } @@ -3518,6 +3563,9 @@ int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args) case CIL_FILECON: rc = cil_resolve_filecon(node, args); break; + case CIL_IBPKEYCON: + rc = cil_resolve_ibpkeycon(node, args); + break; case CIL_PORTCON: rc = cil_resolve_portcon(node, args); break; @@ -3530,6 +3578,9 @@ int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args) case CIL_NETIFCON: rc = cil_resolve_netifcon(node, args); break; + case CIL_IBENDPORTCON: + rc = cil_resolve_ibendportcon(node, args); + break; case CIL_PIRQCON: rc = cil_resolve_pirqcon(node, args); break; @@ -3593,7 +3644,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*/ - cil_log(CIL_ERR, "%s statement is not allowed in optionals (%s:%d)\n", cil_node_to_string(node), node->path, node->line); + cil_tree_log(node, CIL_ERR, "%s statement is not allowed in optionals", cil_node_to_string(node)); rc = SEPOL_ERR; goto exit; } @@ -3601,7 +3652,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) { - cil_log(CIL_ERR, "%s statement is not allowed in blocks (%s:%d)\n", cil_node_to_string(node), node->path, node->line); + cil_tree_log(node, CIL_ERR, "%s statement is not allowed in blocks", cil_node_to_string(node)); rc = SEPOL_ERR; goto exit; } @@ -3612,7 +3663,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) { - cil_log(CIL_ERR, "%s statement is not allowed in macros (%s:%d)\n", cil_node_to_string(node), node->path, node->line); + cil_tree_log(node, CIL_ERR, "%s statement is not allowed in macros", cil_node_to_string(node)); rc = SEPOL_ERR; goto exit; } @@ -3626,9 +3677,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) { - cil_log(CIL_ERR, "%s statement is not allowed in booleanifs (tunableif treated as a booleanif) (%s:%d)\n", cil_node_to_string(node), node->path, node->line); + cil_tree_log(node, CIL_ERR, "%s statement is not allowed in booleanifs (tunableif treated as a booleanif)", cil_node_to_string(node)); } else { - cil_log(CIL_ERR, "%s statement is not allowed in booleanifs (%s:%d)\n", cil_node_to_string(node), node->path, node->line); + cil_tree_log(node, CIL_ERR, "%s statement is not allowed in booleanifs", cil_node_to_string(node)); } rc = SEPOL_ERR; goto exit; @@ -3658,14 +3709,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; - cil_log(lvl, "Disabling optional '%s' at line %d of %s: ", opt->datum.name, opt_node->line, opt_node->path); + cil_tree_log(opt_node, lvl, "Disabling optional '%s'", opt->datum.name); /* disable an optional if something failed to resolve */ opt->enabled = CIL_FALSE; rc = SEPOL_OK; } - cil_log(lvl, "Failed to resolve '%s' in %s statement at line %d of %s\n", - args->last_resolved_name, cil_node_to_string(node), node->line, node->path); + cil_tree_log(node, lvl, "Failed to resolve %s statement", cil_node_to_string(node)); goto exit; } diff --git libsepol-2.5/cil/src/cil_resolve_ast.h libsepol-2.5/cil/src/cil_resolve_ast.h index 1175f97..82c8ea3 100644 --- libsepol-2.5/cil/src/cil_resolve_ast.h +++ libsepol-2.5/cil/src/cil_resolve_ast.h @@ -74,6 +74,8 @@ int cil_resolve_constrain(struct cil_tree_node *current, void *extra_args); int cil_resolve_validatetrans(struct cil_tree_node *current, void *extra_args); int cil_resolve_context(struct cil_tree_node *current, struct cil_context *context, void *extra_args); int cil_resolve_filecon(struct cil_tree_node *current, void *extra_args); +int cil_resolve_ibpkeycon(struct cil_tree_node *current, void *extra_args); +int cil_resolve_ibendportcon(struct cil_tree_node *current, void *extra_args); int cil_resolve_portcon(struct cil_tree_node *current, void *extra_args); int cil_resolve_genfscon(struct cil_tree_node *current, void *extra_args); int cil_resolve_nodecon(struct cil_tree_node *current, void *extra_args); diff --git libsepol-2.5/cil/src/cil_tree.c libsepol-2.5/cil/src/cil_tree.c index 1c23efc..599f756 100644 --- libsepol-2.5/cil/src/cil_tree.c +++ libsepol-2.5/cil/src/cil_tree.c @@ -1,6 +1,6 @@ /* * Copyright 2011 Tresys Technology, LLC. All rights reserved. - * + * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are met: * @@ -59,6 +59,92 @@ __attribute__((noreturn)) __attribute__((format (printf, 1, 2))) void cil_tree_e exit(1); } +struct cil_tree_node *cil_tree_get_next_path(struct cil_tree_node *node, char **path, int* is_cil) +{ + if (!node) { + return NULL; + } + + node = node->parent; + + while (node) { + if (node->flavor == CIL_NODE && node->data == NULL) { + if (node->cl_head->data == CIL_KEY_SRC_INFO) { + /* Parse Tree */ + *path = node->cl_head->next->next->data; + *is_cil = (node->cl_head->next->data == CIL_KEY_SRC_CIL); + return node; + } + node = node->parent; + } else if (node->flavor == CIL_SRC_INFO) { + /* AST */ + struct cil_src_info *info = node->data; + *path = info->path; + *is_cil = info->is_cil; + return node; + } else { + if (node->flavor == CIL_CALL) { + struct cil_call *call = node->data; + node = NODE(call->macro); + } else if (node->flavor == CIL_BLOCKINHERIT) { + struct cil_blockinherit *inherit = node->data; + node = NODE(inherit->block); + } else { + node = node->parent; + } + } + } + + return NULL; +} + +char *cil_tree_get_cil_path(struct cil_tree_node *node) +{ + char *path = NULL; + int is_cil; + + while (node) { + node = cil_tree_get_next_path(node, &path, &is_cil); + if (node && is_cil) { + return path; + } + } + + return NULL; +} + +__attribute__((format (printf, 3, 4))) void cil_tree_log(struct cil_tree_node *node, enum cil_log_level lvl, const char* msg, ...) +{ + va_list ap; + + va_start(ap, msg); + cil_vlog(lvl, msg, ap); + va_end(ap); + + if (node) { + char *path = NULL; + int is_cil; + unsigned hll_line = node->hll_line; + + path = cil_tree_get_cil_path(node); + + if (path != NULL) { + cil_log(lvl, " at %s:%d", path, node->line); + } + + while (node) { + node = cil_tree_get_next_path(node, &path, &is_cil); + if (node && !is_cil) { + cil_log(lvl," from %s:%d", path, hll_line); + path = NULL; + hll_line = node->hll_line; + } + } + } + + cil_log(lvl,"\n"); +} + int cil_tree_init(struct cil_tree **tree) { struct cil_tree *new_tree = cil_malloc(sizeof(*new_tree)); @@ -128,8 +214,8 @@ void cil_tree_node_init(struct cil_tree_node **node) new_node->data = NULL; new_node->next = NULL; new_node->flavor = CIL_ROOT; - new_node->line = 0; - new_node->path = NULL; + new_node->line = 0; + new_node->hll_line = 0; *node = new_node; } @@ -185,7 +271,7 @@ int cil_tree_walk_core(struct cil_tree_node *node, if (process_node != NULL) { rc = (*process_node)(node, &finished, extra_args); if (rc != SEPOL_OK) { - cil_log(CIL_INFO, "Problem at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_INFO, "Problem"); return rc; } } @@ -222,7 +308,7 @@ int cil_tree_walk(struct cil_tree_node *node, if (first_child != NULL) { rc = (*first_child)(node->cl_head, extra_args); if (rc != SEPOL_OK) { - cil_log(CIL_INFO, "Problem at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_INFO, "Problem"); return rc; } } @@ -235,7 +321,7 @@ int cil_tree_walk(struct cil_tree_node *node, if (last_child != NULL) { rc = (*last_child)(node->cl_tail, extra_args); if (rc != SEPOL_OK) { - cil_log(CIL_INFO, "Problem at line %d of %s\n",node->line, node->path); + cil_tree_log(node, CIL_INFO, "Problem"); return rc; } } @@ -1312,6 +1398,20 @@ void cil_tree_print_node(struct cil_tree_node *node) return; } + case CIL_IBPKEYCON: { + struct cil_ibpkeycon *ibpkeycon = node->data; + + cil_log(CIL_INFO, "IBPKEYCON: %s", ibpkeycon->subnet_prefix_str); + cil_log(CIL_INFO, " (%d %d) ", ibpkeycon->pkey_low, ibpkeycon->pkey_high); + + if (ibpkeycon->context) + cil_tree_print_context(ibpkeycon->context); + else if (ibpkeycon->context_str) + cil_log(CIL_INFO, " %s", ibpkeycon->context_str); + + cil_log(CIL_INFO, "\n"); + return; + } case CIL_PORTCON: { struct cil_portcon *portcon = node->data; cil_log(CIL_INFO, "PORTCON:"); @@ -1319,6 +1419,8 @@ void cil_tree_print_node(struct cil_tree_node *node) cil_log(CIL_INFO, " udp"); } else if (portcon->proto == CIL_PROTOCOL_TCP) { cil_log(CIL_INFO, " tcp"); + } else if (portcon->proto == CIL_PROTOCOL_DCCP) { + cil_log(CIL_INFO, " dccp"); } cil_log(CIL_INFO, " (%d %d)", portcon->port_low, portcon->port_high); @@ -1393,6 +1495,19 @@ void cil_tree_print_node(struct cil_tree_node *node) cil_log(CIL_INFO, "\n"); return; } + case CIL_IBENDPORTCON: { + struct cil_ibendportcon *ibendportcon = node->data; + + cil_log(CIL_INFO, "IBENDPORTCON: %s %u ", ibendportcon->dev_name_str, ibendportcon->port); + + if (ibendportcon->context) + cil_tree_print_context(ibendportcon->context); + else if (ibendportcon->context_str) + cil_log(CIL_INFO, " %s", ibendportcon->context_str); + + cil_log(CIL_INFO, "\n"); + return; + } case CIL_PIRQCON: { struct cil_pirqcon *pirqcon = node->data; diff --git libsepol-2.5/cil/src/cil_tree.h libsepol-2.5/cil/src/cil_tree.h index 9bb602f..aeded56 100644 --- libsepol-2.5/cil/src/cil_tree.h +++ libsepol-2.5/cil/src/cil_tree.h @@ -46,10 +46,14 @@ struct cil_tree_node { struct cil_tree_node *next; //Each element in the list points to the next element enum cil_flavor flavor; uint32_t line; - char *path; + uint32_t hll_line; void *data; }; +struct cil_tree_node *cil_tree_get_next_path(struct cil_tree_node *node, char **path, int* is_cil); +char *cil_tree_get_cil_path(struct cil_tree_node *node); +__attribute__((format (printf, 3, 4))) void cil_tree_log(struct cil_tree_node *node, enum cil_log_level lvl, const char* msg, ...); + int cil_tree_init(struct cil_tree **tree); void cil_tree_destroy(struct cil_tree **tree); void cil_tree_subtree_destroy(struct cil_tree_node *node); diff --git libsepol-2.5/cil/src/cil_verify.c libsepol-2.5/cil/src/cil_verify.c index 36ec45a..26cd47c 100644 --- libsepol-2.5/cil/src/cil_verify.c +++ libsepol-2.5/cil/src/cil_verify.c @@ -377,25 +377,25 @@ int __cil_verify_ordered_node_helper(struct cil_tree_node *node, __attribute__(( if (node->flavor == CIL_SID) { struct cil_sid *sid = node->data; if (sid->ordered == CIL_FALSE) { - cil_log(CIL_ERR, "SID %s not in sidorder statement at line %d of %s\n", sid->datum.name, node->line, node->path); + cil_tree_log(node, CIL_ERR, "SID %s not in sidorder statement", sid->datum.name); return SEPOL_ERR; } } else if (node->flavor == CIL_CLASS) { struct cil_class *class = node->data; if (class->ordered == CIL_FALSE) { - cil_log(CIL_ERR, "Class %s not in classorder statement at line %d of %s\n", class->datum.name, node->line, node->path); + cil_tree_log(node, CIL_ERR, "Class %s not in classorder statement", class->datum.name); return SEPOL_ERR; } } else if (node->flavor == CIL_CAT) { struct cil_cat *cat = node->data; if (cat->ordered == CIL_FALSE) { - cil_log(CIL_ERR, "Category %s not in categoryorder statement at line %d of %s\n", cat->datum.name, node->line, node->path); + cil_tree_log(node, CIL_ERR, "Category %s not in categoryorder statement", cat->datum.name); return SEPOL_ERR; } } else if (node->flavor == CIL_SENS) { struct cil_sens *sens = node->data; if (sens->ordered == CIL_FALSE) { - cil_log(CIL_ERR, "Sensitivity %s not in sensitivityorder statement at line %d of %s\n", sens->datum.name, node->line, node->path); + cil_tree_log(node, CIL_ERR, "Sensitivity %s not in sensitivityorder statement", sens->datum.name); return SEPOL_ERR; } } @@ -430,7 +430,7 @@ int __cil_verify_initsids(struct cil_list *sids) struct cil_sid *sid = i->data; if (sid->context == NULL) { struct cil_tree_node *node = sid->datum.nodes->head->data; - cil_log(CIL_ERR, "No context assigned to SID %s declared at line %d in %s\n",sid->datum.name, node->line, node->path); + cil_tree_log(node, CIL_ERR, "No context assigned to SID %s declared",sid->datum.name); rc = SEPOL_ERR; } } @@ -598,7 +598,7 @@ int __cil_verify_named_levelrange(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid named range at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid named range"); return rc; } @@ -638,7 +638,7 @@ static int __cil_verify_user_pre_eval(struct cil_tree_node *node) return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid user at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid user"); return rc; } @@ -657,7 +657,7 @@ static int __cil_verify_user_post_eval(struct cil_db *db, struct cil_tree_node * return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid user at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid user"); return rc; } @@ -688,7 +688,7 @@ int __cil_verify_role(struct cil_tree_node *node) return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid role at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid role"); return rc; } @@ -719,7 +719,7 @@ int __cil_verify_type(struct cil_tree_node *node) return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid type at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid type"); return rc; } @@ -813,7 +813,7 @@ int __cil_verify_named_context(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid named context at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid named context"); return rc; } @@ -852,8 +852,7 @@ int __cil_verify_rule(struct cil_tree_node *node, struct cil_complex_symtab *sym struct cil_complex_symtab_datum *datum = NULL; cil_complex_symtab_search(symtab, &ckey, &datum); if (datum == NULL) { - cil_log(CIL_ERR, "Duplicate rule defined on line %d of %s\n", - node->line, node->path); + cil_tree_log(node, CIL_ERR, "Duplicate rule defined"); rc = SEPOL_ERR; goto exit; } @@ -861,7 +860,7 @@ int __cil_verify_rule(struct cil_tree_node *node, struct cil_complex_symtab *sym return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid rule at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid rule"); return rc; } @@ -877,11 +876,9 @@ int __cil_verify_booleanif_helper(struct cil_tree_node *node, __attribute__((unu avrule = rule_node->data; if (avrule->rule_kind == CIL_AVRULE_NEVERALLOW) { if (bif->preserved_tunable) { - cil_log(CIL_ERR, "Neverallow found in tunableif block (treated as a booleanif due to preserve-tunables) at line %d or %s\n", - node->line, node->path); + cil_tree_log(node, CIL_ERR, "Neverallow found in tunableif block (treated as a booleanif due to preserve-tunables)"); } else { - cil_log(CIL_ERR, "Neverallow found in booleanif block at line %d or %s\n", - node->line, node->path); + cil_tree_log(node, CIL_ERR, "Neverallow found in booleanif block"); } rc = SEPOL_ERR; goto exit; @@ -942,11 +939,9 @@ int __cil_verify_booleanif_helper(struct cil_tree_node *node, __attribute__((unu default: { const char * flavor = cil_node_to_string(node); if (bif->preserved_tunable) { - cil_log(CIL_ERR, "Invalid %s statement in tunableif (treated as a booleanif due to preserve-tunables) at line %d of %s\n", - flavor, node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid %s statement in tunableif (treated as a booleanif due to preserve-tunables)", flavor); } else { - cil_log(CIL_ERR, "Invalid %s statement in booleanif at line %d of %s\n", - flavor, node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid %s statement in booleanif", flavor); } goto exit; } @@ -974,9 +969,9 @@ int __cil_verify_booleanif(struct cil_tree_node *node, struct cil_complex_symtab return SEPOL_OK; exit: if (bif->preserved_tunable) { - cil_log(CIL_ERR, "Invalid tunableif (treated as a booleanif due to preserve-tunables) at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid tunableif (treated as a booleanif due to preserve-tunables)"); } else { - cil_log(CIL_ERR, "Invalid booleanif at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid booleanif"); } return rc; } @@ -1007,7 +1002,27 @@ int __cil_verify_netifcon(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid netifcon at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid netifcon"); + return rc; +} + +int __cil_verify_ibendportcon(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_ibendportcon *ib_end_port = node->data; + struct cil_context *ctx = ib_end_port->context; + + /* Verify only when anonymous */ + if (!ctx->datum.name) { + rc = __cil_verify_context(db, ctx); + if (rc != SEPOL_OK) + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(node, CIL_ERR, "Invalid ibendportcon"); return rc; } @@ -1028,7 +1043,7 @@ int __cil_verify_genfscon(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid genfscon at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid genfscon"); return rc; } @@ -1047,8 +1062,7 @@ int __cil_verify_filecon(struct cil_db *db, struct cil_tree_node *node) if (ctx->datum.name == NULL) { rc = __cil_verify_context(db, ctx); if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Invalid filecon at line %d of %s\n", - node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid filecon"); goto exit; } } @@ -1076,7 +1090,27 @@ int __cil_verify_nodecon(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid nodecon at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid nodecon"); + return rc; +} + +int __cil_verify_ibpkeycon(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_ibpkeycon *pkey = node->data; + struct cil_context *ctx = pkey->context; + + /* Verify only when anonymous */ + if (!ctx->datum.name) { + rc = __cil_verify_context(db, ctx); + if (rc != SEPOL_OK) + goto exit; + } + + return SEPOL_OK; + +exit: + cil_tree_log(node, CIL_ERR, "Invalid ibpkeycon"); return rc; } @@ -1097,7 +1131,7 @@ int __cil_verify_portcon(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid portcon at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid portcon"); return rc; } @@ -1118,7 +1152,7 @@ int __cil_verify_pirqcon(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid pirqcon at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid pirqcon"); return rc; } @@ -1139,7 +1173,7 @@ int __cil_verify_iomemcon(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid iomemcon at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid iomemcon"); return rc; } @@ -1160,7 +1194,7 @@ int __cil_verify_ioportcon(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid ioportcon at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid ioportcon"); return rc; } @@ -1181,7 +1215,7 @@ int __cil_verify_pcidevicecon(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid pcidevicecon at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid pcidevicecon"); return rc; } @@ -1202,7 +1236,7 @@ int __cil_verify_devicetreecon(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid devicetreecon at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid devicetreecon"); return rc; } @@ -1223,7 +1257,7 @@ int __cil_verify_fsuse(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid fsuse at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid fsuse"); return rc; } @@ -1241,7 +1275,7 @@ int __cil_verify_permissionx(struct cil_permissionx *permx, struct cil_tree_node kind_str = CIL_KEY_IOCTL; break; default: - cil_log(CIL_ERR, "Invalid permissionx kind (%d) at line %d of %s\n", permx->kind, node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid permissionx kind (%d)", permx->kind); rc = SEPOL_ERR; goto exit; } @@ -1257,7 +1291,7 @@ int __cil_verify_permissionx(struct cil_permissionx *permx, struct cil_tree_node } if (rc == SEPOL_ENOENT) { - cil_log(CIL_ERR, "Invalid permissionx at line %d of %s: %s is not a permission of class %s\n", node->line, node->path, kind_str, class->datum.name); + cil_tree_log(node, CIL_ERR, "Invalid permissionx: %s is not a permission of class %s", kind_str, class->datum.name); rc = SEPOL_ERR; goto exit; } @@ -1312,7 +1346,7 @@ int __cil_verify_class(struct cil_tree_node *node) return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid class at line %d of %s\n", node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid class"); return rc; } @@ -1329,8 +1363,7 @@ int __cil_verify_policycap(struct cil_tree_node *node) return SEPOL_OK; exit: - cil_log(CIL_ERR, "Invalid policycap (%s) at line %d of %s\n", - (const char*)polcap->datum.name, node->line, node->path); + cil_tree_log(node, CIL_ERR, "Invalid policycap (%s)", (const char*)polcap->datum.name); return rc; } @@ -1453,6 +1486,12 @@ int __cil_verify_helper(struct cil_tree_node *node, uint32_t *finished, void *ex case CIL_NODECON: rc = __cil_verify_nodecon(db, node); break; + case CIL_IBPKEYCON: + rc = __cil_verify_ibpkeycon(db, node); + break; + case CIL_IBENDPORTCON: + rc = __cil_verify_ibendportcon(db, node); + break; case CIL_PORTCON: rc = __cil_verify_portcon(db, node); break; @@ -1547,14 +1586,14 @@ static int __cil_verify_classpermission(struct cil_tree_node *node) struct cil_classpermission *cp = node->data; if (cp->classperms == NULL) { - cil_log(CIL_ERR, "Classpermission %s does not have a classpermissionset at line %d of %s\n", cp->datum.name, node->line, node->path); + cil_tree_log(node, CIL_ERR, "Classpermission %s does not have a classpermissionset", cp->datum.name); rc = SEPOL_ERR; goto exit; } rc = __cil_verify_classperms(cp->classperms, &cp->datum); if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Found circular class permissions involving the set %s at line %d of %s\n",cp->datum.name, node->line, node->path); + cil_tree_log(node, CIL_ERR, "Found circular class permissions involving the set %s",cp->datum.name); goto exit; } @@ -1577,14 +1616,14 @@ static int __verify_map_perm_classperms(__attribute__((unused)) hashtab_key_t k, struct cil_perm *cmp = (struct cil_perm *)d; if (cmp->classperms == NULL) { - cil_log(CIL_ERR, "Map class %s does not have a classmapping for %s at line %d of %s\n", map_args->class->datum.name, cmp->datum.name, map_args->node->line, map_args->node->path); + cil_tree_log(map_args->node, CIL_ERR, "Map class %s does not have a classmapping for %s", map_args->class->datum.name, cmp->datum.name); map_args->rc = SEPOL_ERR; goto exit; } rc = __cil_verify_classperms(cmp->classperms, &cmp->datum); if (rc != SEPOL_OK) { - cil_log(CIL_ERR, "Found circular class permissions involving the map class %s and permission %s at line %d of %s\n", map_args->class->datum.name, cmp->datum.name, map_args->node->line, map_args->node->path); + cil_tree_log(map_args->node, CIL_ERR, "Found circular class permissions involving the map class %s and permission %s", map_args->class->datum.name, cmp->datum.name); map_args->rc = SEPOL_ERR; goto exit; } diff --git libsepol-2.5/include/sepol/ibendport_record.h libsepol-2.5/include/sepol/ibendport_record.h new file mode 100644 index 0000000..e30b252 --- /dev/null +++ libsepol-2.5/include/sepol/ibendport_record.h @@ -0,0 +1,68 @@ +#ifndef _SEPOL_IBENDPORT_RECORD_H_ +#define _SEPOL_IBENDPORT_RECORD_H_ + +#include +#include +#include +#include + +__BEGIN_DECLS + +struct sepol_ibendport; +struct sepol_ibendport_key; +typedef struct sepol_ibendport sepol_ibendport_t; +typedef struct sepol_ibendport_key sepol_ibendport_key_t; + +extern int sepol_ibendport_compare(const sepol_ibendport_t *ibendport, + const sepol_ibendport_key_t *key); + +extern int sepol_ibendport_compare2(const sepol_ibendport_t *ibendport, + const sepol_ibendport_t *ibendport2); + +extern int sepol_ibendport_key_create(sepol_handle_t *handle, + const char *ibdev_name, + int port, + sepol_ibendport_key_t **key_ptr); + +extern void sepol_ibendport_key_unpack(const sepol_ibendport_key_t *key, + const char **ibdev_name, + int *port); + +extern int sepol_ibendport_alloc_ibdev_name(sepol_handle_t *handle, + char **ibdev_name); + +extern int sepol_ibendport_key_extract(sepol_handle_t *handle, + const sepol_ibendport_t *ibendport, + sepol_ibendport_key_t **key_ptr); + +extern void sepol_ibendport_key_free(sepol_ibendport_key_t *key); + +extern void sepol_ibendport_set_port(sepol_ibendport_t *ibendport, int port); + +extern int sepol_ibendport_get_port(const sepol_ibendport_t *ibendport); + +extern int sepol_ibendport_get_ibdev_name(sepol_handle_t *handle, + const sepol_ibendport_t *ibendport, + char **ibdev_name); + +extern int sepol_ibendport_set_ibdev_name(sepol_handle_t *handle, + sepol_ibendport_t *ibendport, + const char *ibdev_name); + +extern sepol_context_t *sepol_ibendport_get_con(const sepol_ibendport_t *ibendport); + +extern int sepol_ibendport_set_con(sepol_handle_t *handle, + sepol_ibendport_t *ibendport, + sepol_context_t *con); + +extern int sepol_ibendport_create(sepol_handle_t *handle, + sepol_ibendport_t **ibendport_ptr); + +extern int sepol_ibendport_clone(sepol_handle_t *handle, + const sepol_ibendport_t *ibendport, + sepol_ibendport_t **ibendport_ptr); + +extern void sepol_ibendport_free(sepol_ibendport_t *ibendport); + +__END_DECLS +#endif diff --git libsepol-2.5/include/sepol/ibendports.h libsepol-2.5/include/sepol/ibendports.h new file mode 100644 index 0000000..4a89e0c --- /dev/null +++ libsepol-2.5/include/sepol/ibendports.h @@ -0,0 +1,45 @@ +#ifndef _SEPOL_IBENDPORTS_H_ +#define _SEPOL_IBENDPORTS_H_ + +#include +#include +#include +#include + +__BEGIN_DECLS + +/* Return the number of ibendports */ +extern int sepol_ibendport_count(sepol_handle_t *handle, + const sepol_policydb_t *p, + unsigned int *response); + +/* Check if a ibendport exists */ +extern int sepol_ibendport_exists(sepol_handle_t *handle, + const sepol_policydb_t *policydb, + const sepol_ibendport_key_t *key, int *response); + +/* Query a ibendport - returns the ibendport, or NULL if not found */ +extern int sepol_ibendport_query(sepol_handle_t *handle, + const sepol_policydb_t *policydb, + const sepol_ibendport_key_t *key, + sepol_ibendport_t **response); + +/* Modify a ibendport, or add it, if the key is not found */ +extern int sepol_ibendport_modify(sepol_handle_t *handle, + sepol_policydb_t *policydb, + const sepol_ibendport_key_t *key, + const sepol_ibendport_t *data); + +/* Iterate the ibendports + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue + */ +extern int sepol_ibendport_iterate(sepol_handle_t *handle, + const sepol_policydb_t *policydb, + int (*fn)(const sepol_ibendport_t *ibendport, + void *fn_arg), void *arg); + +__END_DECLS +#endif diff --git libsepol-2.5/include/sepol/ibpkey_record.h libsepol-2.5/include/sepol/ibpkey_record.h new file mode 100644 index 0000000..ab68147 --- /dev/null +++ libsepol-2.5/include/sepol/ibpkey_record.h @@ -0,0 +1,75 @@ +#ifndef _SEPOL_IBPKEY_RECORD_H_ +#define _SEPOL_IBPKEY_RECORD_H_ + +#include +#include +#include +#include +#include + +#define INET6_ADDRLEN 16 + +__BEGIN_DECLS + +struct sepol_ibpkey; +struct sepol_ibpkey_key; +typedef struct sepol_ibpkey sepol_ibpkey_t; +typedef struct sepol_ibpkey_key sepol_ibpkey_key_t; + +extern int sepol_ibpkey_compare(const sepol_ibpkey_t *ibpkey, + const sepol_ibpkey_key_t *key); + +extern int sepol_ibpkey_compare2(const sepol_ibpkey_t *ibpkey, + const sepol_ibpkey_t *ibpkey2); + +extern int sepol_ibpkey_key_create(sepol_handle_t *handle, + const char *subnet_prefix, + int low, int high, + sepol_ibpkey_key_t **key_ptr); + +extern void sepol_ibpkey_key_unpack(const sepol_ibpkey_key_t *key, + uint64_t *subnet_prefix, + int *low, int *high); + +extern int sepol_ibpkey_key_extract(sepol_handle_t *handle, + const sepol_ibpkey_t *ibpkey, + sepol_ibpkey_key_t **key_ptr); + +extern void sepol_ibpkey_key_free(sepol_ibpkey_key_t *key); + +extern int sepol_ibpkey_get_low(const sepol_ibpkey_t *ibpkey); + +extern int sepol_ibpkey_get_high(const sepol_ibpkey_t *ibpkey); + +extern void sepol_ibpkey_set_pkey(sepol_ibpkey_t *ibpkey, int pkey_num); + +extern void sepol_ibpkey_set_range(sepol_ibpkey_t *ibpkey, int low, int high); + +extern int sepol_ibpkey_get_subnet_prefix(sepol_handle_t *handle, + const sepol_ibpkey_t *ibpkey, + char **subnet_prefix); + +extern uint64_t sepol_ibpkey_get_subnet_prefix_bytes(const sepol_ibpkey_t *ibpkey); + +extern int sepol_ibpkey_set_subnet_prefix(sepol_handle_t *handle, + sepol_ibpkey_t *ibpkey, + const char *subnet_prefix); + +extern void sepol_ibpkey_set_subnet_prefix_bytes(sepol_ibpkey_t *ibpkey, + uint64_t subnet_prefix); + +extern sepol_context_t *sepol_ibpkey_get_con(const sepol_ibpkey_t *ibpkey); + +extern int sepol_ibpkey_set_con(sepol_handle_t *handle, + sepol_ibpkey_t *ibpkey, sepol_context_t *con); + +extern int sepol_ibpkey_create(sepol_handle_t *handle, sepol_ibpkey_t **ibpkey_ptr); + +extern int sepol_ibpkey_clone(sepol_handle_t *handle, + const sepol_ibpkey_t *ibpkey, + sepol_ibpkey_t **ibpkey_ptr); + +extern void sepol_ibpkey_free(sepol_ibpkey_t *ibpkey); + +__END_DECLS +#endif diff --git libsepol-2.5/include/sepol/ibpkeys.h libsepol-2.5/include/sepol/ibpkeys.h new file mode 100644 index 0000000..4ab0a8a --- /dev/null +++ libsepol-2.5/include/sepol/ibpkeys.h @@ -0,0 +1,44 @@ +#ifndef _SEPOL_IBPKEYS_H_ +#define _SEPOL_IBPKEYS_H_ + +#include +#include +#include +#include + +__BEGIN_DECLS + +/* Return the number of ibpkeys */ +extern int sepol_ibpkey_count(sepol_handle_t *handle, + const sepol_policydb_t *p, unsigned int *response); + +/* Check if a ibpkey exists */ +extern int sepol_ibpkey_exists(sepol_handle_t *handle, + const sepol_policydb_t *policydb, + const sepol_ibpkey_key_t *key, int *response); + +/* Query a ibpkey - returns the ibpkey, or NULL if not found */ +extern int sepol_ibpkey_query(sepol_handle_t *handle, + const sepol_policydb_t *policydb, + const sepol_ibpkey_key_t *key, + sepol_ibpkey_t **response); + +/* Modify a ibpkey, or add it, if the key is not found */ +extern int sepol_ibpkey_modify(sepol_handle_t *handle, + sepol_policydb_t *policydb, + const sepol_ibpkey_key_t *key, + const sepol_ibpkey_t *data); + +/* Iterate the ibpkeys + * The handler may return: + * -1 to signal an error condition, + * 1 to signal successful exit + * 0 to signal continue + */ +extern int sepol_ibpkey_iterate(sepol_handle_t *handle, + const sepol_policydb_t *policydb, + int (*fn)(const sepol_ibpkey_t *ibpkey, + void *fn_arg), void *arg); + +__END_DECLS +#endif diff --git libsepol-2.5/include/sepol/policydb/polcaps.h libsepol-2.5/include/sepol/policydb/polcaps.h index 74b7c9e..2018083 100644 --- libsepol-2.5/include/sepol/policydb/polcaps.h +++ libsepol-2.5/include/sepol/policydb/polcaps.h @@ -11,6 +11,8 @@ enum { POLICYDB_CAPABILITY_OPENPERM, POLICYDB_CAPABILITY_REDHAT1, /* reserved for RH testing of ptrace_child */ POLICYDB_CAPABILITY_ALWAYSNETWORK, + POLICYDB_CAPABILITY_CGROUPSECLABEL, + POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION, __POLICYDB_CAPABILITY_MAX }; #define POLICYDB_CAPABILITY_MAX (__POLICYDB_CAPABILITY_MAX - 1) diff --git libsepol-2.5/include/sepol/policydb/policydb.h libsepol-2.5/include/sepol/policydb/policydb.h index 26cec13..a4dc6ec 100644 --- libsepol-2.5/include/sepol/policydb/policydb.h +++ libsepol-2.5/include/sepol/policydb/policydb.h @@ -24,6 +24,7 @@ * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * Copyright (C) 2003 - 2004 Tresys Technology, LLC * Copyright (C) 2003 - 2004 Red Hat, Inc. + * Copyright (C) 2017 Mellanox Techonolgies Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -71,6 +72,8 @@ __BEGIN_DECLS +#define IB_DEVICE_NAME_MAX 64 + /* * A datum type is defined for each kind of symbol * in the configuration data: individual permissions, @@ -353,6 +356,15 @@ typedef struct ocontext { uint32_t low_ioport; uint32_t high_ioport; } ioport; + struct { + uint64_t subnet_prefix; + uint16_t low_pkey; + uint16_t high_pkey; + } ibpkey; + struct { + char *dev_name; + uint8_t port; + } ibendport; } u; union { uint32_t sclass; /* security class for genfs */ @@ -381,14 +393,15 @@ typedef struct genfs { #define SYM_NUM 8 /* object context array indices */ -#define OCON_ISID 0 /* initial SIDs */ -#define OCON_FS 1 /* unlabeled file systems */ -#define OCON_PORT 2 /* TCP and UDP port numbers */ -#define OCON_NETIF 3 /* network interfaces */ -#define OCON_NODE 4 /* nodes */ -#define OCON_FSUSE 5 /* fs_use */ -#define OCON_NODE6 6 /* IPv6 nodes */ -#define OCON_GENFS 7 /* needed for ocontext_supported */ +#define OCON_ISID 0 /* initial SIDs */ +#define OCON_FS 1 /* unlabeled file systems */ +#define OCON_PORT 2 /* TCP and UDP port numbers */ +#define OCON_NETIF 3 /* network interfaces */ +#define OCON_NODE 4 /* nodes */ +#define OCON_FSUSE 5 /* fs_use */ +#define OCON_NODE6 6 /* IPv6 nodes */ +#define OCON_IBPKEY 7 /* Infiniband PKEY */ +#define OCON_IBENDPORT 8 /* Infiniband End Port */ /* object context array indices for Xen */ #define OCON_XEN_ISID 0 /* initial SIDs */ @@ -399,7 +412,7 @@ typedef struct genfs { #define OCON_XEN_DEVICETREE 5 /* device tree node */ /* OCON_NUM needs to be the largest index in any platform's ocontext array */ -#define OCON_NUM 7 +#define OCON_NUM 9 /* section: module information */ @@ -713,10 +726,11 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); #define POLICYDB_VERSION_CONSTRAINT_NAMES 29 #define POLICYDB_VERSION_XEN_DEVICETREE 30 /* Xen-specific */ #define POLICYDB_VERSION_XPERMS_IOCTL 30 /* Linux-specific */ +#define POLICYDB_VERSION_INFINIBAND 31 /* Linux-specific */ /* Range of policy versions we understand*/ #define POLICYDB_VERSION_MIN POLICYDB_VERSION_BASE -#define POLICYDB_VERSION_MAX POLICYDB_VERSION_XPERMS_IOCTL +#define POLICYDB_VERSION_MAX POLICYDB_VERSION_INFINIBAND /* Module versions and specific changes*/ #define MOD_POLICYDB_VERSION_BASE 4 @@ -735,9 +749,11 @@ extern int policydb_set_target_platform(policydb_t *p, int platform); #define MOD_POLICYDB_VERSION_NEW_OBJECT_DEFAULTS 15 #define MOD_POLICYDB_VERSION_DEFAULT_TYPE 16 #define MOD_POLICYDB_VERSION_CONSTRAINT_NAMES 17 +#define MOD_POLICYDB_VERSION_XPERMS_IOCTL 18 +#define MOD_POLICYDB_VERSION_INFINIBAND 19 #define MOD_POLICYDB_VERSION_MIN MOD_POLICYDB_VERSION_BASE -#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_CONSTRAINT_NAMES +#define MOD_POLICYDB_VERSION_MAX MOD_POLICYDB_VERSION_INFINIBAND #define POLICYDB_CONFIG_MLS 1 diff --git libsepol-2.5/include/sepol/policydb/services.h libsepol-2.5/include/sepol/policydb/services.h index 8a5dc9a..ea2fa2e 100644 --- libsepol-2.5/include/sepol/policydb/services.h +++ libsepol-2.5/include/sepol/policydb/services.h @@ -186,6 +186,22 @@ extern int sepol_port_sid(uint16_t domain, uint16_t port, sepol_security_id_t * out_sid); /* + * Return the SID of the ibpkey specified by + * `subnet prefix', and `pkey'. + */ +extern int sepol_ibpkey_sid(uint64_t subnet_prefix_p, + uint16_t pkey, + sepol_security_id_t *out_sid); + +/* + * Return the SID of the ibendport specified by + * `dev_name', and `port'. + */ +extern int sepol_ibendport_sid(char *dev_name, + uint8_t port, + sepol_security_id_t *out_sid); + +/* * Return the SIDs to use for a network interface * with the name `name'. The `if_sid' SID is returned for * the interface and the `msg_sid' SID is returned as diff --git libsepol-2.5/include/sepol/port_record.h libsepol-2.5/include/sepol/port_record.h index 697cea4..c07d1fa 100644 --- libsepol-2.5/include/sepol/port_record.h +++ libsepol-2.5/include/sepol/port_record.h @@ -14,6 +14,7 @@ typedef struct sepol_port_key sepol_port_key_t; #define SEPOL_PROTO_UDP 0 #define SEPOL_PROTO_TCP 1 +#define SEPOL_PROTO_DCCP 2 /* Key */ extern int sepol_port_compare(const sepol_port_t * port, diff --git libsepol-2.5/include/sepol/sepol.h libsepol-2.5/include/sepol/sepol.h index 00a2129..66a98f2 100644 --- libsepol-2.5/include/sepol/sepol.h +++ libsepol-2.5/include/sepol/sepol.h @@ -10,12 +10,16 @@ __BEGIN_DECLS #include #include #include +#include +#include #include #include #include #include #include +#include +#include #include #include #include diff --git libsepol-2.5/src/Makefile libsepol-2.5/src/Makefile index db6c2ba..b0c901f 100644 --- libsepol-2.5/src/Makefile +++ libsepol-2.5/src/Makefile @@ -18,15 +18,15 @@ TARGET=libsepol.so LIBPC=libsepol.pc LIBMAP=libsepol.map LIBSO=$(TARGET).$(LIBVERSION) -OBJS= $(patsubst %.c,%.o,$(wildcard *.c)) -LOBJS= $(patsubst %.c,%.lo,$(wildcard *.c)) +OBJS= $(patsubst %.c,%.o,$(sort $(wildcard *.c))) +LOBJS= $(patsubst %.c,%.lo,$(sort $(wildcard *.c))) CFLAGS ?= -Werror -Wall -W -Wundef -Wshadow -Wmissing-format-attribute -O2 override CFLAGS += -I. -I../include -D_GNU_SOURCE ifneq ($(DISABLE_CIL),y) -OBJS += $(sort $(patsubst %.c,%.o,$(wildcard $(CILDIR)/src/*.c) $(CIL_GENERATED))) -LOBJS += $(sort $(patsubst %.c,%.lo,$(wildcard $(CILDIR)/src/*.c) $(CIL_GENERATED))) +OBJS += $(sort $(patsubst %.c,%.o,$(sort $(wildcard $(CILDIR)/src/*.c)) $(CIL_GENERATED))) +LOBJS += $(sort $(patsubst %.c,%.lo,$(sort $(wildcard $(CILDIR)/src/*.c)) $(CIL_GENERATED))) override CFLAGS += -I$(CILDIR)/include endif @@ -76,7 +76,7 @@ relabel: /sbin/restorecon $(SHLIBDIR)/$(LIBSO) clean: - -rm -f $(LIBPC) $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(TARGET) $(CIL_GENERATED) + -rm -f $(LIBPC) $(LIBMAP) $(OBJS) $(LOBJS) $(LIBA) $(LIBSO) $(TARGET) $(CIL_GENERATED) indent: ../../scripts/Lindent $(wildcard *.[ch]) diff --git libsepol-2.5/src/assertion.c libsepol-2.5/src/assertion.c index fbf397f..a4be880 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[stype]; + ebitmap_t *tattr = &p->type_attr_map[ttype]; + 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_permissions */ + 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[i], + p->p_type_val_to_name[j], + p->p_class_val_to_name[curperm->tclass - 1], + sepol_extended_perms_to_string(&error)); + + rc = 0; + ret++; + } + } } - } /* failure on the regular permissions */ @@ -304,9 +317,57 @@ oom: } /* - * If the ioctl permission is granted in check_assertion_avtab_match for the - * source/target/class matching the current avrule neverallow, a lookup is - * performed to determine if extended permissions exist for the source/target/class. + * Look up the extended permissions in avtab and verify that neverallowed + * permissions are not granted. + */ +static int check_assertion_extended_permissions_avtab(avrule_t *avrule, avtab_t *avtab, + unsigned int stype, unsigned int ttype, + 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[stype]; + ebitmap_t *tattr = &p->type_attr_map[ttype]; + 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; + + 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(neverallow_xperms, xperms); + if (rc) + break; + } + } + } + + return rc; +} + +/* + * When the ioctl permission is granted on an avtab entry that matches an + * avrule neverallowxperm entry, enumerate over the matching + * source/target/class sets to determine if the extended permissions exist + * and if the neverallowed ioctls are granted. * * Four scenarios of interest: * 1. PASS - the ioctl permission is not granted for this source/target/class @@ -319,33 +380,72 @@ 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; - int rc = 1; + ebitmap_t src_matches, tgt_matches, matches; + unsigned int i, j; + ebitmap_node_t *snode, *tnode; + class_perm_node_t *cp; + int rc; + int ret = 1; - memcpy(&tmp_key, k, sizeof(avtab_key_t)); - tmp_key.specified = AVTAB_XPERMS_ALLOWED; + ebitmap_init(&src_matches); + ebitmap_init(&tgt_matches); + ebitmap_init(&matches); + rc = ebitmap_and(&src_matches, &avrule->stypes.types, + &p->attr_type_map[k->source_type - 1]); + if (rc) + goto oom; - 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; + if (ebitmap_length(&src_matches) == 0) + goto exit; - rc = check_extended_permissions(neverallow_xperms, xperms); + if (avrule->flags == RULE_SELF) { + rc = ebitmap_and(&matches, &p->attr_type_map[k->source_type - 1], + &p->attr_type_map[k->target_type - 1]); if (rc) - break; + goto oom; + rc = ebitmap_and(&tgt_matches, &avrule->stypes.types, &matches); + if (rc) + goto oom; + } else { + rc = ebitmap_and(&tgt_matches, &avrule->ttypes.types, + &p->attr_type_map[k->target_type -1]); + if (rc) + goto oom; } - return rc; -} + if (ebitmap_length(&tgt_matches) == 0) + goto exit; + for (cp = avrule->perms; cp; cp = cp->next) { + if (cp->tclass != k->target_class) + continue; + ebitmap_for_each_bit(&src_matches, snode, i) { + if (!ebitmap_node_get_bit(snode, i)) + continue; + ebitmap_for_each_bit(&tgt_matches, tnode, j) { + if (!ebitmap_node_get_bit(tnode, j)) + continue; + + ret = check_assertion_extended_permissions_avtab( + avrule, avtab, i, j, k, p); + if (ret) + goto exit; + } + } + } + goto exit; + +oom: + ERR(NULL, "Out of memory - unable to check neverallows"); + +exit: + ebitmap_destroy(&src_matches); + ebitmap_destroy(&tgt_matches); + ebitmap_destroy(&matches); + return ret; +} static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *args) { @@ -355,7 +455,7 @@ static int check_assertion_avtab_match(avtab_key_t *k, avtab_datum_t *d, void *a avrule_t *avrule = a->avrule; avtab_t *avtab = a->avtab; - if (k->specified != AVTAB_ALLOWED && k->specified != AVTAB_XPERMS_ALLOWED) + if (k->specified != AVTAB_ALLOWED) goto exit; if (!match_any_class_permissions(avrule->perms, k->target_class, d->data)) @@ -386,7 +486,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/context.c libsepol-2.5/src/context.c index 84dad34..420ee16 100644 --- libsepol-2.5/src/context.c +++ libsepol-2.5/src/context.c @@ -55,7 +55,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; diff --git libsepol-2.5/src/expand.c libsepol-2.5/src/expand.c index 9cb7965..3fe6b56 100644 --- libsepol-2.5/src/expand.c +++ libsepol-2.5/src/expand.c @@ -4,6 +4,7 @@ * * Copyright (C) 2004-2005 Tresys Technology, LLC * Copyright (C) 2007 Red Hat, Inc. + * Copyright (C) 2017 Mellanox Technologies, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -2201,6 +2202,20 @@ static int ocontext_copy_selinux(expand_state_t *state) return -1; } break; + case OCON_IBPKEY: + n->u.ibpkey.subnet_prefix = c->u.ibpkey.subnet_prefix; + + n->u.ibpkey.low_pkey = c->u.ibpkey.low_pkey; + n->u.ibpkey.high_pkey = c->u.ibpkey.high_pkey; + break; + case OCON_IBENDPORT: + n->u.ibendport.dev_name = strdup(c->u.ibendport.dev_name); + if (!n->u.ibendport.dev_name) { + ERR(state->handle, "Out of memory!"); + return -1; + } + n->u.ibendport.port = c->u.ibendport.port; + break; case OCON_PORT: n->u.port.protocol = c->u.port.protocol; n->u.port.low_port = c->u.port.low_port; @@ -2497,6 +2512,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 +2521,25 @@ 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]->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 --- 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, if (boolf == NULL) goto localbool; -#ifdef DARWIN +#ifdef __APPLE__ if ((buffer = (char *)malloc(255 * sizeof(char))) == NULL) { ERR(NULL, "out of memory"); return -1; @@ -111,7 +111,7 @@ static int load_booleans(struct policydb *policydb, const char *path, boolf = fopen(localbools, "r"); if (boolf != NULL) { -#ifdef DARWIN +#ifdef __APPLE__ 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 --- libsepol-2.5/src/genusers.c +++ libsepol-2.5/src/genusers.c @@ -7,7 +7,7 @@ #include -#ifndef DARWIN +#ifndef __APPLE__ #include #endif @@ -47,7 +47,7 @@ static int load_users(struct policydb *policydb, const char *path) if (fp == NULL) return -1; -#ifdef DARWIN +#ifdef __APPLE__ if ((buffer = (char *)malloc(255 * sizeof(char))) == NULL) { ERR(NULL, "out of memory"); return -1; diff --git libsepol-2.5/src/hierarchy.c libsepol-2.5/src/hierarchy.c index 6f73195..778541a 100644 --- libsepol-2.5/src/hierarchy.c +++ libsepol-2.5/src/hierarchy.c @@ -121,18 +121,6 @@ static int bounds_expand_rule(sepol_handle_t *handle, policydb_t *p, } } - if (ebitmap_get_bit(&p->attr_type_map[tgt - 1], parent - 1)) { - avtab_key.target_type = parent; - ebitmap_for_each_bit(&p->attr_type_map[src - 1], tnode, i) { - if (!ebitmap_node_get_bit(tnode, i)) - continue; - avtab_key.source_type = i + 1; - rc = bounds_insert_rule(handle, avtab, global, other, - &avtab_key, &datum); - if (rc) goto exit; - } - } - exit: return rc; } @@ -313,45 +301,21 @@ static int bounds_check_rule(sepol_handle_t *handle, policydb_t *p, ebitmap_for_each_bit(&p->attr_type_map[tgt - 1], tnode, i) { if (!ebitmap_node_get_bit(tnode, i)) continue; - avtab_key.target_type = i + 1; - d = bounds_not_covered(global_avtab, cur_avtab, - &avtab_key, data); - if (!d) continue; td = p->type_val_to_struct[i]; if (td && td->bounds) { avtab_key.target_type = td->bounds; d = bounds_not_covered(global_avtab, cur_avtab, &avtab_key, data); - if (!d) continue; - } - (*numbad)++; - rc = bounds_add_bad(handle, child, i+1, class, d, bad); - if (rc) goto exit; - } - } - if (ebitmap_get_bit(&p->attr_type_map[tgt - 1], child - 1)) { - avtab_key.target_type = parent; - ebitmap_for_each_bit(&p->attr_type_map[src - 1], tnode, i) { - if (!ebitmap_node_get_bit(tnode, i)) - continue; - avtab_key.source_type = i + 1; - if (avtab_key.source_type == child) { - /* Checked above */ - continue; - } - d = bounds_not_covered(global_avtab, cur_avtab, - &avtab_key, data); - if (!d) continue; - td = p->type_val_to_struct[i]; - if (td && td->bounds) { - avtab_key.source_type = td->bounds; + } else { + avtab_key.target_type = i + 1; d = bounds_not_covered(global_avtab, cur_avtab, &avtab_key, data); - if (!d) continue; } - (*numbad)++; - rc = bounds_add_bad(handle, i+1, child, class, d, bad); - if (rc) goto exit; + if (d) { + (*numbad)++; + rc = bounds_add_bad(handle, child, i+1, class, d, bad); + if (rc) goto exit; + } } } diff --git libsepol-2.5/src/ibendport_internal.h libsepol-2.5/src/ibendport_internal.h new file mode 100644 index 0000000..ed8f9b4 --- /dev/null +++ libsepol-2.5/src/ibendport_internal.h @@ -0,0 +1,18 @@ +#ifndef _SEPOL_IBENDPORT_INTERNAL_H_ +#define _SEPOL_IBENDPORT_INTERNAL_H_ + +#include +#include +#include "dso.h" + +hidden_proto(sepol_ibendport_create) +hidden_proto(sepol_ibendport_free) +hidden_proto(sepol_ibendport_get_con) +hidden_proto(sepol_ibendport_get_port) +hidden_proto(sepol_ibendport_key_create) +hidden_proto(sepol_ibendport_key_unpack) +hidden_proto(sepol_ibendport_set_con) +hidden_proto(sepol_ibendport_set_port) +hidden_proto(sepol_ibendport_get_ibdev_name) +hidden_proto(sepol_ibendport_set_ibdev_name) +#endif diff --git libsepol-2.5/src/ibendport_record.c libsepol-2.5/src/ibendport_record.c new file mode 100644 index 0000000..912aeb5 --- /dev/null +++ libsepol-2.5/src/ibendport_record.c @@ -0,0 +1,298 @@ +#include +#include +#include +#include +#include + +#include "sepol/policydb/policydb.h" +#include "ibendport_internal.h" +#include "context_internal.h" +#include "debug.h" + +struct sepol_ibendport { + /* Device Name */ + char *ibdev_name; + + /* Port number */ + int port; + + /* Context */ + sepol_context_t *con; +}; + +struct sepol_ibendport_key { + /* Device Name */ + char *ibdev_name; + + /* Port number */ + int port; +}; + +/* Allocates a sufficiently large string (ibdev_name) */ +int sepol_ibendport_alloc_ibdev_name(sepol_handle_t *handle, + char **ibdev_name) +{ + char *tmp_ibdev_name = NULL; + + tmp_ibdev_name = calloc(1, IB_DEVICE_NAME_MAX); + + if (!tmp_ibdev_name) + goto omem; + + *ibdev_name = tmp_ibdev_name; + return STATUS_SUCCESS; + +omem: + ERR(handle, "out of memory"); + ERR(handle, "could not allocate string buffer for ibdev_name"); + return STATUS_ERR; +} + +/* Key */ +int sepol_ibendport_key_create(sepol_handle_t *handle, + const char *ibdev_name, + int port, + sepol_ibendport_key_t **key_ptr) +{ + sepol_ibendport_key_t *tmp_key = + (sepol_ibendport_key_t *)malloc(sizeof(sepol_ibendport_key_t)); + + if (!tmp_key) { + ERR(handle, "out of memory, could not create ibendport key"); + goto omem; + } + + if (sepol_ibendport_alloc_ibdev_name(handle, &tmp_key->ibdev_name) < 0) + goto err; + + strncpy(tmp_key->ibdev_name, ibdev_name, IB_DEVICE_NAME_MAX); + tmp_key->port = port; + + *key_ptr = tmp_key; + return STATUS_SUCCESS; + +omem: + ERR(handle, "out of memory"); + +err: + sepol_ibendport_key_free(tmp_key); + ERR(handle, "could not create ibendport key for IB device %s, port %u", + ibdev_name, port); + return STATUS_ERR; +} + +hidden_def(sepol_ibendport_key_create) + +void sepol_ibendport_key_unpack(const sepol_ibendport_key_t *key, + const char **ibdev_name, int *port) +{ + *ibdev_name = key->ibdev_name; + *port = key->port; +} + +hidden_def(sepol_ibendport_key_unpack) + +int sepol_ibendport_key_extract(sepol_handle_t *handle, + const sepol_ibendport_t *ibendport, + sepol_ibendport_key_t **key_ptr) +{ + if (sepol_ibendport_key_create + (handle, ibendport->ibdev_name, ibendport->port, key_ptr) < 0) { + ERR(handle, "could not extract key from ibendport device %s port %d", + ibendport->ibdev_name, + ibendport->port); + + return STATUS_ERR; + } + + return STATUS_SUCCESS; +} + +void sepol_ibendport_key_free(sepol_ibendport_key_t *key) +{ + if (!key) + return; + free(key->ibdev_name); + free(key); +} + +int sepol_ibendport_compare(const sepol_ibendport_t *ibendport, const sepol_ibendport_key_t *key) +{ + int rc; + + rc = strcmp(ibendport->ibdev_name, key->ibdev_name); + + if ((ibendport->port == key->port) && !rc) + return 0; + + if (ibendport->port < key->port) + return -1; + else if (key->port < ibendport->port) + return 1; + else + return rc; +} + +int sepol_ibendport_compare2(const sepol_ibendport_t *ibendport, const sepol_ibendport_t *ibendport2) +{ + int rc; + + rc = strcmp(ibendport->ibdev_name, ibendport2->ibdev_name); + + if ((ibendport->port == ibendport2->port) && !rc) + return 0; + + if (ibendport->port < ibendport2->port) + return -1; + else if (ibendport2->port < ibendport->port) + return 1; + else + return rc; +} + +int sepol_ibendport_get_port(const sepol_ibendport_t *ibendport) +{ + return ibendport->port; +} + +hidden_def(sepol_ibendport_get_port) + +void sepol_ibendport_set_port(sepol_ibendport_t *ibendport, int port) +{ + ibendport->port = port; +} + +hidden_def(sepol_ibendport_set_port) + +int sepol_ibendport_get_ibdev_name(sepol_handle_t *handle, + const sepol_ibendport_t *ibendport, + char **ibdev_name) +{ + char *tmp_ibdev_name = NULL; + + if (sepol_ibendport_alloc_ibdev_name(handle, &tmp_ibdev_name) < 0) + goto err; + + strncpy(tmp_ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX); + *ibdev_name = tmp_ibdev_name; + return STATUS_SUCCESS; + +err: + free(tmp_ibdev_name); + ERR(handle, "could not get ibendport ibdev_name"); + return STATUS_ERR; +} + +hidden_def(sepol_ibendport_get_ibdev_name) + +int sepol_ibendport_set_ibdev_name(sepol_handle_t *handle, + sepol_ibendport_t *ibendport, + const char *ibdev_name) +{ + char *tmp = NULL; + + if (sepol_ibendport_alloc_ibdev_name(handle, &tmp) < 0) + goto err; + + strncpy(tmp, ibdev_name, IB_DEVICE_NAME_MAX); + free(ibendport->ibdev_name); + ibendport->ibdev_name = tmp; + return STATUS_SUCCESS; + +err: + free(tmp); + ERR(handle, "could not set ibendport subnet prefix to %s", ibdev_name); + return STATUS_ERR; +} + +hidden_def(sepol_ibendport_set_ibdev_name) + +/* Create */ +int sepol_ibendport_create(sepol_handle_t *handle, sepol_ibendport_t **ibendport) +{ + sepol_ibendport_t *tmp_ibendport = (sepol_ibendport_t *)malloc(sizeof(sepol_ibendport_t)); + + if (!tmp_ibendport) { + ERR(handle, "out of memory, could not create ibendport record"); + return STATUS_ERR; + } + + tmp_ibendport->ibdev_name = NULL; + tmp_ibendport->port = 0; + tmp_ibendport->con = NULL; + *ibendport = tmp_ibendport; + + return STATUS_SUCCESS; +} + +hidden_def(sepol_ibendport_create) + +/* Deep copy clone */ +int sepol_ibendport_clone(sepol_handle_t *handle, + const sepol_ibendport_t *ibendport, + sepol_ibendport_t **ibendport_ptr) +{ + sepol_ibendport_t *new_ibendport = NULL; + + if (sepol_ibendport_create(handle, &new_ibendport) < 0) + goto err; + + if (sepol_ibendport_alloc_ibdev_name(handle, &new_ibendport->ibdev_name) < 0) + goto omem; + + strncpy(new_ibendport->ibdev_name, ibendport->ibdev_name, IB_DEVICE_NAME_MAX); + new_ibendport->port = ibendport->port; + + if (ibendport->con && + (sepol_context_clone(handle, ibendport->con, &new_ibendport->con) < 0)) + goto err; + + *ibendport_ptr = new_ibendport; + return STATUS_SUCCESS; + +omem: + ERR(handle, "out of memory"); + +err: + ERR(handle, "could not clone ibendport record"); + sepol_ibendport_free(new_ibendport); + return STATUS_ERR; +} + +/* Destroy */ +void sepol_ibendport_free(sepol_ibendport_t *ibendport) +{ + if (!ibendport) + return; + + free(ibendport->ibdev_name); + sepol_context_free(ibendport->con); + free(ibendport); +} + +hidden_def(sepol_ibendport_free) + +/* Context */ +sepol_context_t *sepol_ibendport_get_con(const sepol_ibendport_t *ibendport) +{ + return ibendport->con; +} + +hidden_def(sepol_ibendport_get_con) + +int sepol_ibendport_set_con(sepol_handle_t *handle, + sepol_ibendport_t *ibendport, sepol_context_t *con) +{ + sepol_context_t *newcon; + + if (sepol_context_clone(handle, con, &newcon) < 0) { + ERR(handle, "out of memory, could not set ibendport context"); + return STATUS_ERR; + } + + sepol_context_free(ibendport->con); + ibendport->con = newcon; + return STATUS_SUCCESS; +} + +hidden_def(sepol_ibendport_set_con) diff --git libsepol-2.5/src/ibendports.c libsepol-2.5/src/ibendports.c new file mode 100644 index 0000000..0438093 --- /dev/null +++ libsepol-2.5/src/ibendports.c @@ -0,0 +1,255 @@ +#include +#include + +#include "debug.h" +#include "context.h" +#include "handle.h" + +#include +#include "ibendport_internal.h" + +/* Create a low level ibendport structure from + * a high level representation + */ +static int ibendport_from_record(sepol_handle_t *handle, + const policydb_t *policydb, + ocontext_t **ibendport, + const sepol_ibendport_t *data) +{ + ocontext_t *tmp_ibendport = NULL; + context_struct_t *tmp_con = NULL; + char *ibdev_name = NULL; + int port = sepol_ibendport_get_port(data); + + tmp_ibendport = (ocontext_t *)calloc(1, sizeof(ocontext_t)); + if (!tmp_ibendport) + goto omem; + + if (sepol_ibendport_alloc_ibdev_name(handle, + &tmp_ibendport->u.ibendport.dev_name) < 0) + goto omem; + + if (sepol_ibendport_get_ibdev_name(handle, + data, + &ibdev_name) < 0) + goto err; + + strncpy(tmp_ibendport->u.ibendport.dev_name, ibdev_name, IB_DEVICE_NAME_MAX); + + free(ibdev_name); + ibdev_name = NULL; + + tmp_ibendport->u.ibendport.port = port; + + /* Context */ + if (context_from_record(handle, policydb, &tmp_con, + sepol_ibendport_get_con(data)) < 0) + goto err; + context_cpy(&tmp_ibendport->context[0], tmp_con); + context_destroy(tmp_con); + free(tmp_con); + tmp_con = NULL; + + *ibendport = tmp_ibendport; + return STATUS_SUCCESS; + +omem: + ERR(handle, "out of memory"); + +err: + if (tmp_ibendport) { + context_destroy(&tmp_ibendport->context[0]); + free(tmp_ibendport); + } + context_destroy(tmp_con); + free(tmp_con); + free(ibdev_name); + ERR(handle, "could not create ibendport structure"); + return STATUS_ERR; +} + +static int ibendport_to_record(sepol_handle_t *handle, + const policydb_t *policydb, + ocontext_t *ibendport, + sepol_ibendport_t **record) +{ + int port = ibendport->u.ibendport.port; + context_struct_t *con = &ibendport->context[0]; + + sepol_context_t *tmp_con = NULL; + sepol_ibendport_t *tmp_record = NULL; + + if (sepol_ibendport_create(handle, &tmp_record) < 0) + goto err; + + if (sepol_ibendport_set_ibdev_name(handle, tmp_record, + ibendport->u.ibendport.dev_name) < 0) + goto err; + + sepol_ibendport_set_port(tmp_record, port); + + if (context_to_record(handle, policydb, con, &tmp_con) < 0) + goto err; + + if (sepol_ibendport_set_con(handle, tmp_record, tmp_con) < 0) + goto err; + + sepol_context_free(tmp_con); + *record = tmp_record; + return STATUS_SUCCESS; + +err: + ERR(handle, "could not convert ibendport to record"); + sepol_context_free(tmp_con); + sepol_ibendport_free(tmp_record); + return STATUS_ERR; +} + +/* Return the number of ibendports */ +extern int sepol_ibendport_count(sepol_handle_t *handle __attribute__ ((unused)), + const sepol_policydb_t *p, unsigned int *response) +{ + unsigned int count = 0; + ocontext_t *c, *head; + const policydb_t *policydb = &p->p; + + head = policydb->ocontexts[OCON_IBENDPORT]; + for (c = head; c; c = c->next) + count++; + + *response = count; + + handle = NULL; + return STATUS_SUCCESS; +} + +/* Check if a ibendport exists */ +int sepol_ibendport_exists(sepol_handle_t *handle __attribute__ ((unused)), + const sepol_policydb_t *p, + const sepol_ibendport_key_t *key, int *response) +{ + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + int port; + const char *ibdev_name; + + sepol_ibendport_key_unpack(key, &ibdev_name, &port); + + head = policydb->ocontexts[OCON_IBENDPORT]; + for (c = head; c; c = c->next) { + const char *ibdev_name2 = c->u.ibendport.dev_name; + int port2 = c->u.ibendport.port; + + if (port2 == port && + (!strcmp(ibdev_name, ibdev_name2))) { + *response = 1; + return STATUS_SUCCESS; + } + } + + *response = 0; + return STATUS_SUCCESS; +} + +int sepol_ibendport_query(sepol_handle_t *handle, + const sepol_policydb_t *p, + const sepol_ibendport_key_t *key, + sepol_ibendport_t **response) +{ + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + int port; + const char *ibdev_name; + + sepol_ibendport_key_unpack(key, &ibdev_name, &port); + + head = policydb->ocontexts[OCON_IBENDPORT]; + for (c = head; c; c = c->next) { + const char *ibdev_name2 = c->u.ibendport.dev_name; + int port2 = c->u.ibendport.port; + + if (port2 == port && + (!strcmp(ibdev_name, ibdev_name2))) { + if (ibendport_to_record(handle, policydb, c, response) < 0) + goto err; + return STATUS_SUCCESS; + } + } + + *response = NULL; + return STATUS_SUCCESS; + +err: + ERR(handle, "could not query ibendport, IB device: %s port %u", + ibdev_name, port); + return STATUS_ERR; +} + +/* Load a ibendport into policy */ +int sepol_ibendport_modify(sepol_handle_t *handle, + sepol_policydb_t *p, + const sepol_ibendport_key_t *key, + const sepol_ibendport_t *data) +{ + policydb_t *policydb = &p->p; + ocontext_t *ibendport = NULL; + int port; + const char *ibdev_name; + + sepol_ibendport_key_unpack(key, &ibdev_name, &port); + + if (ibendport_from_record(handle, policydb, &ibendport, data) < 0) + goto err; + + /* Attach to context list */ + ibendport->next = policydb->ocontexts[OCON_IBENDPORT]; + policydb->ocontexts[OCON_IBENDPORT] = ibendport; + + return STATUS_SUCCESS; + +err: + ERR(handle, "could not load ibendport %s/%d", + ibdev_name, port); + if (ibendport) { + context_destroy(&ibendport->context[0]); + free(ibendport); + } + return STATUS_ERR; +} + +int sepol_ibendport_iterate(sepol_handle_t *handle, + const sepol_policydb_t *p, + int (*fn)(const sepol_ibendport_t *ibendport, + void *fn_arg), void *arg) +{ + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + sepol_ibendport_t *ibendport = NULL; + + head = policydb->ocontexts[OCON_IBENDPORT]; + for (c = head; c; c = c->next) { + int status; + + if (ibendport_to_record(handle, policydb, c, &ibendport) < 0) + goto err; + + /* Invoke handler */ + status = fn(ibendport, arg); + if (status < 0) + goto err; + + sepol_ibendport_free(ibendport); + ibendport = NULL; + + /* Handler requested exit */ + if (status > 0) + break; + } + + return STATUS_SUCCESS; + +err: + ERR(handle, "could not iterate over ibendports"); + sepol_ibendport_free(ibendport); + return STATUS_ERR; +} diff --git libsepol-2.5/src/ibpkey_internal.h libsepol-2.5/src/ibpkey_internal.h new file mode 100644 index 0000000..addf80a --- /dev/null +++ libsepol-2.5/src/ibpkey_internal.h @@ -0,0 +1,21 @@ +#ifndef _SEPOL_IBPKEY_INTERNAL_H_ +#define _SEPOL_IBPKEY_INTERNAL_H_ + +#include +#include +#include "dso.h" + +hidden_proto(sepol_ibpkey_create) +hidden_proto(sepol_ibpkey_free) +hidden_proto(sepol_ibpkey_get_con) +hidden_proto(sepol_ibpkey_get_high) +hidden_proto(sepol_ibpkey_get_low) +hidden_proto(sepol_ibpkey_key_create) +hidden_proto(sepol_ibpkey_key_unpack) +hidden_proto(sepol_ibpkey_set_con) +hidden_proto(sepol_ibpkey_set_range) +hidden_proto(sepol_ibpkey_get_subnet_prefix) +hidden_proto(sepol_ibpkey_get_subnet_prefix_bytes) +hidden_proto(sepol_ibpkey_set_subnet_prefix) +hidden_proto(sepol_ibpkey_set_subnet_prefix_bytes) +#endif diff --git libsepol-2.5/src/ibpkey_record.c libsepol-2.5/src/ibpkey_record.c new file mode 100644 index 0000000..badf2b3 --- /dev/null +++ libsepol-2.5/src/ibpkey_record.c @@ -0,0 +1,379 @@ +#include +#include +#include +#include +#include +#include + +#include "ibpkey_internal.h" +#include "context_internal.h" +#include "debug.h" + +struct sepol_ibpkey { + /* Subnet prefix */ + uint64_t subnet_prefix; + + /* Low - High range. Same for single ibpkeys. */ + int low, high; + + /* Context */ + sepol_context_t *con; +}; + +struct sepol_ibpkey_key { + /* Subnet prefix */ + uint64_t subnet_prefix; + + /* Low - High range. Same for single ibpkeys. */ + int low, high; +}; + +/* Converts a string represtation (subnet_prefix_str) + * to a numeric representation (subnet_prefix_bytes) + */ +static int ibpkey_parse_subnet_prefix(sepol_handle_t *handle, + const char *subnet_prefix_str, + uint64_t *subnet_prefix) +{ + struct in6_addr in_addr; + + if (inet_pton(AF_INET6, subnet_prefix_str, &in_addr) <= 0) { + ERR(handle, "could not parse IPv6 address for ibpkey subnet prefix %s: %s", + subnet_prefix_str, strerror(errno)); + return STATUS_ERR; + } + + memcpy(subnet_prefix, in_addr.s6_addr, sizeof(*subnet_prefix)); + + return STATUS_SUCCESS; +} + +/* Converts a numeric representation (subnet_prefix_bytes) + * to a string representation (subnet_prefix_str) + */ + +static int ibpkey_expand_subnet_prefix(sepol_handle_t *handle, + uint64_t subnet_prefix, + char *subnet_prefix_str) +{ + struct in6_addr addr; + + memset(&addr, 0, sizeof(struct in6_addr)); + memcpy(&addr.s6_addr[0], &subnet_prefix, sizeof(subnet_prefix)); + + if (inet_ntop(AF_INET6, &addr, subnet_prefix_str, + INET6_ADDRSTRLEN) == NULL) { + ERR(handle, + "could not expand IPv6 address to string: %s", + strerror(errno)); + return STATUS_ERR; + } + + return STATUS_SUCCESS; +} + +/* Allocates a sufficiently large string (subnet_prefix) + * for an IPV6 address for the subnet prefix + */ +static int ibpkey_alloc_subnet_prefix_string(sepol_handle_t *handle, + char **subnet_prefix) +{ + char *tmp_subnet_prefix = NULL; + + tmp_subnet_prefix = malloc(INET6_ADDRSTRLEN); + + if (!tmp_subnet_prefix) + goto omem; + + *subnet_prefix = tmp_subnet_prefix; + return STATUS_SUCCESS; + +omem: + ERR(handle, "out of memory"); + + ERR(handle, "could not allocate string buffer for subnet_prefix"); + return STATUS_ERR; +} + +/* Key */ +int sepol_ibpkey_key_create(sepol_handle_t *handle, + const char *subnet_prefix, + int low, int high, + sepol_ibpkey_key_t **key_ptr) +{ + sepol_ibpkey_key_t *tmp_key = + (sepol_ibpkey_key_t *)malloc(sizeof(sepol_ibpkey_key_t)); + + if (!tmp_key) { + ERR(handle, "out of memory, could not create ibpkey key"); + goto omem; + } + + if (ibpkey_parse_subnet_prefix(handle, subnet_prefix, &tmp_key->subnet_prefix) < 0) + goto err; + + tmp_key->low = low; + tmp_key->high = high; + + *key_ptr = tmp_key; + return STATUS_SUCCESS; + +omem: + ERR(handle, "out of memory"); + +err: + sepol_ibpkey_key_free(tmp_key); + ERR(handle, "could not create ibpkey key for subnet prefix%s, range %u, %u", + subnet_prefix, low, high); + return STATUS_ERR; +} + +hidden_def(sepol_ibpkey_key_create) + +void sepol_ibpkey_key_unpack(const sepol_ibpkey_key_t *key, + uint64_t *subnet_prefix, int *low, int *high) +{ + *subnet_prefix = key->subnet_prefix; + *low = key->low; + *high = key->high; +} + +hidden_def(sepol_ibpkey_key_unpack) + +int sepol_ibpkey_key_extract(sepol_handle_t *handle, + const sepol_ibpkey_t *ibpkey, + sepol_ibpkey_key_t **key_ptr) +{ + char subnet_prefix_str[INET6_ADDRSTRLEN]; + + ibpkey_expand_subnet_prefix(handle, ibpkey->subnet_prefix, subnet_prefix_str); + + if (sepol_ibpkey_key_create + (handle, subnet_prefix_str, ibpkey->low, ibpkey->high, key_ptr) < 0) { + ERR(handle, "could not extract key from ibpkey %s %d:%d", + subnet_prefix_str, + ibpkey->low, ibpkey->high); + + return STATUS_ERR; + } + + return STATUS_SUCCESS; +} + +void sepol_ibpkey_key_free(sepol_ibpkey_key_t *key) +{ + if (!key) + return; + free(key); +} + +int sepol_ibpkey_compare(const sepol_ibpkey_t *ibpkey, const sepol_ibpkey_key_t *key) +{ + if (ibpkey->subnet_prefix < key->subnet_prefix) + return -1; + if (key->subnet_prefix < ibpkey->subnet_prefix) + return 1; + + if (ibpkey->low < key->low) + return -1; + if (key->low < ibpkey->low) + return 1; + + if (ibpkey->high < key->high) + return -1; + if (key->high < ibpkey->high) + return 1; + + return 0; +} + +int sepol_ibpkey_compare2(const sepol_ibpkey_t *ibpkey, const sepol_ibpkey_t *ibpkey2) +{ + if (ibpkey->subnet_prefix < ibpkey2->subnet_prefix) + return -1; + if (ibpkey2->subnet_prefix < ibpkey->subnet_prefix) + return 1; + + if (ibpkey->low < ibpkey2->low) + return -1; + if (ibpkey2->low < ibpkey->low) + return 1; + + if (ibpkey->high < ibpkey2->high) + return -1; + if (ibpkey2->high < ibpkey->high) + return 1; + + return 0; +} + +/* Pkey */ +int sepol_ibpkey_get_low(const sepol_ibpkey_t *ibpkey) +{ + return ibpkey->low; +} + +hidden_def(sepol_ibpkey_get_low) + +int sepol_ibpkey_get_high(const sepol_ibpkey_t *ibpkey) +{ + return ibpkey->high; +} + +hidden_def(sepol_ibpkey_get_high) + +void sepol_ibpkey_set_pkey(sepol_ibpkey_t *ibpkey, int pkey_num) +{ + ibpkey->low = pkey_num; + ibpkey->high = pkey_num; +} + +void sepol_ibpkey_set_range(sepol_ibpkey_t *ibpkey, int low, int high) +{ + ibpkey->low = low; + ibpkey->high = high; +} + +hidden_def(sepol_ibpkey_set_range) + +int sepol_ibpkey_get_subnet_prefix(sepol_handle_t *handle, + const sepol_ibpkey_t *ibpkey, + char **subnet_prefix) +{ + char *tmp_subnet_prefix = NULL; + + if (ibpkey_alloc_subnet_prefix_string(handle, &tmp_subnet_prefix) < 0) + goto err; + + if (ibpkey_expand_subnet_prefix(handle, ibpkey->subnet_prefix, tmp_subnet_prefix) < 0) + goto err; + + *subnet_prefix = tmp_subnet_prefix; + return STATUS_SUCCESS; + +err: + free(tmp_subnet_prefix); + ERR(handle, "could not get ibpkey subnet_prefix"); + return STATUS_ERR; +} + +hidden_def(sepol_ibpkey_get_subnet_prefix) + +/* Subnet prefix */ +uint64_t sepol_ibpkey_get_subnet_prefix_bytes(const sepol_ibpkey_t *ibpkey) +{ + return ibpkey->subnet_prefix; +} + +hidden_def(sepol_ibpkey_get_subnet_prefix_bytes) + +int sepol_ibpkey_set_subnet_prefix(sepol_handle_t *handle, + sepol_ibpkey_t *ibpkey, + const char *subnet_prefix_str) +{ + uint64_t tmp = 0; + + if (ibpkey_parse_subnet_prefix(handle, subnet_prefix_str, &tmp) < 0) + goto err; + + ibpkey->subnet_prefix = tmp; + return STATUS_SUCCESS; + +err: + ERR(handle, "could not set ibpkey subnet prefix to %s", subnet_prefix_str); + return STATUS_ERR; +} + +hidden_def(sepol_ibpkey_set_subnet_prefix) + +void sepol_ibpkey_set_subnet_prefix_bytes(sepol_ibpkey_t *ibpkey, + uint64_t subnet_prefix) +{ + ibpkey->subnet_prefix = subnet_prefix; +} + +hidden_def(sepol_ibpkey_set_subnet_prefix_bytes) + +/* Create */ +int sepol_ibpkey_create(sepol_handle_t *handle, sepol_ibpkey_t **ibpkey) +{ + sepol_ibpkey_t *tmp_ibpkey = (sepol_ibpkey_t *)malloc(sizeof(sepol_ibpkey_t)); + + if (!tmp_ibpkey) { + ERR(handle, "out of memory, could not create ibpkey record"); + return STATUS_ERR; + } + + tmp_ibpkey->subnet_prefix = 0; + tmp_ibpkey->low = 0; + tmp_ibpkey->high = 0; + tmp_ibpkey->con = NULL; + *ibpkey = tmp_ibpkey; + + return STATUS_SUCCESS; +} + +hidden_def(sepol_ibpkey_create) + +/* Deep copy clone */ +int sepol_ibpkey_clone(sepol_handle_t *handle, + const sepol_ibpkey_t *ibpkey, sepol_ibpkey_t **ibpkey_ptr) +{ + sepol_ibpkey_t *new_ibpkey = NULL; + + if (sepol_ibpkey_create(handle, &new_ibpkey) < 0) + goto err; + + new_ibpkey->subnet_prefix = ibpkey->subnet_prefix; + new_ibpkey->low = ibpkey->low; + new_ibpkey->high = ibpkey->high; + + if (ibpkey->con && + (sepol_context_clone(handle, ibpkey->con, &new_ibpkey->con) < 0)) + goto err; + + *ibpkey_ptr = new_ibpkey; + return STATUS_SUCCESS; + +err: + ERR(handle, "could not clone ibpkey record"); + sepol_ibpkey_free(new_ibpkey); + return STATUS_ERR; +} + +/* Destroy */ +void sepol_ibpkey_free(sepol_ibpkey_t *ibpkey) +{ + if (!ibpkey) + return; + + sepol_context_free(ibpkey->con); + free(ibpkey); +} + +hidden_def(sepol_ibpkey_free) + +/* Context */ +sepol_context_t *sepol_ibpkey_get_con(const sepol_ibpkey_t *ibpkey) +{ + return ibpkey->con; +} + +hidden_def(sepol_ibpkey_get_con) + +int sepol_ibpkey_set_con(sepol_handle_t *handle, + sepol_ibpkey_t *ibpkey, sepol_context_t *con) +{ + sepol_context_t *newcon; + + if (sepol_context_clone(handle, con, &newcon) < 0) { + ERR(handle, "out of memory, could not set ibpkey context"); + return STATUS_ERR; + } + + sepol_context_free(ibpkey->con); + ibpkey->con = newcon; + return STATUS_SUCCESS; +} + +hidden_def(sepol_ibpkey_set_con) diff --git libsepol-2.5/src/ibpkeys.c libsepol-2.5/src/ibpkeys.c new file mode 100644 index 0000000..ad6c07f --- /dev/null +++ libsepol-2.5/src/ibpkeys.c @@ -0,0 +1,251 @@ +#include +#include + +#include "debug.h" +#include "context.h" +#include "handle.h" + +#include +#include +#include "ibpkey_internal.h" + +/* Create a low level ibpkey structure from + * a high level representation + */ +static int ibpkey_from_record(sepol_handle_t *handle, + const policydb_t *policydb, + ocontext_t **ibpkey, const sepol_ibpkey_t *data) +{ + ocontext_t *tmp_ibpkey = NULL; + context_struct_t *tmp_con = NULL; + char *subnet_prefix_buf = NULL; + int low = sepol_ibpkey_get_low(data); + int high = sepol_ibpkey_get_high(data); + + tmp_ibpkey = (ocontext_t *)calloc(1, sizeof(*tmp_ibpkey)); + if (!tmp_ibpkey) + goto omem; + + tmp_ibpkey->u.ibpkey.subnet_prefix = sepol_ibpkey_get_subnet_prefix_bytes(data); + + /* Pkey range */ + tmp_ibpkey->u.ibpkey.low_pkey = low; + tmp_ibpkey->u.ibpkey.high_pkey = high; + if (tmp_ibpkey->u.ibpkey.low_pkey > tmp_ibpkey->u.ibpkey.high_pkey) { + ERR(handle, "low ibpkey %d exceeds high ibpkey %d", + tmp_ibpkey->u.ibpkey.low_pkey, tmp_ibpkey->u.ibpkey.high_pkey); + goto err; + } + + /* Context */ + if (context_from_record(handle, policydb, &tmp_con, + sepol_ibpkey_get_con(data)) < 0) + goto err; + context_cpy(&tmp_ibpkey->context[0], tmp_con); + context_destroy(tmp_con); + free(tmp_con); + tmp_con = NULL; + + *ibpkey = tmp_ibpkey; + return STATUS_SUCCESS; + +omem: + ERR(handle, "out of memory"); + +err: + if (tmp_ibpkey) { + context_destroy(&tmp_ibpkey->context[0]); + free(tmp_ibpkey); + } + context_destroy(tmp_con); + free(tmp_con); + free(subnet_prefix_buf); + ERR(handle, "could not create ibpkey structure"); + return STATUS_ERR; +} + +static int ibpkey_to_record(sepol_handle_t *handle, + const policydb_t *policydb, + ocontext_t *ibpkey, sepol_ibpkey_t **record) +{ + context_struct_t *con = &ibpkey->context[0]; + sepol_context_t *tmp_con = NULL; + sepol_ibpkey_t *tmp_record = NULL; + + if (sepol_ibpkey_create(handle, &tmp_record) < 0) + goto err; + + sepol_ibpkey_set_subnet_prefix_bytes(tmp_record, + ibpkey->u.ibpkey.subnet_prefix); + + sepol_ibpkey_set_range(tmp_record, ibpkey->u.ibpkey.low_pkey, + ibpkey->u.ibpkey.high_pkey); + + if (context_to_record(handle, policydb, con, &tmp_con) < 0) + goto err; + + if (sepol_ibpkey_set_con(handle, tmp_record, tmp_con) < 0) + goto err; + + sepol_context_free(tmp_con); + *record = tmp_record; + return STATUS_SUCCESS; + +err: + ERR(handle, "could not convert ibpkey to record"); + sepol_context_free(tmp_con); + sepol_ibpkey_free(tmp_record); + return STATUS_ERR; +} + +/* Return the number of ibpkeys */ +extern int sepol_ibpkey_count(sepol_handle_t *handle __attribute__ ((unused)), + const sepol_policydb_t *p, unsigned int *response) +{ + unsigned int count = 0; + ocontext_t *c, *head; + const policydb_t *policydb = &p->p; + + head = policydb->ocontexts[OCON_IBPKEY]; + for (c = head; c; c = c->next) + count++; + + *response = count; + + handle = NULL; + return STATUS_SUCCESS; +} + +/* Check if a ibpkey exists */ +int sepol_ibpkey_exists(sepol_handle_t *handle __attribute__ ((unused)), + const sepol_policydb_t *p, + const sepol_ibpkey_key_t *key, int *response) +{ + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + int low, high; + uint64_t subnet_prefix; + + sepol_ibpkey_key_unpack(key, &subnet_prefix, &low, &high); + + head = policydb->ocontexts[OCON_IBPKEY]; + for (c = head; c; c = c->next) { + uint64_t subnet_prefix2 = c->u.ibpkey.subnet_prefix; + uint16_t low2 = c->u.ibpkey.low_pkey; + uint16_t high2 = c->u.ibpkey.high_pkey; + + if (low2 == low && + high2 == high && + subnet_prefix == subnet_prefix2) { + *response = 1; + return STATUS_SUCCESS; + } + } + + *response = 0; + return STATUS_SUCCESS; +} + +/* Query a ibpkey */ +int sepol_ibpkey_query(sepol_handle_t *handle, + const sepol_policydb_t *p, + const sepol_ibpkey_key_t *key, sepol_ibpkey_t **response) +{ + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + int low, high; + uint64_t subnet_prefix; + + sepol_ibpkey_key_unpack(key, &subnet_prefix, &low, &high); + + head = policydb->ocontexts[OCON_IBPKEY]; + for (c = head; c; c = c->next) { + uint64_t subnet_prefix2 = c->u.ibpkey.subnet_prefix; + int low2 = c->u.ibpkey.low_pkey; + int high2 = c->u.ibpkey.high_pkey; + + if (low2 == low && + high2 == high && + subnet_prefix == subnet_prefix2) { + if (ibpkey_to_record(handle, policydb, c, response) < 0) + goto err; + return STATUS_SUCCESS; + } + } + + *response = NULL; + return STATUS_SUCCESS; + +err: + ERR(handle, "could not query ibpkey subnet prefix: %#lx range %u - %u exists", + subnet_prefix, low, high); + return STATUS_ERR; +} + +/* Load a ibpkey into policy */ +int sepol_ibpkey_modify(sepol_handle_t *handle, + sepol_policydb_t *p, + const sepol_ibpkey_key_t *key, const sepol_ibpkey_t *data) +{ + policydb_t *policydb = &p->p; + ocontext_t *ibpkey = NULL; + int low, high; + uint64_t subnet_prefix; + + sepol_ibpkey_key_unpack(key, &subnet_prefix, &low, &high); + + if (ibpkey_from_record(handle, policydb, &ibpkey, data) < 0) + goto err; + + /* Attach to context list */ + ibpkey->next = policydb->ocontexts[OCON_IBPKEY]; + policydb->ocontexts[OCON_IBPKEY] = ibpkey; + + return STATUS_SUCCESS; + +err: + ERR(handle, "could not load ibpkey subnet prefix: %#lx range %u - %u exists", + subnet_prefix, low, high); + if (ibpkey) { + context_destroy(&ibpkey->context[0]); + free(ibpkey); + } + return STATUS_ERR; +} + +int sepol_ibpkey_iterate(sepol_handle_t *handle, + const sepol_policydb_t *p, + int (*fn)(const sepol_ibpkey_t *ibpkey, + void *fn_arg), void *arg) +{ + const policydb_t *policydb = &p->p; + ocontext_t *c, *head; + sepol_ibpkey_t *ibpkey = NULL; + + head = policydb->ocontexts[OCON_IBPKEY]; + for (c = head; c; c = c->next) { + int status; + + if (ibpkey_to_record(handle, policydb, c, &ibpkey) < 0) + goto err; + + /* Invoke handler */ + status = fn(ibpkey, arg); + if (status < 0) + goto err; + + sepol_ibpkey_free(ibpkey); + ibpkey = NULL; + + /* Handler requested exit */ + if (status > 0) + break; + } + + return STATUS_SUCCESS; + +err: + ERR(handle, "could not iterate over ibpkeys"); + sepol_ibpkey_free(ibpkey); + return STATUS_ERR; +} diff --git libsepol-2.5/src/libsepol.map.in libsepol-2.5/src/libsepol.map.in index 0a46b09..83491c0 100644 --- libsepol-2.5/src/libsepol.map.in +++ libsepol-2.5/src/libsepol.map.in @@ -6,6 +6,8 @@ LIBSEPOL_1.0 { sepol_context_*; sepol_mls_*; sepol_check_context; sepol_iface_*; sepol_port_*; + sepol_ibpkey_*; + sepol_ibendport_*; sepol_node_*; sepol_user_*; sepol_genusers; sepol_set_delusers; sepol_msg_*; sepol_debug; diff --git libsepol-2.5/src/link.c libsepol-2.5/src/link.c index f211164..cd4cc86 100644 --- libsepol-2.5/src/link.c +++ libsepol-2.5/src/link.c @@ -1325,6 +1325,15 @@ static int copy_avrule_list(avrule_t * list, avrule_t ** dst, tail_perm = new_perm; cur_perm = cur_perm->next; } + + if (cur->xperms) { + new_rule->xperms = calloc(1, sizeof(*new_rule->xperms)); + if (!new_rule->xperms) + goto cleanup; + memcpy(new_rule->xperms, cur->xperms, + sizeof(*new_rule->xperms)); + } + new_rule->line = cur->line; new_rule->source_line = cur->source_line; if (cur->source_filename) { @@ -2569,6 +2578,12 @@ int link_modules(sepol_handle_t * handle, goto cleanup; } + if (mods[i]->policyvers > b->policyvers) { + WARN(state.handle, + "Upgrading policy version from %u to %u\n", b->policyvers, mods[i]->policyvers); + b->policyvers = mods[i]->policyvers; + } + if ((modules[i] = (policy_module_t *) calloc(1, sizeof(policy_module_t))) == diff --git libsepol-2.5/src/module_to_cil.c libsepol-2.5/src/module_to_cil.c index 18ec6b9..26b1ee3 100644 --- libsepol-2.5/src/module_to_cil.c +++ libsepol-2.5/src/module_to_cil.c @@ -3,6 +3,7 @@ * Functions to convert policy module to CIL * * Copyright (C) 2015 Tresys Technology, LLC + * Copyright (C) 2017 Mellanox Technologies Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -26,6 +27,9 @@ #include #include #include +#ifndef IPPROTO_DCCP +#define IPPROTO_DCCP 33 +#endif #include #include #include @@ -602,6 +606,103 @@ exit: return rc; } +#define next_bit_in_range(i, p) ((i + 1 < sizeof(p)*8) && xperm_test((i + 1), p)) + +static int xperms_to_cil(const av_extended_perms_t *xperms) +{ + uint16_t value; + uint16_t low_bit; + uint16_t low_value; + unsigned int bit; + unsigned int in_range = 0; + int first = 1; + + if ((xperms->specified != AVTAB_XPERMS_IOCTLFUNCTION) + && (xperms->specified != AVTAB_XPERMS_IOCTLDRIVER)) + return -1; + + for (bit = 0; bit < sizeof(xperms->perms)*8; bit++) { + if (!xperm_test(bit, xperms->perms)) + continue; + + if (in_range && next_bit_in_range(bit, xperms->perms)) { + /* continue until high value found */ + continue; + } else if (next_bit_in_range(bit, xperms->perms)) { + /* low value */ + low_bit = bit; + in_range = 1; + continue; + } + + if (!first) + cil_printf(" "); + else + first = 0; + + if (xperms->specified & AVTAB_XPERMS_IOCTLFUNCTION) { + value = xperms->driver<<8 | bit; + low_value = xperms->driver<<8 | low_bit; + if (in_range) { + cil_printf("(range 0x%hx 0x%hx)", low_value, value); + in_range = 0; + } else { + cil_printf("0x%hx", value); + } + } else if (xperms->specified & AVTAB_XPERMS_IOCTLDRIVER) { + value = bit << 8; + low_value = low_bit << 8; + if (in_range) { + cil_printf("(range 0x%hx 0x%hx)", low_value, (uint16_t) (value|0xff)); + in_range = 0; + } else { + cil_printf("(range 0x%hx 0x%hx)", value, (uint16_t) (value|0xff)); + } + } + } + + return 0; +} + +static int avrulex_to_cil(int indent, struct policydb *pdb, uint32_t type, const char *src, const char *tgt, const class_perm_node_t *classperms, const av_extended_perms_t *xperms) +{ + int rc = -1; + const char *rule; + const struct class_perm_node *classperm; + + switch (type) { + case AVRULE_XPERMS_ALLOWED: + rule = "allowx"; + break; + case AVRULE_XPERMS_AUDITALLOW: + rule = "auditallowx"; + break; + case AVRULE_XPERMS_DONTAUDIT: + rule = "dontauditx"; + break; + case AVRULE_XPERMS_NEVERALLOW: + rule = "neverallowx"; + break; + default: + log_err("Unknown avrule xperm type: %i", type); + rc = -1; + goto exit; + } + + for (classperm = classperms; classperm != NULL; classperm = classperm->next) { + cil_indent(indent); + cil_printf("(%s %s %s (%s %s (", rule, src, tgt, + "ioctl", pdb->p_class_val_to_name[classperm->tclass - 1]); + xperms_to_cil(xperms); + cil_printf(")))\n"); + } + + return 0; + +exit: + return rc; +} + static int num_digits(int n) { int num = 1; @@ -1070,6 +1171,11 @@ 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) { + if ((avrule->specified & (AVRULE_NEVERALLOW|AVRULE_XPERMS_NEVERALLOW)) && + avrule->source_filename) { + cil_println(0, ";;* lmx %lu %s\n",avrule->source_line, avrule->source_filename); + } + ts = &avrule->stypes; rc = process_typeset(indent, pdb, ts, attr_list, &snames, &num_snames); if (rc != 0) { @@ -1084,14 +1190,22 @@ static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *a for (s = 0; s < num_snames; s++) { for (t = 0; t < num_tnames; t++) { - rc = avrule_to_cil(indent, pdb, avrule->specified, snames[s], tnames[t], avrule->perms); + if (avrule->specified & AVRULE_XPERMS) { + rc = avrulex_to_cil(indent, pdb, avrule->specified, snames[s], tnames[t], avrule->perms, avrule->xperms); + } else { + rc = avrule_to_cil(indent, pdb, avrule->specified, snames[s], tnames[t], avrule->perms); + } if (rc != 0) { goto exit; } } if (avrule->flags & RULE_SELF) { - rc = avrule_to_cil(indent, pdb, avrule->specified, snames[s], "self", avrule->perms); + if (avrule->specified & AVRULE_XPERMS) { + rc = avrulex_to_cil(indent, pdb, avrule->specified, snames[s], "self", avrule->perms, avrule->xperms); + } else { + rc = avrule_to_cil(indent, pdb, avrule->specified, snames[s], "self", avrule->perms); + } if (rc != 0) { goto exit; } @@ -1100,6 +1214,11 @@ static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *a names_destroy(&snames, &num_snames); names_destroy(&tnames, &num_tnames); + + if ((avrule->specified & (AVRULE_NEVERALLOW|AVRULE_XPERMS_NEVERALLOW)) && + avrule->source_filename) { + cil_println(0, ";;* lme\n"); + } } return 0; @@ -1292,7 +1411,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 +2656,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; + case IPPROTO_DCCP: protocol = "dccp"; break; default: log_err("Unknown portcon protocol: %i", portcon->u.port.protocol); rc = -1; @@ -2562,6 +2682,45 @@ exit: return rc; } +static int ocontext_selinux_ibpkey_to_cil(struct policydb *pdb, + struct ocontext *ibpkeycons) +{ + int rc = -1; + struct ocontext *ibpkeycon; + char subnet_prefix_str[INET6_ADDRSTRLEN]; + struct in6_addr subnet_prefix = IN6ADDR_ANY_INIT; + uint16_t high; + uint16_t low; + + for (ibpkeycon = ibpkeycons; ibpkeycon; ibpkeycon = ibpkeycon->next) { + low = ibpkeycon->u.ibpkey.low_pkey; + high = ibpkeycon->u.ibpkey.high_pkey; + memcpy(&subnet_prefix.s6_addr, &ibpkeycon->u.ibpkey.subnet_prefix, + sizeof(ibpkeycon->u.ibpkey.subnet_prefix)); + + if (inet_ntop(AF_INET6, &subnet_prefix.s6_addr, + subnet_prefix_str, INET6_ADDRSTRLEN) == NULL) { + log_err("ibpkeycon subnet_prefix is invalid: %s", + strerror(errno)); + rc = -1; + goto exit; + } + + if (low == high) + cil_printf("(ibpkeycon %s %i ", subnet_prefix_str, low); + else + cil_printf("(ibpkeycon %s (%i %i) ", subnet_prefix_str, low, + high); + + context_to_cil(pdb, &ibpkeycon->context[0]); + + cil_printf(")\n"); + } + return 0; +exit: + return rc; +} + static int ocontext_selinux_netif_to_cil(struct policydb *pdb, struct ocontext *netifs) { struct ocontext *netif; @@ -2642,6 +2801,19 @@ exit: return rc; } +static int ocontext_selinux_ibendport_to_cil(struct policydb *pdb, struct ocontext *ibendports) +{ + struct ocontext *ibendport; + + for (ibendport = ibendports; ibendport; ibendport = ibendport->next) { + cil_printf("(ibendportcon %s %u ", ibendport->u.ibendport.dev_name, ibendport->u.ibendport.port); + context_to_cil(pdb, &ibendport->context[0]); + + cil_printf(")\n"); + } + + return 0; +} static int ocontext_selinux_fsuse_to_cil(struct policydb *pdb, struct ocontext *fsuses) { @@ -2795,6 +2967,8 @@ static int ocontexts_to_cil(struct policydb *pdb) ocontext_selinux_node_to_cil, ocontext_selinux_fsuse_to_cil, ocontext_selinux_node6_to_cil, + ocontext_selinux_ibpkey_to_cil, + ocontext_selinux_ibendport_to_cil, }; static int (*ocon_xen_funcs[OCON_NUM])(struct policydb *pdb, struct ocontext *ocon) = { ocontext_xen_isid_to_cil, @@ -3470,7 +3644,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 +3793,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 +3861,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 +++ libsepol-2.5/src/node_record.c @@ -70,7 +70,7 @@ static int node_parse_addr(sepol_handle_t * handle, return STATUS_ERR; } -#ifdef DARWIN +#ifdef __APPLE__ memcpy(addr_bytes, in_addr.s6_addr, 16); #else memcpy(addr_bytes, in_addr.s6_addr32, 16); @@ -162,7 +162,7 @@ static int node_expand_addr(sepol_handle_t * handle, { struct in6_addr addr; memset(&addr, 0, sizeof(struct in6_addr)); -#ifdef DARWIN +#ifdef __APPLE__ memcpy(&addr.s6_addr[0], addr_bytes, 16); #else memcpy(&addr.s6_addr32[0], addr_bytes, 16); diff --git libsepol-2.5/src/nodes.c libsepol-2.5/src/nodes.c index 50cf21d..820346d 100644 --- libsepol-2.5/src/nodes.c +++ libsepol-2.5/src/nodes.c @@ -273,6 +273,7 @@ int sepol_node_query(sepol_handle_t * handle, c, SEPOL_PROTO_IP6, response) < 0) goto err; + return STATUS_SUCCESS; } } break; diff --git libsepol-2.5/src/polcaps.c libsepol-2.5/src/polcaps.c index 43a71a7..0c6f2af 100644 --- libsepol-2.5/src/polcaps.c +++ libsepol-2.5/src/polcaps.c @@ -10,6 +10,8 @@ static const char *polcap_names[] = { "open_perms", /* POLICYDB_CAPABILITY_OPENPERM */ "redhat1", /* POLICYDB_CAPABILITY_REDHAT1, aka ptrace_child */ "always_check_network", /* POLICYDB_CAPABILITY_ALWAYSNETWORK */ + "cgroup_seclabel", /* POLICYDB_CAPABILITY_SECLABEL */ + "nnp_nosuid_transition", /* POLICYDB_CAPABILITY_NNP_NOSUID_TRANSITION */ NULL }; diff --git libsepol-2.5/src/policydb.c libsepol-2.5/src/policydb.c index 6a80f94..98fb9c8 100644 --- libsepol-2.5/src/policydb.c +++ libsepol-2.5/src/policydb.c @@ -18,6 +18,7 @@ * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * Copyright (C) 2003 - 2005 Tresys Technology, LLC * Copyright (C) 2003 - 2007 Red Hat, Inc. + * Copyright (C) 2017 Mellanox Technologies Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -186,6 +187,13 @@ static struct policydb_compat_info policydb_compat[] = { .target_platform = SEPOL_TARGET_SELINUX, }, { + .type = POLICY_KERN, + .version = POLICYDB_VERSION_INFINIBAND, + .sym_num = SYM_NUM, + .ocon_num = OCON_IBENDPORT + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { .type = POLICY_BASE, .version = MOD_POLICYDB_VERSION_BASE, .sym_num = SYM_NUM, @@ -284,6 +292,20 @@ static struct policydb_compat_info policydb_compat[] = { .target_platform = SEPOL_TARGET_SELINUX, }, { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_XPERMS_IOCTL, + .sym_num = SYM_NUM, + .ocon_num = OCON_NODE6 + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_BASE, + .version = MOD_POLICYDB_VERSION_INFINIBAND, + .sym_num = SYM_NUM, + .ocon_num = OCON_IBENDPORT + 1, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { .type = POLICY_MOD, .version = MOD_POLICYDB_VERSION_BASE, .sym_num = SYM_NUM, @@ -381,6 +403,20 @@ static struct policydb_compat_info policydb_compat[] = { .ocon_num = 0, .target_platform = SEPOL_TARGET_SELINUX, }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_XPERMS_IOCTL, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, + { + .type = POLICY_MOD, + .version = MOD_POLICYDB_VERSION_INFINIBAND, + .sym_num = SYM_NUM, + .ocon_num = 0, + .target_platform = SEPOL_TARGET_SELINUX, + }, }; #if 0 @@ -557,6 +593,8 @@ void avrule_destroy(avrule_t * x) next = cur->next; free(cur); } + + free(x->xperms); } void role_trans_rule_init(role_trans_rule_t * x) @@ -1068,7 +1106,7 @@ 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; @@ -2618,6 +2656,8 @@ static int ocontext_read_selinux(struct policydb_compat_info *info, if (rc < 0) return -1; len = le32_to_cpu(buf[0]); + if (len > 63) + return -1; c->u.name = malloc(len + 1); if (!c->u.name) return -1; @@ -2632,6 +2672,41 @@ static int ocontext_read_selinux(struct policydb_compat_info *info, (&c->context[1], p, fp)) return -1; break; + case OCON_IBPKEY: + rc = next_entry(buf, fp, sizeof(uint32_t) * 4); + if (rc < 0 || buf[2] > 0xffff || buf[3] > 0xffff) + return -1; + + memcpy(&c->u.ibpkey.subnet_prefix, buf, + sizeof(c->u.ibpkey.subnet_prefix)); + + c->u.ibpkey.low_pkey = le32_to_cpu(buf[2]); + c->u.ibpkey.high_pkey = le32_to_cpu(buf[3]); + + if (context_read_and_validate + (&c->context[0], p, fp)) + return -1; + break; + case OCON_IBENDPORT: + rc = next_entry(buf, fp, sizeof(uint32_t) * 2); + if (rc < 0) + return -1; + len = le32_to_cpu(buf[0]); + if (len == 0 || len > IB_DEVICE_NAME_MAX - 1) + return -1; + + c->u.ibendport.dev_name = malloc(len + 1); + if (!c->u.ibendport.dev_name) + return -1; + rc = next_entry(c->u.ibendport.dev_name, fp, len); + if (rc < 0) + return -1; + c->u.ibendport.dev_name[len] = 0; + c->u.ibendport.port = le32_to_cpu(buf[1]); + if (context_read_and_validate + (&c->context[0], p, fp)) + return -1; + break; case OCON_PORT: rc = next_entry(buf, fp, sizeof(uint32_t) * 3); if (rc < 0) @@ -3029,8 +3104,7 @@ common_read, class_read, role_read, type_read, user_read, /************** module reading functions below **************/ -static avrule_t *avrule_read(policydb_t * p - __attribute__ ((unused)), struct policy_file *fp) +static avrule_t *avrule_read(policydb_t * p, struct policy_file *fp) { unsigned int i; uint32_t buf[2], len; @@ -3048,8 +3122,8 @@ static avrule_t *avrule_read(policydb_t * p if (rc < 0) goto bad; - (avrule)->specified = le32_to_cpu(buf[0]); - (avrule)->flags = le32_to_cpu(buf[1]); + avrule->specified = le32_to_cpu(buf[0]); + avrule->flags = le32_to_cpu(buf[1]); if (type_set_read(&avrule->stypes, fp)) goto bad; @@ -3085,6 +3159,52 @@ static avrule_t *avrule_read(policydb_t * p tail = cur; } + if (avrule->specified & AVRULE_XPERMS) { + uint8_t buf8; + size_t nel = ARRAY_SIZE(avrule->xperms->perms); + uint32_t buf32[nel]; + + if (p->policyvers < MOD_POLICYDB_VERSION_XPERMS_IOCTL) { + ERR(fp->handle, + "module policy version %u does not support ioctl" + " extended permissions rules and one was specified", + p->policyvers); + goto bad; + } + + if (p->target_platform != SEPOL_TARGET_SELINUX) { + ERR(fp->handle, + "Target platform %s does not support ioctl" + " extended permissions rules and one was specified", + policydb_target_strings[p->target_platform]); + goto bad; + } + + avrule->xperms = calloc(1, sizeof(*avrule->xperms)); + if (!avrule->xperms) + goto bad; + + rc = next_entry(&buf8, fp, sizeof(uint8_t)); + if (rc < 0) { + ERR(fp->handle, "truncated entry"); + goto bad; + } + avrule->xperms->specified = buf8; + rc = next_entry(&buf8, fp, sizeof(uint8_t)); + if (rc < 0) { + ERR(fp->handle, "truncated entry"); + goto bad; + } + avrule->xperms->driver = buf8; + rc = next_entry(buf32, fp, sizeof(uint32_t)*nel); + if (rc < 0) { + ERR(fp->handle, "truncated entry"); + goto bad; + } + for (i = 0; i < nel; i++) + avrule->xperms->perms[i] = le32_to_cpu(buf32[i]); + } + return avrule; bad: if (avrule) { 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 +++ libsepol-2.5/src/port_record.c @@ -184,6 +184,8 @@ const char *sepol_port_get_proto_str(int proto) return "udp"; case SEPOL_PROTO_TCP: return "tcp"; + case SEPOL_PROTO_DCCP: + return "dccp"; default: return "???"; } diff --git libsepol-2.5/src/ports.c libsepol-2.5/src/ports.c index 607a629..62ec602 100644 --- libsepol-2.5/src/ports.c +++ libsepol-2.5/src/ports.c @@ -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; + case SEPOL_PROTO_DCCP: + return IPPROTO_DCCP; default: ERR(handle, "unsupported protocol %u", proto); return STATUS_ERR; @@ -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; + case IPPROTO_DCCP: + return SEPOL_PROTO_DCCP; default: 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 --- libsepol-2.5/src/private.h +++ libsepol-2.5/src/private.h @@ -5,7 +5,7 @@ #include -#ifdef DARWIN +#ifdef __APPLE__ #include #include #else @@ -16,7 +16,7 @@ #include #include -#ifdef DARWIN +#ifdef __APPLE__ #define __BYTE_ORDER BYTE_ORDER #define __LITTLE_ENDIAN LITTLE_ENDIAN #endif diff --git libsepol-2.5/src/services.c libsepol-2.5/src/services.c index d64a8e8..ea8453b 100644 --- libsepol-2.5/src/services.c +++ libsepol-2.5/src/services.c @@ -21,6 +21,7 @@ * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * Copyright (C) 2003 - 2004 Tresys Technology, LLC * Copyright (C) 2003 - 2004 Red Hat, Inc. + * Copyright (C) 2017 Mellanox Technologies Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -1152,20 +1153,16 @@ int hidden sepol_compute_av(sepol_security_id_t ssid, int hidden sepol_string_to_security_class(const char *class_name, sepol_security_class_t *tclass) { - char *class = NULL; - sepol_security_class_t id; - - for (id = 1;; id++) { - class = policydb->p_class_val_to_name[id - 1]; - if (class == NULL) { - ERR(NULL, "could not convert %s to class id", class_name); - return STATUS_ERR; - } - if ((strcmp(class, class_name)) == 0) { - *tclass = id; - return STATUS_SUCCESS; - } + class_datum_t *tclass_datum; + + tclass_datum = hashtab_search(policydb->p_classes.table, + (hashtab_key_t) class_name); + if (!tclass_datum) { + ERR(NULL, "unrecognized class %s", class_name); + return STATUS_ERR; } + *tclass = tclass_datum->s.value; + return STATUS_SUCCESS; } /* @@ -1811,6 +1808,79 @@ int hidden sepol_fs_sid(char *name, } /* + * Return the SID of the ibpkey specified by + * `subnet prefix', and `pkey number'. + */ +int hidden sepol_ibpkey_sid(uint64_t subnet_prefix, + uint16_t pkey, sepol_security_id_t *out_sid) +{ + ocontext_t *c; + int rc = 0; + + c = policydb->ocontexts[OCON_IBPKEY]; + while (c) { + if (c->u.ibpkey.low_pkey <= pkey && + c->u.ibpkey.high_pkey >= pkey && + subnet_prefix == c->u.ibpkey.subnet_prefix) + break; + c = c->next; + } + + if (c) { + if (!c->sid[0]) { + rc = sepol_sidtab_context_to_sid(sidtab, + &c->context[0], + &c->sid[0]); + if (rc) + goto out; + } + *out_sid = c->sid[0]; + } else { + *out_sid = SECINITSID_UNLABELED; + } + +out: + return rc; +} + +/* + * Return the SID of the subnet management interface specified by + * `device name', and `port'. + */ +int hidden sepol_ibendport_sid(char *dev_name, + uint8_t port, + sepol_security_id_t *out_sid) +{ + ocontext_t *c; + int rc = 0; + + c = policydb->ocontexts[OCON_IBENDPORT]; + while (c) { + if (c->u.ibendport.port == port && + !strcmp(dev_name, c->u.ibendport.dev_name)) + break; + c = c->next; + } + + if (c) { + if (!c->sid[0]) { + rc = sepol_sidtab_context_to_sid(sidtab, + &c->context[0], + &c->sid[0]); + if (rc) + goto out; + } + *out_sid = c->sid[0]; + } else { + *out_sid = SECINITSID_UNLABELED; + } + +out: + return rc; +} + + +/* * Return the SID of the port specified by * `domain', `type', `protocol', and `port'. */ diff --git libsepol-2.5/src/write.c libsepol-2.5/src/write.c index d87ea61..620baa9 100644 --- libsepol-2.5/src/write.c +++ libsepol-2.5/src/write.c @@ -16,6 +16,7 @@ * * Copyright (C) 2004-2005 Trusted Computer Solutions, Inc. * Copyright (C) 2003-2005 Tresys Technology, LLC + * Copyright (C) 2017 Mellanox Technologies Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -50,7 +51,8 @@ struct policy_data { struct policydb *p; }; -static int avrule_write_list(avrule_t * avrules, struct policy_file *fp); +static int avrule_write_list(policydb_t *p, + avrule_t * avrules, struct policy_file *fp); static int ebitmap_write(ebitmap_t * e, struct policy_file *fp) { @@ -764,9 +766,9 @@ static int cond_write_node(policydb_t * p, if (cond_write_av_list(p, node->false_list, fp) != 0) return POLICYDB_ERROR; } else { - if (avrule_write_list(node->avtrue_list, fp)) + if (avrule_write_list(p, node->avtrue_list, fp)) return POLICYDB_ERROR; - if (avrule_write_list(node->avfalse_list, fp)) + if (avrule_write_list(p, node->avfalse_list, fp)) return POLICYDB_ERROR; } @@ -1379,6 +1381,35 @@ static int ocontext_write_selinux(struct policydb_compat_info *info, if (context_write(p, &c->context[1], fp)) return POLICYDB_ERROR; break; + case OCON_IBPKEY: + /* The subnet prefix is in network order */ + memcpy(buf, &c->u.ibpkey.subnet_prefix, + sizeof(c->u.ibpkey.subnet_prefix)); + + buf[2] = cpu_to_le32(c->u.ibpkey.low_pkey); + buf[3] = cpu_to_le32(c->u.ibpkey.high_pkey); + + items = put_entry(buf, sizeof(uint32_t), 4, fp); + if (items != 4) + return POLICYDB_ERROR; + + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + break; + case OCON_IBENDPORT: + len = strlen(c->u.ibendport.dev_name); + buf[0] = cpu_to_le32(len); + buf[1] = cpu_to_le32(c->u.ibendport.port); + items = put_entry(buf, sizeof(uint32_t), 2, fp); + if (items != 2) + return POLICYDB_ERROR; + items = put_entry(c->u.ibendport.dev_name, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + break; case OCON_PORT: buf[0] = c->u.port.protocol; buf[1] = c->u.port.low_port; @@ -1544,18 +1575,13 @@ static int range_write(policydb_t * p, struct policy_file *fp) /************** module writing functions below **************/ -static int avrule_write(avrule_t * avrule, struct policy_file *fp) +static int avrule_write(policydb_t *p, avrule_t * avrule, + struct policy_file *fp) { size_t items, items2; uint32_t buf[32], len; class_perm_node_t *cur; - if (avrule->specified & AVRULE_XPERMS) { - ERR(fp->handle, "module policy does not support extended" - " permissions rules and one was specified"); - return POLICYDB_ERROR; - } - items = 0; buf[items++] = cpu_to_le32(avrule->specified); buf[items++] = cpu_to_le32(avrule->flags); @@ -1592,10 +1618,48 @@ static int avrule_write(avrule_t * avrule, struct policy_file *fp) cur = cur->next; } + if (avrule->specified & AVRULE_XPERMS) { + size_t nel = ARRAY_SIZE(avrule->xperms->perms); + uint32_t buf32[nel]; + uint8_t buf8; + unsigned int i; + + if (p->policyvers < MOD_POLICYDB_VERSION_XPERMS_IOCTL) { + ERR(fp->handle, + "module policy version %u does not support ioctl" + " extended permissions rules and one was specified", + p->policyvers); + return POLICYDB_ERROR; + } + + if (p->target_platform != SEPOL_TARGET_SELINUX) { + ERR(fp->handle, + "Target platform %s does not support ioctl" + " extended permissions rules and one was specified", + policydb_target_strings[p->target_platform]); + return POLICYDB_ERROR; + } + + buf8 = avrule->xperms->specified; + items = put_entry(&buf8, sizeof(uint8_t),1,fp); + if (items != 1) + return POLICYDB_ERROR; + buf8 = avrule->xperms->driver; + items = put_entry(&buf8, sizeof(uint8_t),1,fp); + if (items != 1) + return POLICYDB_ERROR; + for (i = 0; i < nel; i++) + buf32[i] = cpu_to_le32(avrule->xperms->perms[i]); + items = put_entry(buf32, sizeof(uint32_t), nel, fp); + if (items != nel) + return POLICYDB_ERROR; + } + return POLICYDB_SUCCESS; } -static int avrule_write_list(avrule_t * avrules, struct policy_file *fp) +static int avrule_write_list(policydb_t *p, avrule_t * avrules, + struct policy_file *fp) { uint32_t buf[32], len; avrule_t *avrule; @@ -1613,7 +1677,7 @@ static int avrule_write_list(avrule_t * avrules, struct policy_file *fp) avrule = avrules; while (avrule) { - if (avrule_write(avrule, fp)) + if (avrule_write(p, avrule, fp)) return POLICYDB_ERROR; avrule = avrule->next; } @@ -1801,7 +1865,7 @@ static int avrule_decl_write(avrule_decl_t * decl, int num_scope_syms, return POLICYDB_ERROR; } if (cond_write_list(p, decl->cond_list, fp) == -1 || - avrule_write_list(decl->avrules, fp) == -1 || + avrule_write_list(p, decl->avrules, fp) == -1 || role_trans_rule_write(p, decl->role_tr_rules, fp) == -1 || role_allow_rule_write(decl->role_allow_rules, fp) == -1) { return POLICYDB_ERROR; diff --git libsepol-2.5/tests/.gitignore libsepol-2.5/tests/.gitignore new file mode 100644 index 0000000..c3f60fd --- /dev/null +++ libsepol-2.5/tests/.gitignore @@ -0,0 +1 @@ +libsepol-tests diff --git libsepol-2.5/tests/policies/.gitignore libsepol-2.5/tests/policies/.gitignore new file mode 100644 index 0000000..5a547a8 --- /dev/null +++ libsepol-2.5/tests/policies/.gitignore @@ -0,0 +1,3 @@ +test-downgrade/ +test-*/*.mls +test-*/*.std