From ef525bcd608da877daed47cbb7511fcec71eb6b2 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Apr 10 2018 05:25:20 +0000 Subject: import libsepol-2.5-8.1.el7 --- diff --git a/SOURCES/libsepol-rhel.patch b/SOURCES/libsepol-rhel.patch index 0efef6b..4e5b8fa 100644 --- a/SOURCES/libsepol-rhel.patch +++ b/SOURCES/libsepol-rhel.patch @@ -44,7 +44,7 @@ index ace3d54..c7cc464 100644 * 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..929ab19 100644 +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) @@ -55,7 +55,16 @@ index afdc240..929ab19 100644 CIL_KEY_AUDITALLOW = cil_strpool_add("auditallow"); CIL_KEY_TUNABLEIF = cil_strpool_add("tunableif"); CIL_KEY_ALLOW = cil_strpool_add("allow"); -@@ -232,6 +233,9 @@ static void cil_init_keys(void) +@@ -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"); @@ -65,7 +74,41 @@ index afdc240..929ab19 100644 } void cil_db_init(struct cil_db **db) -@@ -756,6 +760,9 @@ void cil_destroy_data(void **data, enum cil_flavor flavor) +@@ -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; @@ -75,7 +118,7 @@ index afdc240..929ab19 100644 case CIL_OP: case CIL_CONS_OPERAND: break; -@@ -763,8 +770,8 @@ void cil_destroy_data(void **data, enum cil_flavor flavor) +@@ -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; } @@ -86,7 +129,18 @@ index afdc240..929ab19 100644 } int cil_flavor_to_symtab_index(enum cil_flavor flavor, enum cil_sym_index *sym_index) -@@ -1108,6 +1115,8 @@ const char * cil_node_to_string(struct cil_tree_node *node) +@@ -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; @@ -95,7 +149,7 @@ index afdc240..929ab19 100644 case CIL_ALL: return CIL_KEY_ALL; case CIL_RANGE: -@@ -1755,8 +1764,7 @@ int cil_get_symtab(struct cil_tree_node *ast_node, symtab_t **symtab, enum cil_s +@@ -1755,8 +1780,7 @@ int cil_get_symtab(struct cil_tree_node *ast_node, symtab_t **symtab, enum cil_s return SEPOL_OK; exit: @@ -105,7 +159,42 @@ index afdc240..929ab19 100644 return SEPOL_ERR; } -@@ -2553,3 +2561,10 @@ void cil_mls_init(struct cil_mls **mls) +@@ -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; } @@ -117,7 +206,7 @@ index afdc240..929ab19 100644 + (*info)->path = NULL; +} diff --git libsepol-2.5/cil/src/cil_binary.c libsepol-2.5/cil/src/cil_binary.c -index f749e53..46fea4b 100644 +index f749e53..c507124 100644 --- libsepol-2.5/cil/src/cil_binary.c +++ libsepol-2.5/cil/src/cil_binary.c @@ -31,6 +31,9 @@ @@ -237,7 +326,48 @@ index f749e53..46fea4b 100644 goto exit; } } -@@ -3035,6 +3043,9 @@ int cil_portcon_to_policydb(policydb_t *pdb, struct cil_sort *portcons) +@@ -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; @@ -247,7 +377,38 @@ index f749e53..46fea4b 100644 default: /* should not get here */ rc = SEPOL_ERR; -@@ -3583,7 +3594,7 @@ int __cil_node_to_policydb(struct cil_tree_node *node, void *extra_args) +@@ -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) { @@ -256,7 +417,24 @@ index f749e53..46fea4b 100644 } return rc; } -@@ -4227,6 +4238,9 @@ exit: +@@ -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; @@ -266,7 +444,7 @@ index f749e53..46fea4b 100644 avrule = cil_malloc(sizeof(avrule_t)); avrule->specified = kind; -@@ -4235,8 +4249,17 @@ static avrule_t *__cil_init_sepol_avrule(uint32_t kind, struct cil_tree_node *no +@@ -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; @@ -285,7 +463,7 @@ index f749e53..46fea4b 100644 avrule->next = NULL; return avrule; } -@@ -4263,10 +4286,8 @@ static void __cil_print_parents(const char *pad, struct cil_tree_node *n) +@@ -4263,10 +4354,8 @@ static void __cil_print_parents(const char *pad, struct cil_tree_node *n) __cil_print_parents(pad, n->parent); @@ -298,7 +476,7 @@ index f749e53..46fea4b 100644 } } -@@ -4357,7 +4378,7 @@ static int __cil_print_neverallow_failure(const struct cil_db *db, struct cil_tr +@@ -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; } @@ -307,7 +485,7 @@ index f749e53..46fea4b 100644 __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 +4401,9 @@ exit: +@@ -4380,10 +4469,9 @@ exit: return rc; } @@ -320,7 +498,7 @@ index f749e53..46fea4b 100644 struct cil_avrule *cil_rule = node->data; struct cil_symtab_datum *tgt = cil_rule->tgt; uint32_t kind; -@@ -4422,11 +4442,11 @@ static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct +@@ -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) { @@ -333,7 +511,7 @@ index f749e53..46fea4b 100644 } } else { -@@ -4444,12 +4464,11 @@ static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct +@@ -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) { @@ -347,7 +525,7 @@ index f749e53..46fea4b 100644 } } } -@@ -4466,34 +4485,23 @@ exit: +@@ -4466,34 +4553,23 @@ exit: rule->xperms = NULL; __cil_destroy_sepol_avrules(rule); @@ -387,7 +565,7 @@ index f749e53..46fea4b 100644 } 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 +4556,7 @@ exit: +@@ -4548,7 +4624,7 @@ exit: return rc; } @@ -396,7 +574,7 @@ index f749e53..46fea4b 100644 { int rc = SEPOL_OK; int i; -@@ -4574,6 +4582,9 @@ static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void +@@ -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; @@ -406,7 +584,7 @@ index f749e53..46fea4b 100644 target.is_extended = 0; target.rule_kind = CIL_AVRULE_ALLOWED; -@@ -4585,7 +4596,6 @@ static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void +@@ -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; @@ -414,7 +592,7 @@ index f749e53..46fea4b 100644 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 +4604,7 @@ static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void +@@ -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); @@ -423,7 +601,7 @@ index f749e53..46fea4b 100644 if (rc) { cil_log(CIL_ERR, "Error occurred while checking type bounds\n"); cil_list_destroy(&matching, CIL_FALSE); -@@ -4602,14 +4612,17 @@ static int cil_check_type_bounds(const struct cil_db *db, policydb_t *pdb, void +@@ -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; } @@ -447,7 +625,7 @@ index f749e53..46fea4b 100644 cil_list_destroy(&matching, CIL_FALSE); cil_list_destroy(&target.perms.classperms, CIL_TRUE); } -@@ -4753,20 +4766,32 @@ int cil_binary_create_allocated_pdb(const struct cil_db *db, sepol_policydb_t *p +@@ -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) { @@ -484,8 +662,43 @@ index f749e53..46fea4b 100644 } 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..1505873 100644 +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 @@ -1116,7 +1329,97 @@ index 1135e06..1505873 100644 cil_destroy_filecon(filecon); return rc; } -@@ -4261,6 +4199,8 @@ int cil_gen_portcon(struct cil_db *db, struct cil_tree_node *parse_current, stru +@@ -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; @@ -1125,7 +1428,7 @@ index 1135e06..1505873 100644 } else { cil_log(CIL_ERR, "Invalid protocol\n"); rc = SEPOL_ERR; -@@ -4311,8 +4251,7 @@ int cil_gen_portcon(struct cil_db *db, struct cil_tree_node *parse_current, stru +@@ -4311,8 +4334,7 @@ int cil_gen_portcon(struct cil_db *db, struct cil_tree_node *parse_current, stru return SEPOL_OK; exit: @@ -1135,7 +1438,7 @@ index 1135e06..1505873 100644 cil_destroy_portcon(portcon); return rc; } -@@ -4393,8 +4332,7 @@ int cil_gen_nodecon(struct cil_db *db, struct cil_tree_node *parse_current, stru +@@ -4393,8 +4415,7 @@ int cil_gen_nodecon(struct cil_db *db, struct cil_tree_node *parse_current, stru return SEPOL_OK; exit: @@ -1145,7 +1448,7 @@ index 1135e06..1505873 100644 cil_destroy_nodecon(nodecon); return rc; } -@@ -4464,8 +4402,7 @@ int cil_gen_genfscon(struct cil_db *db, struct cil_tree_node *parse_current, str +@@ -4464,8 +4485,7 @@ int cil_gen_genfscon(struct cil_db *db, struct cil_tree_node *parse_current, str return SEPOL_OK; exit: @@ -1155,7 +1458,7 @@ index 1135e06..1505873 100644 cil_destroy_genfscon(genfscon); return SEPOL_ERR; } -@@ -4538,8 +4475,7 @@ int cil_gen_netifcon(struct cil_db *db, struct cil_tree_node *parse_current, str +@@ -4538,8 +4558,7 @@ int cil_gen_netifcon(struct cil_db *db, struct cil_tree_node *parse_current, str return SEPOL_OK; exit: @@ -1165,7 +1468,76 @@ index 1135e06..1505873 100644 cil_destroy_netifcon(netifcon); return SEPOL_ERR; } -@@ -4606,8 +4542,7 @@ int cil_gen_pirqcon(struct cil_db *db, struct cil_tree_node *parse_current, stru +@@ -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: @@ -1175,7 +1547,7 @@ index 1135e06..1505873 100644 cil_destroy_pirqcon(pirqcon); return rc; } -@@ -4692,8 +4627,7 @@ int cil_gen_iomemcon(struct cil_db *db, struct cil_tree_node *parse_current, str +@@ -4692,8 +4772,7 @@ int cil_gen_iomemcon(struct cil_db *db, struct cil_tree_node *parse_current, str return SEPOL_OK; exit: @@ -1185,7 +1557,7 @@ index 1135e06..1505873 100644 cil_destroy_iomemcon(iomemcon); return rc; } -@@ -4778,8 +4712,7 @@ int cil_gen_ioportcon(struct cil_db *db, struct cil_tree_node *parse_current, st +@@ -4778,8 +4857,7 @@ int cil_gen_ioportcon(struct cil_db *db, struct cil_tree_node *parse_current, st return SEPOL_OK; exit: @@ -1195,7 +1567,7 @@ index 1135e06..1505873 100644 cil_destroy_ioportcon(ioportcon); return rc; } -@@ -4842,8 +4775,7 @@ int cil_gen_pcidevicecon(struct cil_db *db, struct cil_tree_node *parse_current, +@@ -4842,8 +4920,7 @@ int cil_gen_pcidevicecon(struct cil_db *db, struct cil_tree_node *parse_current, return SEPOL_OK; exit: @@ -1205,7 +1577,7 @@ index 1135e06..1505873 100644 cil_destroy_pcidevicecon(pcidevicecon); return rc; } -@@ -4903,8 +4835,7 @@ int cil_gen_devicetreecon(struct cil_db *db, struct cil_tree_node *parse_current +@@ -4903,8 +4980,7 @@ int cil_gen_devicetreecon(struct cil_db *db, struct cil_tree_node *parse_current return SEPOL_OK; exit: @@ -1215,7 +1587,7 @@ index 1135e06..1505873 100644 cil_destroy_devicetreecon(devicetreecon); return rc; } -@@ -4979,8 +4910,7 @@ int cil_gen_fsuse(struct cil_db *db, struct cil_tree_node *parse_current, struct +@@ -4979,8 +5055,7 @@ int cil_gen_fsuse(struct cil_db *db, struct cil_tree_node *parse_current, struct return SEPOL_OK; exit: @@ -1225,7 +1597,7 @@ index 1135e06..1505873 100644 cil_destroy_fsuse(fsuse); return SEPOL_ERR; } -@@ -5137,8 +5067,7 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct +@@ -5137,8 +5212,7 @@ int cil_gen_macro(struct cil_db *db, struct cil_tree_node *parse_current, struct return SEPOL_OK; exit: @@ -1235,7 +1607,7 @@ index 1135e06..1505873 100644 cil_destroy_macro(macro); cil_clear_node(ast_node); return SEPOL_ERR; -@@ -5196,8 +5125,7 @@ int cil_gen_call(struct cil_db *db, struct cil_tree_node *parse_current, struct +@@ -5196,8 +5270,7 @@ int cil_gen_call(struct cil_db *db, struct cil_tree_node *parse_current, struct return SEPOL_OK; exit: @@ -1245,7 +1617,7 @@ index 1135e06..1505873 100644 cil_destroy_call(call); return rc; } -@@ -5299,8 +5227,7 @@ int cil_gen_optional(struct cil_db *db, struct cil_tree_node *parse_current, str +@@ -5299,8 +5372,7 @@ int cil_gen_optional(struct cil_db *db, struct cil_tree_node *parse_current, str return SEPOL_OK; exit: @@ -1255,7 +1627,7 @@ index 1135e06..1505873 100644 cil_destroy_optional(optional); cil_clear_node(ast_node); return rc; -@@ -5348,8 +5275,7 @@ int cil_gen_policycap(struct cil_db *db, struct cil_tree_node *parse_current, st +@@ -5348,8 +5420,7 @@ int cil_gen_policycap(struct cil_db *db, struct cil_tree_node *parse_current, st return SEPOL_OK; exit: @@ -1265,7 +1637,7 @@ index 1135e06..1505873 100644 cil_destroy_policycap(polcap); cil_clear_node(ast_node); return rc; -@@ -5404,8 +5330,7 @@ int cil_gen_ipaddr(struct cil_db *db, struct cil_tree_node *parse_current, struc +@@ -5404,8 +5475,7 @@ int cil_gen_ipaddr(struct cil_db *db, struct cil_tree_node *parse_current, struc return SEPOL_OK; exit: @@ -1275,7 +1647,7 @@ index 1135e06..1505873 100644 cil_destroy_ipaddr(ipaddr); cil_clear_node(ast_node); return rc; -@@ -5609,8 +5534,7 @@ int cil_gen_bounds(struct cil_db *db, struct cil_tree_node *parse_current, struc +@@ -5609,8 +5679,7 @@ int cil_gen_bounds(struct cil_db *db, struct cil_tree_node *parse_current, struc return SEPOL_OK; exit: @@ -1285,7 +1657,7 @@ index 1135e06..1505873 100644 cil_destroy_bounds(bounds); return rc; } -@@ -5671,8 +5595,7 @@ int cil_gen_default(struct cil_tree_node *parse_current, struct cil_tree_node *a +@@ -5671,8 +5740,7 @@ int cil_gen_default(struct cil_tree_node *parse_current, struct cil_tree_node *a return SEPOL_OK; exit: @@ -1295,7 +1667,7 @@ index 1135e06..1505873 100644 cil_destroy_default(def); return rc; } -@@ -5758,8 +5681,7 @@ int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_no +@@ -5758,8 +5826,7 @@ int cil_gen_defaultrange(struct cil_tree_node *parse_current, struct cil_tree_no return SEPOL_OK; exit: @@ -1305,7 +1677,7 @@ index 1135e06..1505873 100644 cil_destroy_defaultrange(def); return rc; } -@@ -5819,8 +5741,7 @@ int cil_gen_handleunknown(struct cil_tree_node *parse_current, struct cil_tree_n +@@ -5819,8 +5886,7 @@ int cil_gen_handleunknown(struct cil_tree_node *parse_current, struct cil_tree_n return SEPOL_OK; exit: @@ -1315,7 +1687,7 @@ index 1135e06..1505873 100644 cil_destroy_handleunknown(unknown); return rc; } -@@ -5868,8 +5789,7 @@ int cil_gen_mls(struct cil_tree_node *parse_current, struct cil_tree_node *ast_n +@@ -5868,8 +5934,7 @@ int cil_gen_mls(struct cil_tree_node *parse_current, struct cil_tree_node *ast_n return SEPOL_OK; exit: @@ -1325,7 +1697,7 @@ index 1135e06..1505873 100644 cil_destroy_mls(mls); return rc; } -@@ -5879,6 +5799,27 @@ void cil_destroy_mls(struct cil_mls *mls) +@@ -5879,6 +5944,27 @@ void cil_destroy_mls(struct cil_mls *mls) free(mls); } @@ -1353,7 +1725,7 @@ index 1135e06..1505873 100644 int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *finished, void *extra_args) { struct cil_args_build *args = NULL; -@@ -5913,7 +5854,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f +@@ -5913,7 +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 { @@ -1362,7 +1734,7 @@ index 1135e06..1505873 100644 } goto exit; } -@@ -5926,7 +5867,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f +@@ -5926,7 +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; @@ -1371,7 +1743,7 @@ index 1135e06..1505873 100644 goto exit; } } -@@ -5942,8 +5883,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f +@@ -5942,8 +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; @@ -1381,7 +1753,7 @@ index 1135e06..1505873 100644 if (((struct cil_booleanif*)boolif->data)->preserved_tunable) { cil_log(CIL_ERR, "%s cannot be defined within tunableif statement (treated as a booleanif due to preserve-tunables)\n", (char*)parse_current->data); -@@ -5958,8 +5898,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f +@@ -5958,8 +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; @@ -1391,7 +1763,7 @@ index 1135e06..1505873 100644 cil_log(CIL_ERR, "Tunables cannot be defined within tunableif statement\n"); goto exit; } -@@ -5968,8 +5907,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f +@@ -5968,8 +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; @@ -1401,7 +1773,7 @@ index 1135e06..1505873 100644 cil_log(CIL_ERR, "in-statements cannot be defined within in-statements\n"); goto exit; } -@@ -5979,7 +5917,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f +@@ -5979,7 +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; @@ -1410,7 +1782,20 @@ index 1135e06..1505873 100644 if (parse_current->data == CIL_KEY_BLOCK) { rc = cil_gen_block(db, parse_current, ast_node, 0); -@@ -6242,8 +6180,10 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f +@@ -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; @@ -1422,7 +1807,7 @@ index 1135e06..1505873 100644 rc = SEPOL_ERR; } -@@ -6264,7 +6204,7 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f +@@ -6264,7 +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; } @@ -1432,10 +1817,21 @@ index 1135e06..1505873 100644 } 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..825029e 100644 +index f428394..be76f6c 100644 --- libsepol-2.5/cil/src/cil_build_ast.h +++ libsepol-2.5/cil/src/cil_build_ast.h -@@ -215,6 +215,8 @@ int cil_gen_mls(struct cil_tree_node *parse_current, struct cil_tree_node *ast_n +@@ -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); @@ -1445,10 +1841,62 @@ index f428394..825029e 100644 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..5debd0d 100644 +index 0be1dda..0e87714 100644 --- libsepol-2.5/cil/src/cil_copy_ast.c +++ libsepol-2.5/cil/src/cil_copy_ast.c -@@ -1666,6 +1666,21 @@ int cil_copy_bounds(__attribute__((unused)) struct cil_db *db, void *data, void +@@ -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; } @@ -1470,7 +1918,20 @@ index 0be1dda..5debd0d 100644 int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) uint32_t *finished, void *extra_args) { int rc = SEPOL_ERR; -@@ -1942,6 +1957,9 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u +@@ -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; @@ -1480,7 +1941,7 @@ index 0be1dda..5debd0d 100644 default: goto exit; } -@@ -1964,7 +1982,7 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u +@@ -1964,7 +2033,7 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u new->parent = parent; new->line = orig->line; @@ -1489,7 +1950,7 @@ index 0be1dda..5debd0d 100644 new->flavor = orig->flavor; new->data = data; -@@ -1985,8 +2003,8 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u +@@ -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) { @@ -1500,6 +1961,18 @@ index 0be1dda..5debd0d 100644 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 @@ -1527,14 +2000,16 @@ index 75de886..4134242 100644 return rc; diff --git libsepol-2.5/cil/src/cil_flavor.h libsepol-2.5/cil/src/cil_flavor.h -index 9fb5083..cd08b97 100644 +index 9fb5083..04f4abd 100644 --- libsepol-2.5/cil/src/cil_flavor.h +++ libsepol-2.5/cil/src/cil_flavor.h -@@ -111,6 +111,7 @@ enum cil_flavor { +@@ -111,6 +111,9 @@ enum cil_flavor { CIL_DEFAULTRANGE, CIL_HANDLEUNKNOWN, CIL_MLS, + CIL_SRC_INFO, ++ CIL_IBPKEYCON, ++ CIL_IBENDPORTCON, /* * boolean constraint set catset @@ -1552,7 +2027,7 @@ index 865bd7d..dad1347 100644 return rc; diff --git libsepol-2.5/cil/src/cil_internal.h libsepol-2.5/cil/src/cil_internal.h -index a0a5480..5875dc9 100644 +index a0a5480..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; @@ -1563,7 +2038,16 @@ index a0a5480..5875dc9 100644 char *CIL_KEY_AUDITALLOW; char *CIL_KEY_TUNABLEIF; char *CIL_KEY_ALLOW; -@@ -225,6 +226,9 @@ char *CIL_KEY_NEVERALLOWX; +@@ -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; @@ -1573,17 +2057,47 @@ index a0a5480..5875dc9 100644 /* Symbol Table Array Indices -@@ -713,7 +717,8 @@ struct cil_filecon { +@@ -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 { -@@ -915,6 +920,11 @@ struct cil_mls { +@@ -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; }; @@ -1595,7 +2109,23 @@ index a0a5480..5875dc9 100644 void cil_db_init(struct cil_db **db); void cil_db_destroy(struct cil_db **db); -@@ -1017,6 +1027,7 @@ void cil_default_init(struct cil_default **def); +@@ -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); @@ -1988,7 +2518,7 @@ index d0e108c..101520c 100644 + return SEPOL_ERR; } diff --git libsepol-2.5/cil/src/cil_policy.c libsepol-2.5/cil/src/cil_policy.c -index 2c9b158..382129b 100644 +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) @@ -2000,56 +2530,372 @@ index 2c9b158..382129b 100644 } fprintf(file_arr[NETIFCONS], "%d ", portcon->port_low); fprintf(file_arr[NETIFCONS], "%d ", portcon->port_high); -diff --git libsepol-2.5/cil/src/cil_reset_ast.c libsepol-2.5/cil/src/cil_reset_ast.c -index 06146ca..de00679 100644 ---- libsepol-2.5/cil/src/cil_reset_ast.c -+++ 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; -diff --git libsepol-2.5/cil/src/cil_resolve_ast.c libsepol-2.5/cil/src/cil_resolve_ast.c -index 1489680..8348d57 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; +@@ -148,6 +150,39 @@ int cil_genfscon_to_policy(FILE **file_arr, struct cil_sort *sort) + return SEPOL_OK; + } - 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; ++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; + } -@@ -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"); - } ++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; -@@ -2252,12 +2252,10 @@ void cil_print_recursive_blockinherit(struct cil_tree_node *bi_node, struct cil_ +@@ -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; @@ -2064,7 +2910,7 @@ index 1489680..8348d57 100644 } } -@@ -2442,7 +2440,7 @@ int cil_resolve_in_list(void *extra_args) +@@ -2442,7 +2489,7 @@ int cil_resolve_in_list(void *extra_args) } if (unresolved > 0 && resolved == 0) { @@ -2073,7 +2919,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -2485,7 +2483,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil +@@ -2485,7 +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; @@ -2082,7 +2928,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -2498,7 +2496,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil +@@ -2498,7 +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; @@ -2091,7 +2937,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -2512,8 +2510,8 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil +@@ -2512,8 +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; @@ -2102,7 +2948,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -2542,7 +2540,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil +@@ -2542,7 +2589,7 @@ int cil_resolve_bounds(struct cil_tree_node *current, void *extra_args, enum cil return SEPOL_OK; exit: @@ -2111,7 +2957,7 @@ index 1489680..8348d57 100644 return rc; } -@@ -2617,12 +2615,10 @@ void cil_print_recursive_call(struct cil_tree_node *call_node, struct cil_tree_n +@@ -2617,12 +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; @@ -2126,7 +2972,7 @@ index 1489680..8348d57 100644 } } -@@ -2700,7 +2696,7 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args) +@@ -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) { @@ -2135,7 +2981,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -2713,7 +2709,7 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args) +@@ -2713,7 +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) { @@ -2144,7 +2990,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -2890,12 +2886,12 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args) +@@ -2890,12 +2935,12 @@ int cil_resolve_call1(struct cil_tree_node *current, void *extra_args) } if (pc != NULL) { @@ -2159,7 +3005,27 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -3593,7 +3589,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished +@@ -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*/ @@ -2168,7 +3034,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -3601,7 +3597,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished +@@ -3601,7 +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) { @@ -2177,7 +3043,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -3612,7 +3608,7 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished +@@ -3612,7 +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) { @@ -2186,7 +3052,7 @@ index 1489680..8348d57 100644 rc = SEPOL_ERR; goto exit; } -@@ -3626,9 +3622,9 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished +@@ -3626,9 +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) { @@ -2198,7 +3064,7 @@ index 1489680..8348d57 100644 } rc = SEPOL_ERR; goto exit; -@@ -3658,14 +3654,13 @@ int __cil_resolve_ast_node_helper(struct cil_tree_node *node, uint32_t *finished +@@ -3658,14 +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; @@ -2215,10 +3081,31 @@ index 1489680..8348d57 100644 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..9ff9d4b 100644 +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); } @@ -2350,7 +3237,28 @@ index 1c23efc..9ff9d4b 100644 return rc; } } -@@ -1319,6 +1405,8 @@ void cil_tree_print_node(struct cil_tree_node *node) +@@ -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"); @@ -2359,6 +3267,26 @@ index 1c23efc..9ff9d4b 100644 } 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 @@ -2380,7 +3308,7 @@ index 9bb602f..aeded56 100644 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..038f77a 100644 +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__(( @@ -2535,16 +3463,36 @@ index 36ec45a..038f77a 100644 } return rc; } -@@ -1007,7 +1002,7 @@ int __cil_verify_netifcon(struct cil_db *db, struct cil_tree_node *node) +@@ -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 +1023,7 @@ int __cil_verify_genfscon(struct cil_db *db, struct cil_tree_node *node) +@@ -1028,7 +1043,7 @@ int __cil_verify_genfscon(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: @@ -2553,7 +3501,7 @@ index 36ec45a..038f77a 100644 return rc; } -@@ -1047,8 +1042,7 @@ int __cil_verify_filecon(struct cil_db *db, struct cil_tree_node *node) +@@ -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) { @@ -2563,16 +3511,36 @@ index 36ec45a..038f77a 100644 goto exit; } } -@@ -1076,7 +1070,7 @@ int __cil_verify_nodecon(struct cil_db *db, struct cil_tree_node *node) +@@ -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 +1091,7 @@ int __cil_verify_portcon(struct cil_db *db, struct cil_tree_node *node) +@@ -1097,7 +1131,7 @@ int __cil_verify_portcon(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: @@ -2581,7 +3549,7 @@ index 36ec45a..038f77a 100644 return rc; } -@@ -1118,7 +1112,7 @@ int __cil_verify_pirqcon(struct cil_db *db, struct cil_tree_node *node) +@@ -1118,7 +1152,7 @@ int __cil_verify_pirqcon(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: @@ -2590,7 +3558,7 @@ index 36ec45a..038f77a 100644 return rc; } -@@ -1139,7 +1133,7 @@ int __cil_verify_iomemcon(struct cil_db *db, struct cil_tree_node *node) +@@ -1139,7 +1173,7 @@ int __cil_verify_iomemcon(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: @@ -2599,7 +3567,7 @@ index 36ec45a..038f77a 100644 return rc; } -@@ -1160,7 +1154,7 @@ int __cil_verify_ioportcon(struct cil_db *db, struct cil_tree_node *node) +@@ -1160,7 +1194,7 @@ int __cil_verify_ioportcon(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: @@ -2608,7 +3576,7 @@ index 36ec45a..038f77a 100644 return rc; } -@@ -1181,7 +1175,7 @@ int __cil_verify_pcidevicecon(struct cil_db *db, struct cil_tree_node *node) +@@ -1181,7 +1215,7 @@ int __cil_verify_pcidevicecon(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: @@ -2617,7 +3585,7 @@ index 36ec45a..038f77a 100644 return rc; } -@@ -1202,7 +1196,7 @@ int __cil_verify_devicetreecon(struct cil_db *db, struct cil_tree_node *node) +@@ -1202,7 +1236,7 @@ int __cil_verify_devicetreecon(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: @@ -2626,7 +3594,7 @@ index 36ec45a..038f77a 100644 return rc; } -@@ -1223,7 +1217,7 @@ int __cil_verify_fsuse(struct cil_db *db, struct cil_tree_node *node) +@@ -1223,7 +1257,7 @@ int __cil_verify_fsuse(struct cil_db *db, struct cil_tree_node *node) return SEPOL_OK; exit: @@ -2635,7 +3603,7 @@ index 36ec45a..038f77a 100644 return rc; } -@@ -1241,7 +1235,7 @@ int __cil_verify_permissionx(struct cil_permissionx *permx, struct cil_tree_node +@@ -1241,7 +1275,7 @@ int __cil_verify_permissionx(struct cil_permissionx *permx, struct cil_tree_node kind_str = CIL_KEY_IOCTL; break; default: @@ -2644,7 +3612,7 @@ index 36ec45a..038f77a 100644 rc = SEPOL_ERR; goto exit; } -@@ -1257,7 +1251,7 @@ int __cil_verify_permissionx(struct cil_permissionx *permx, struct cil_tree_node +@@ -1257,7 +1291,7 @@ int __cil_verify_permissionx(struct cil_permissionx *permx, struct cil_tree_node } if (rc == SEPOL_ENOENT) { @@ -2653,7 +3621,7 @@ index 36ec45a..038f77a 100644 rc = SEPOL_ERR; goto exit; } -@@ -1312,7 +1306,7 @@ int __cil_verify_class(struct cil_tree_node *node) +@@ -1312,7 +1346,7 @@ int __cil_verify_class(struct cil_tree_node *node) return SEPOL_OK; exit: @@ -2662,7 +3630,7 @@ index 36ec45a..038f77a 100644 return rc; } -@@ -1329,8 +1323,7 @@ int __cil_verify_policycap(struct cil_tree_node *node) +@@ -1329,8 +1363,7 @@ int __cil_verify_policycap(struct cil_tree_node *node) return SEPOL_OK; exit: @@ -2672,7 +3640,20 @@ index 36ec45a..038f77a 100644 return rc; } -@@ -1547,14 +1540,14 @@ static int __cil_verify_classpermission(struct cil_tree_node *node) +@@ -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) { @@ -2689,7 +3670,7 @@ index 36ec45a..038f77a 100644 goto exit; } -@@ -1577,14 +1570,14 @@ static int __verify_map_perm_classperms(__attribute__((unused)) hashtab_key_t k, +@@ -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) { @@ -2706,68 +3687,481 @@ index 36ec45a..038f77a 100644 map_args->rc = SEPOL_ERR; goto exit; } -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/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; +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; @@ -2997,11 +4391,53 @@ index fbf397f..a4be880 100644 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..0ad57f5 100644 +index 9cb7965..3fe6b56 100644 --- libsepol-2.5/src/expand.c +++ libsepol-2.5/src/expand.c -@@ -2497,6 +2497,7 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, +@@ -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; @@ -3009,7 +4445,7 @@ index 9cb7965..0ad57f5 100644 ebitmap_init(&types); ebitmap_init(t); -@@ -2505,17 +2506,25 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, +@@ -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)) { @@ -3037,7 +4473,7 @@ index 9cb7965..0ad57f5 100644 } } } -@@ -2523,7 +2532,7 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, +@@ -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)) @@ -3046,7 +4482,7 @@ index 9cb7965..0ad57f5 100644 } /* Now do the same thing for negset */ -@@ -2535,11 +2544,11 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, +@@ -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)) { @@ -3060,7 +4496,7 @@ index 9cb7965..0ad57f5 100644 } } } -@@ -2554,7 +2563,7 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, +@@ -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)) @@ -3069,7 +4505,7 @@ index 9cb7965..0ad57f5 100644 } goto out; } -@@ -2563,7 +2572,7 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, +@@ -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)) @@ -3078,7 +4514,7 @@ index 9cb7965..0ad57f5 100644 } if (set->flags & TYPE_COMP) { -@@ -2575,20 +2584,23 @@ int type_set_expand(type_set_t * set, ebitmap_t * t, policydb_t * p, +@@ -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)) @@ -3227,112 +4663,1630 @@ index 6f73195..778541a 100644 } } -diff --git libsepol-2.5/src/module_to_cil.c libsepol-2.5/src/module_to_cil.c -index 18ec6b9..36f3b7d 100644 ---- libsepol-2.5/src/module_to_cil.c -+++ libsepol-2.5/src/module_to_cil.c -@@ -26,6 +26,9 @@ - #include - #include - #include -+#ifndef IPPROTO_DCCP -+#define IPPROTO_DCCP 33 +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 - #include - #include - #include -@@ -1070,6 +1073,10 @@ static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *a - struct type_set *ts; - - for (avrule = avrule_list; avrule != NULL; avrule = avrule->next) { -+ if (avrule->specified == AVRULE_NEVERALLOW && avrule->source_filename) { -+ cil_println(0, ";;* lmx %lu %s\n",avrule->source_line, avrule->source_filename); -+ } +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 + - ts = &avrule->stypes; - rc = process_typeset(indent, pdb, ts, attr_list, &snames, &num_snames); - if (rc != 0) { -@@ -1100,6 +1107,10 @@ static int avrule_list_to_cil(int indent, struct policydb *pdb, struct avrule *a - - names_destroy(&snames, &num_snames); - names_destroy(&tnames, &num_tnames); ++#include "sepol/policydb/policydb.h" ++#include "ibendport_internal.h" ++#include "context_internal.h" ++#include "debug.h" + -+ if (avrule->specified == AVRULE_NEVERALLOW && avrule->source_filename) { -+ cil_println(0, ";;* lme\n"); -+ } - } - - return 0; -@@ -1292,7 +1303,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 +2548,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; -@@ -3470,7 +3482,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 +3631,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 +3699,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 ++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) @@ -3341,6 +6295,230 @@ index 50cf21d..820346d 100644 } } 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 @@ -3407,10 +6585,18 @@ index 8a6d4bb..9c700c9 100644 #define __LITTLE_ENDIAN LITTLE_ENDIAN #endif diff --git libsepol-2.5/src/services.c libsepol-2.5/src/services.c -index d64a8e8..d2b80b4 100644 +index d64a8e8..ea8453b 100644 --- libsepol-2.5/src/services.c +++ libsepol-2.5/src/services.c -@@ -1152,20 +1152,16 @@ int hidden sepol_compute_av(sepol_security_id_t ssid, +@@ -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) { @@ -3440,6 +6626,245 @@ index d64a8e8..d2b80b4 100644 } /* +@@ -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 diff --git a/SPECS/libsepol.spec b/SPECS/libsepol.spec index 403518d..b3ab8bf 100644 --- a/SPECS/libsepol.spec +++ b/SPECS/libsepol.spec @@ -1,11 +1,11 @@ Summary: SELinux binary policy manipulation library Name: libsepol Version: 2.5 -Release: 6%{?dist} +Release: 8.1%{?dist} License: LGPLv2+ Group: System Environment/Libraries Source: https://raw.githubusercontent.com/wiki/SELinuxProject/selinux/files/releases/20160223/libsepol-2.5.tar.gz -# HEAD e7ab0f8b86a3f6234f264d3bf98ccfb070ebaca7 +# HEAD f4aca6b867715e9f93537d116e6ff2268c3f3394 Patch1: libsepol-rhel.patch URL: https://github.com/SELinuxProject/selinux/wiki BuildRequires: flex @@ -104,6 +104,25 @@ exit 0 %{_libdir}/libsepol.so.1 %changelog +* Thu Oct 12 2017 Vit Mojzis - 2.5-8.1 +- Define nnp_nosuid_transition policy capability (rhbz#1480519) +- use IN6ADDR_ANY_INIT to initialize IPv6 addresses +- Allow runtime labeling of ibendports (rhbz#1464489) +- Allow runtime labeling of Infiniband Pkeys (rhbz#1464489) +- Add IB end port handling to CIL (rhbz#1464489) +- Add ibendport ocontext handling (rhbz#1464489) +- Add support for ibendportcon labels (rhbz#1464489) +- Add Infiniband Pkey handling to CIL (rhbz#1464489) +- Add ibpkey ocontext handling (rhbz#1464489) +- Add support for ibpkeycon labels (rhbz#1464489) +- Remove unused attribute on a used argument from avrule_read() (rhbz#1464489) +- Add binary module support for xperms +- Add support for converting extended permissions to CIL + +* Wed Sep 20 2017 Vit Mojzis - 2.5-7 +- Define cgroup_seclabel policy capability (rhbz#1493517) +- Fix unitialized jmp and invalid dereference + * Wed Aug 10 2016 Petr Lautrbach 2.5-6 - Fix memory leak in expand.c - Fix invalid read when policy file is corrupt