diff --git a/checkpolicy/policy_define.c b/checkpolicy/policy_define.c index 66c1ff25..de01f6f3 100644 --- a/checkpolicy/policy_define.c +++ b/checkpolicy/policy_define.c @@ -4116,6 +4116,61 @@ bad: return -1; } +int define_devicetree_context() +{ + ocontext_t *newc, *c, *l, *head; + + if (policydbp->target_platform != SEPOL_TARGET_XEN) { + yyerror("devicetreecon not supported for target"); + return -1; + } + + if (pass == 1) { + free(queue_remove(id_queue)); + parse_security_context(NULL); + return 0; + } + + newc = malloc(sizeof(ocontext_t)); + if (!newc) { + yyerror("out of memory"); + return -1; + } + memset(newc, 0, sizeof(ocontext_t)); + + newc->u.name = (char *)queue_remove(id_queue); + if (!newc->u.name) { + free(newc); + return -1; + } + + if (parse_security_context(&newc->context[0])) { + free(newc->u.name); + free(newc); + return -1; + } + + head = policydbp->ocontexts[OCON_XEN_DEVICETREE]; + for (l = NULL, c = head; c; l = c, c = c->next) { + if (strcmp(newc->u.name, c->u.name) == 0) { + yyerror2("duplicate devicetree entry for '%s'", newc->u.name); + goto bad; + } + } + + if (l) + l->next = newc; + else + policydbp->ocontexts[OCON_XEN_DEVICETREE] = newc; + + return 0; + +bad: + free(newc->u.name); + free(newc); + return -1; +} + int define_port_context(unsigned int low, unsigned int high) { ocontext_t *newc, *c, *l, *head; diff --git a/checkpolicy/policy_define.h b/checkpolicy/policy_define.h index 14d30e13..a87ced34 100644 --- a/checkpolicy/policy_define.h +++ b/checkpolicy/policy_define.h @@ -49,6 +49,7 @@ int define_pirq_context(unsigned int pirq); int define_iomem_context(uint64_t low, uint64_t high); int define_ioport_context(unsigned long low, unsigned long high); int define_pcidevice_context(unsigned long device); +int define_devicetree_context(void); int define_range_trans(int class_specified); int define_role_allow(void); int define_role_trans(int class_specified); diff --git a/checkpolicy/policy_parse.y b/checkpolicy/policy_parse.y index e3899b97..8b81f04c 100644 --- a/checkpolicy/policy_parse.y +++ b/checkpolicy/policy_parse.y @@ -130,7 +130,7 @@ typedef int (* require_func_t)(int pass); %token TARGET %token SAMEUSER %token FSCON PORTCON NETIFCON NODECON -%token PIRQCON IOMEMCON IOPORTCON PCIDEVICECON +%token PIRQCON IOMEMCON IOPORTCON PCIDEVICECON DEVICETREECON %token FSUSEXATTR FSUSETASK FSUSETRANS %token GENFSCON %token U1 U2 U3 R1 R2 R3 T1 T2 T3 L1 L2 H1 H2 @@ -644,7 +644,8 @@ dev_contexts : dev_context_def dev_context_def : pirq_context_def | iomem_context_def | ioport_context_def | - pci_context_def + pci_context_def | + dtree_context_def ; pirq_context_def : PIRQCON number security_context_def {if (define_pirq_context($2)) return -1;} @@ -662,6 +663,9 @@ ioport_context_def : IOPORTCON number security_context_def pci_context_def : PCIDEVICECON number security_context_def {if (define_pcidevice_context($2)) return -1;} ; +dtree_context_def : DEVICETREECON path security_context_def + {if (define_devicetree_context()) return -1;} + ; opt_fs_contexts : fs_contexts | ; diff --git a/checkpolicy/policy_scan.l b/checkpolicy/policy_scan.l index 6763c380..108edbc3 100644 --- a/checkpolicy/policy_scan.l +++ b/checkpolicy/policy_scan.l @@ -187,6 +187,8 @@ ioportcon | IOPORTCON { return(IOPORTCON);} pcidevicecon | PCIDEVICECON { return(PCIDEVICECON);} +devicetreecon | +DEVICETREECON { return(DEVICETREECON);} fs_use_xattr | FS_USE_XATTR { return(FSUSEXATTR);} fs_use_task | diff --git a/libsepol/cil/src/cil.c b/libsepol/cil/src/cil.c index a25f878c..1594be6d 100644 --- a/libsepol/cil/src/cil.c +++ b/libsepol/cil/src/cil.c @@ -189,6 +189,7 @@ static void cil_init_keys(void) CIL_KEY_IOMEMCON = cil_strpool_add("iomemcon"); CIL_KEY_IOPORTCON = cil_strpool_add("ioportcon"); CIL_KEY_PCIDEVICECON = cil_strpool_add("pcidevicecon"); + CIL_KEY_DEVICETREECON = cil_strpool_add("devicetreecon"); CIL_KEY_FSUSE = cil_strpool_add("fsuse"); CIL_KEY_POLICYCAP = cil_strpool_add("policycap"); CIL_KEY_OPTIONAL = cil_strpool_add("optional"); @@ -244,6 +245,7 @@ void cil_db_init(struct cil_db **db) cil_sort_init(&(*db)->iomemcon); cil_sort_init(&(*db)->ioportcon); cil_sort_init(&(*db)->pcidevicecon); + cil_sort_init(&(*db)->devicetreecon); cil_sort_init(&(*db)->fsuse); cil_list_init(&(*db)->userprefixes, CIL_LIST_ITEM); cil_list_init(&(*db)->selinuxusers, CIL_LIST_ITEM); @@ -289,6 +291,7 @@ void cil_db_destroy(struct cil_db **db) cil_sort_destroy(&(*db)->iomemcon); cil_sort_destroy(&(*db)->ioportcon); cil_sort_destroy(&(*db)->pcidevicecon); + cil_sort_destroy(&(*db)->devicetreecon); cil_sort_destroy(&(*db)->fsuse); cil_list_destroy(&(*db)->userprefixes, CIL_FALSE); cil_list_destroy(&(*db)->selinuxusers, CIL_FALSE); @@ -697,6 +700,9 @@ void cil_destroy_data(void **data, enum cil_flavor flavor) case CIL_PCIDEVICECON: cil_destroy_pcidevicecon(*data); break; + case CIL_DEVICETREECON: + cil_destroy_devicetreecon(*data); + break; case CIL_POLICYCAP: cil_destroy_policycap(*data); break; @@ -1026,6 +1032,8 @@ const char * cil_node_to_string(struct cil_tree_node *node) return CIL_KEY_IOPORTCON; case CIL_PCIDEVICECON: return CIL_KEY_PCIDEVICECON; + case CIL_DEVICETREECON: + return CIL_KEY_DEVICETREECON; case CIL_POLICYCAP: return CIL_KEY_POLICYCAP; case CIL_DEFAULTUSER: @@ -2181,6 +2189,15 @@ void cil_pcidevicecon_init(struct cil_pcidevicecon **pcidevicecon) (*pcidevicecon)->context = NULL; } +void cil_devicetreecon_init(struct cil_devicetreecon **dtcon) +{ + *dtcon = cil_malloc(sizeof(**dtcon)); + + (*dtcon)->path = NULL; + (*dtcon)->context_str = NULL; + (*dtcon)->context = NULL; +} + void cil_fsuse_init(struct cil_fsuse **fsuse) { *fsuse = cil_malloc(sizeof(**fsuse)); diff --git a/libsepol/cil/src/cil_binary.c b/libsepol/cil/src/cil_binary.c index 387237fe..03f4924e 100644 --- a/libsepol/cil/src/cil_binary.c +++ b/libsepol/cil/src/cil_binary.c @@ -2993,6 +2993,30 @@ exit: return rc; } +int cil_devicetreecon_to_policydb(policydb_t *pdb, struct cil_sort *devicetreecons) +{ + int rc = SEPOL_ERR; + uint32_t i = 0; + ocontext_t *tail = NULL; + + for (i = 0; i < devicetreecons->count; i++) { + ocontext_t *new_ocon = cil_add_ocontext(&pdb->ocontexts[OCON_XEN_DEVICETREE], &tail); + struct cil_devicetreecon *cil_devicetreecon = devicetreecons->array[i]; + + new_ocon->u.name = cil_strdup(cil_devicetreecon->path); + + rc = __cil_context_to_sepol_context(pdb, cil_devicetreecon->context, &new_ocon->context[0]); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + int cil_default_to_policydb(policydb_t *pdb, struct cil_default *def) { struct cil_list_item *curr; @@ -3340,6 +3364,11 @@ int __cil_contexts_to_policydb(policydb_t *pdb, const struct cil_db *db) if (rc != SEPOL_OK) { goto exit; } + + rc = cil_devicetreecon_to_policydb(pdb, db->devicetreecon); + if (rc != SEPOL_OK) { + goto exit; + } } return SEPOL_OK; exit: diff --git a/libsepol/cil/src/cil_build_ast.c b/libsepol/cil/src/cil_build_ast.c index 1949d2b8..973b2d79 100644 --- a/libsepol/cil/src/cil_build_ast.c +++ b/libsepol/cil/src/cil_build_ast.c @@ -4529,6 +4529,69 @@ void cil_destroy_pcidevicecon(struct cil_pcidevicecon *pcidevicecon) free(pcidevicecon); } +int cil_gen_devicetreecon(__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_END + }; + int syntax_len = sizeof(syntax)/sizeof(*syntax); + int rc = SEPOL_ERR; + struct cil_devicetreecon *devicetreecon = NULL; + + if (db == NULL || parse_current == NULL || ast_node == NULL) { + goto exit; + } + + rc = __cil_verify_syntax(parse_current, syntax, syntax_len); + if (rc != SEPOL_OK) { + goto exit; + } + + cil_devicetreecon_init(&devicetreecon); + + devicetreecon->path = parse_current->next->data; + + if (parse_current->next->next->cl_head == NULL) { + devicetreecon->context_str = parse_current->next->next->data; + } else { + cil_context_init(&devicetreecon->context); + + rc = cil_fill_context(parse_current->next->next->cl_head, devicetreecon->context); + if (rc != SEPOL_OK) { + goto exit; + } + } + + ast_node->data = devicetreecon; + ast_node->flavor = CIL_DEVICETREECON; + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Bad devicetreecon declaration at line %d of %s\n", + parse_current->line, parse_current->path); + cil_destroy_devicetreecon(devicetreecon); + return rc; +} + +void cil_destroy_devicetreecon(struct cil_devicetreecon *devicetreecon) +{ + if (devicetreecon == NULL) { + return; + } + + free(devicetreecon->path); + + if (devicetreecon->context_str == NULL && devicetreecon->context != NULL) { + cil_destroy_context(devicetreecon->context); + } + + free(devicetreecon); +} + int cil_gen_fsuse(__attribute__((unused)) struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node) { enum cil_syntax syntax[] = { @@ -5806,6 +5869,9 @@ int __cil_build_ast_node_helper(struct cil_tree_node *parse_current, uint32_t *f } else if (parse_current->data == CIL_KEY_PCIDEVICECON) { rc = cil_gen_pcidevicecon(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; + } else if (parse_current->data == CIL_KEY_DEVICETREECON) { + rc = cil_gen_devicetreecon(db, parse_current, ast_node); + *finished = CIL_TREE_SKIP_NEXT; } else if (parse_current->data == CIL_KEY_FSUSE) { rc = cil_gen_fsuse(db, parse_current, ast_node); *finished = CIL_TREE_SKIP_NEXT; diff --git a/libsepol/cil/src/cil_build_ast.h b/libsepol/cil/src/cil_build_ast.h index 1bd33cea..43bc7f62 100644 --- a/libsepol/cil/src/cil_build_ast.h +++ b/libsepol/cil/src/cil_build_ast.h @@ -182,6 +182,8 @@ int cil_gen_ioportcon(struct cil_db *db, struct cil_tree_node *parse_current, st void cil_destroy_ioportcon(struct cil_ioportcon *ioportcon); int cil_gen_pcidevicecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); void cil_destroy_pcidevicecon(struct cil_pcidevicecon *pcidevicecon); +int cil_gen_devicetreecon(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); +void cil_destroy_devicetreecon(struct cil_devicetreecon *devicetreecon); int cil_gen_fsuse(struct cil_db *db, struct cil_tree_node *parse_current, struct cil_tree_node *ast_node); void cil_destroy_fsuse(struct cil_fsuse *fsuse); void cil_destroy_param(struct cil_param *param); diff --git a/libsepol/cil/src/cil_copy_ast.c b/libsepol/cil/src/cil_copy_ast.c index 5a245551..199ce1ce 100644 --- a/libsepol/cil/src/cil_copy_ast.c +++ b/libsepol/cil/src/cil_copy_ast.c @@ -1211,6 +1211,27 @@ int cil_copy_pcidevicecon(struct cil_db *db, void *data, void **copy, __attribut return SEPOL_OK; } +int cil_copy_devicetreecon(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) +{ + struct cil_devicetreecon *orig = data; + struct cil_devicetreecon *new = NULL; + + cil_devicetreecon_init(&new); + + new->path = orig->path; + + if (orig->context_str != NULL) { + 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_fsuse(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab) { struct cil_fsuse *orig = data; @@ -1780,6 +1801,9 @@ int __cil_copy_node_helper(struct cil_tree_node *orig, __attribute__((unused)) u case CIL_PCIDEVICECON: copy_func = &cil_copy_pcidevicecon; break; + case CIL_DEVICETREECON: + copy_func = &cil_copy_devicetreecon; + break; case CIL_FSUSE: copy_func = &cil_copy_fsuse; break; diff --git a/libsepol/cil/src/cil_flavor.h b/libsepol/cil/src/cil_flavor.h index 7295b190..d839f68b 100644 --- a/libsepol/cil/src/cil_flavor.h +++ b/libsepol/cil/src/cil_flavor.h @@ -102,6 +102,7 @@ enum cil_flavor { CIL_IOMEMCON, CIL_IOPORTCON, CIL_PCIDEVICECON, + CIL_DEVICETREECON, CIL_DEFAULTUSER, CIL_DEFAULTROLE, CIL_DEFAULTTYPE, diff --git a/libsepol/cil/src/cil_internal.h b/libsepol/cil/src/cil_internal.h index 11a20854..a43d1116 100644 --- a/libsepol/cil/src/cil_internal.h +++ b/libsepol/cil/src/cil_internal.h @@ -206,6 +206,7 @@ char *CIL_KEY_PIRQCON; char *CIL_KEY_IOMEMCON; char *CIL_KEY_IOPORTCON; char *CIL_KEY_PCIDEVICECON; +char *CIL_KEY_DEVICETREECON; char *CIL_KEY_FSUSE; char *CIL_KEY_POLICYCAP; char *CIL_KEY_OPTIONAL; @@ -273,6 +274,7 @@ struct cil_db { struct cil_sort *iomemcon; struct cil_sort *ioportcon; struct cil_sort *pcidevicecon; + struct cil_sort *devicetreecon; struct cil_sort *fsuse; struct cil_list *userprefixes; struct cil_list *selinuxusers; @@ -738,6 +740,13 @@ struct cil_pcidevicecon { struct cil_context *context; }; +struct cil_devicetreecon { + char *path; + char *context_str; + struct cil_context *context; +}; + + /* Ensure that CIL uses the same values as sepol services.h */ enum cil_fsuse_types { CIL_FSUSE_XATTR = SECURITY_FS_USE_XATTR, @@ -933,6 +942,7 @@ void cil_pirqcon_init(struct cil_pirqcon **pirqcon); void cil_iomemcon_init(struct cil_iomemcon **iomemcon); void cil_ioportcon_init(struct cil_ioportcon **ioportcon); void cil_pcidevicecon_init(struct cil_pcidevicecon **pcidevicecon); +void cil_devicetreecon_init(struct cil_devicetreecon **devicetreecon); void cil_fsuse_init(struct cil_fsuse **fsuse); void cil_constrain_init(struct cil_constrain **constrain); void cil_validatetrans_init(struct cil_validatetrans **validtrans); diff --git a/libsepol/cil/src/cil_post.c b/libsepol/cil/src/cil_post.c index e89f16ba..633a5a12 100644 --- a/libsepol/cil/src/cil_post.c +++ b/libsepol/cil/src/cil_post.c @@ -296,6 +296,17 @@ int cil_post_pcidevicecon_compare(const void *a, const void *b) return rc; } +int cil_post_devicetreecon_compare(const void *a, const void *b) +{ + int rc = SEPOL_ERR; + struct cil_devicetreecon *adevicetreecon = *(struct cil_devicetreecon**)a; + struct cil_devicetreecon *bdevicetreecon = *(struct cil_devicetreecon**)b; + + rc = strcmp(adevicetreecon->path, bdevicetreecon->path); + + return rc; +} + int cil_post_fsuse_compare(const void *a, const void *b) { int rc; @@ -377,6 +388,9 @@ static int __cil_post_db_count_helper(struct cil_tree_node *node, uint32_t *fini case CIL_PCIDEVICECON: db->pcidevicecon->count++; break; + case CIL_DEVICETREECON: + db->devicetreecon->count++; + break; case CIL_FSUSE: db->fsuse->count++; break; @@ -540,6 +554,17 @@ static int __cil_post_db_array_helper(struct cil_tree_node *node, __attribute__( sort->index++; break; } + case CIL_DEVICETREECON: { + struct cil_sort *sort = db->devicetreecon; + uint32_t count = sort->count; + uint32_t i = sort->index; + if (sort->array == NULL) { + sort->array = cil_malloc(sizeof(*sort->array)*count); + } + sort->array[i] = node->data; + sort->index++; + break; + } default: break; } @@ -1305,6 +1330,14 @@ static int __cil_post_db_cat_helper(struct cil_tree_node *node, uint32_t *finish } break; } + case CIL_DEVICETREECON: { + struct cil_devicetreecon *devicetreecon = node->data; + rc = __evaluate_levelrange_expression(devicetreecon->context->range, db); + if (rc != SEPOL_OK) { + goto exit; + } + break; + } case CIL_FSUSE: { struct cil_fsuse *fsuse = node->data; rc = __evaluate_levelrange_expression(fsuse->context->range, db); @@ -1590,6 +1623,7 @@ static int cil_post_db(struct cil_db *db) qsort(db->iomemcon->array, db->iomemcon->count, sizeof(db->iomemcon->array), cil_post_iomemcon_compare); qsort(db->ioportcon->array, db->ioportcon->count, sizeof(db->ioportcon->array), cil_post_ioportcon_compare); qsort(db->pcidevicecon->array, db->pcidevicecon->count, sizeof(db->pcidevicecon->array), cil_post_pcidevicecon_compare); + qsort(db->devicetreecon->array, db->devicetreecon->count, sizeof(db->devicetreecon->array), cil_post_devicetreecon_compare); exit: return rc; diff --git a/libsepol/cil/src/cil_reset_ast.c b/libsepol/cil/src/cil_reset_ast.c index 170e612c..92f7720b 100644 --- a/libsepol/cil/src/cil_reset_ast.c +++ b/libsepol/cil/src/cil_reset_ast.c @@ -323,6 +323,13 @@ static void cil_reset_pcidevicecon(struct cil_pcidevicecon *pcidevicecon) } } +static void cil_reset_devicetreecon(struct cil_devicetreecon *devicetreecon) +{ + if (devicetreecon->context_str == NULL) { + cil_reset_context(devicetreecon->context); + } +} + static void cil_reset_fsuse(struct cil_fsuse *fsuse) { if (fsuse->context_str == NULL) { @@ -475,6 +482,9 @@ int __cil_reset_node(struct cil_tree_node *node, __attribute__((unused)) uint32 case CIL_PCIDEVICECON: cil_reset_pcidevicecon(node->data); break; + case CIL_DEVICETREECON: + cil_reset_devicetreecon(node->data); + break; case CIL_FSUSE: cil_reset_fsuse(node->data); break; diff --git a/libsepol/cil/src/cil_resolve_ast.c b/libsepol/cil/src/cil_resolve_ast.c index e27f9656..7d46fd59 100644 --- a/libsepol/cil/src/cil_resolve_ast.c +++ b/libsepol/cil/src/cil_resolve_ast.c @@ -1969,6 +1969,31 @@ exit: return rc; } +int cil_resolve_devicetreecon(struct cil_tree_node *current, void *extra_args) +{ + struct cil_devicetreecon *devicetreecon = current->data; + struct cil_symtab_datum *context_datum = NULL; + int rc = SEPOL_ERR; + + if (devicetreecon->context_str != NULL) { + rc = cil_resolve_name(current, devicetreecon->context_str, CIL_SYM_CONTEXTS, extra_args, &context_datum); + if (rc != SEPOL_OK) { + goto exit; + } + devicetreecon->context = (struct cil_context*)context_datum; + } else { + rc = cil_resolve_context(current, devicetreecon->context, extra_args); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + return rc; +} + int cil_resolve_fsuse(struct cil_tree_node *current, void *extra_args) { struct cil_fsuse *fsuse = current->data; @@ -3185,6 +3210,9 @@ int __cil_resolve_ast_node(struct cil_tree_node *node, void *extra_args) case CIL_PCIDEVICECON: rc = cil_resolve_pcidevicecon(node, args); break; + case CIL_DEVICETREECON: + rc = cil_resolve_devicetreecon(node, args); + break; case CIL_FSUSE: rc = cil_resolve_fsuse(node, args); break; diff --git a/libsepol/cil/src/cil_tree.c b/libsepol/cil/src/cil_tree.c index 81a1abc6..6a731f22 100644 --- a/libsepol/cil/src/cil_tree.c +++ b/libsepol/cil/src/cil_tree.c @@ -1429,6 +1429,19 @@ void cil_tree_print_node(struct cil_tree_node *node) cil_log(CIL_INFO, "\n"); return; } + case CIL_DEVICETREECON: { + struct cil_devicetreecon *devicetreecon = node->data; + + cil_log(CIL_INFO, "DEVICETREECON %s", devicetreecon->path); + if (devicetreecon->context != NULL) { + cil_tree_print_context(devicetreecon->context); + } else { + cil_log(CIL_INFO, " %s", devicetreecon->context_str); + } + + cil_log(CIL_INFO, "\n"); + return; + } case CIL_FSUSE: { struct cil_fsuse *fsuse = node->data; cil_log(CIL_INFO, "FSUSE: "); diff --git a/libsepol/cil/src/cil_verify.c b/libsepol/cil/src/cil_verify.c index 03e0fd19..399c94a6 100644 --- a/libsepol/cil/src/cil_verify.c +++ b/libsepol/cil/src/cil_verify.c @@ -1181,6 +1181,27 @@ exit: return rc; } +int __cil_verify_devicetreecon(struct cil_db *db, struct cil_tree_node *node) +{ + int rc = SEPOL_ERR; + struct cil_devicetreecon *dt = node->data; + struct cil_context *ctx = dt->context; + + /* Verify only when anonymous */ + if (ctx->datum.name == NULL) { + rc = __cil_verify_context(db, ctx); + if (rc != SEPOL_OK) { + goto exit; + } + } + + return SEPOL_OK; + +exit: + cil_log(CIL_ERR, "Invalid devicetreecon at line %d of %s\n", node->line, node->path); + return rc; +} + int __cil_verify_fsuse(struct cil_db *db, struct cil_tree_node *node) { int rc = SEPOL_ERR; @@ -1390,6 +1411,9 @@ int __cil_verify_helper(struct cil_tree_node *node, uint32_t *finished, void *ex case CIL_PCIDEVICECON: rc = __cil_verify_pcidevicecon(db, node); break; + case CIL_DEVICETREECON: + rc = __cil_verify_devicetreecon(db, node); + break; case CIL_FSUSE: rc = __cil_verify_fsuse(db, node); break; diff --git a/libsepol/include/sepol/policydb/policydb.h b/libsepol/include/sepol/policydb/policydb.h index 946cbafd..31efc3a7 100644 --- a/libsepol/include/sepol/policydb/policydb.h +++ b/libsepol/include/sepol/policydb/policydb.h @@ -375,6 +375,7 @@ typedef struct genfs { #define OCON_XEN_IOPORT 2 /* io ports */ #define OCON_XEN_IOMEM 3 /* io memory */ #define OCON_XEN_PCIDEVICE 4 /* pci devices */ +#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 diff --git a/libsepol/src/expand.c b/libsepol/src/expand.c index 3193ef55..a8b1115e 100644 --- a/libsepol/src/expand.c +++ b/libsepol/src/expand.c @@ -2091,6 +2091,13 @@ static int ocontext_copy_xen(expand_state_t *state) case OCON_XEN_PCIDEVICE: n->u.device = c->u.device; break; + case OCON_XEN_DEVICETREE: + n->u.name = strdup(c->u.name); + if (!n->u.name) { + ERR(state->handle, "Out of memory!"); + return -1; + } + break; default: /* shouldn't get here */ ERR(state->handle, "Unknown ocontext"); diff --git a/libsepol/src/policydb.c b/libsepol/src/policydb.c index d54eb9e4..b45b6628 100644 --- a/libsepol/src/policydb.c +++ b/libsepol/src/policydb.c @@ -70,7 +70,7 @@ static struct policydb_compat_info policydb_compat[] = { .type = POLICY_KERN, .version = POLICYDB_VERSION_XEN_DEVICETREE, .sym_num = SYM_NUM, - .ocon_num = OCON_XEN_PCIDEVICE + 1, + .ocon_num = OCON_XEN_DEVICETREE + 1, .target_platform = SEPOL_TARGET_XEN, }, { @@ -2478,7 +2478,7 @@ static int ocontext_read_xen(struct policydb_compat_info *info, policydb_t *p, struct policy_file *fp) { unsigned int i, j; - size_t nel; + size_t nel, len; ocontext_t *l, *c; uint32_t buf[8]; int rc; @@ -2555,6 +2555,20 @@ static int ocontext_read_xen(struct policydb_compat_info *info, (&c->context[0], p, fp)) return -1; break; + case OCON_XEN_DEVICETREE: + rc = next_entry(buf, fp, sizeof(uint32_t)); + if (rc < 0) + return -1; + len = le32_to_cpu(buf[1]); + c->u.name = malloc(len + 1); + if (!c->u.name) + return -1; + rc = next_entry(c->u.name, fp, len); + c->u.name[len] = 0; + if (context_read_and_validate + (&c->context[0], p, fp)) + return -1; + break; default: /* should never get here */ ERR(fp->handle, "Unknown Xen ocontext"); diff --git a/libsepol/src/write.c b/libsepol/src/write.c index 3452017d..c97a4da7 100644 --- a/libsepol/src/write.c +++ b/libsepol/src/write.c @@ -1211,7 +1211,7 @@ static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p, struct policy_file *fp) { unsigned int i, j; - size_t nel, items; + size_t nel, items, len; uint32_t buf[32]; ocontext_t *c; for (i = 0; i < info->ocon_num; i++) { @@ -1288,6 +1288,18 @@ static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p, if (context_write(p, &c->context[0], fp)) return POLICYDB_ERROR; break; + case OCON_XEN_DEVICETREE: + len = strlen(c->u.name); + buf[0] = cpu_to_le32(len); + items = put_entry(buf, sizeof(uint32_t), 1, fp); + if (items != 1) + return POLICYDB_ERROR; + items = put_entry(c->u.name, 1, len, fp); + if (items != len) + return POLICYDB_ERROR; + if (context_write(p, &c->context[0], fp)) + return POLICYDB_ERROR; + break; } } } diff --git a/sepolgen/src/sepolgen/refparser.py b/sepolgen/src/sepolgen/refparser.py index b453a296..83542d3e 100644 --- a/sepolgen/src/sepolgen/refparser.py +++ b/sepolgen/src/sepolgen/refparser.py @@ -88,6 +88,7 @@ tokens = ( 'IOMEMCON', 'IOPORTCON', 'PCIDEVICECON', + 'DEVICETREECON', # object classes 'CLASS', # types and attributes @@ -152,6 +153,7 @@ reserved = { 'iomemcon' : 'IOMEMCON', 'ioportcon' : 'IOPORTCON', 'pcidevicecon' : 'PCIDEVICECON', + 'devicetreecon' : 'DEVICETREECON', # object classes 'class' : 'CLASS', # types and attributes @@ -524,6 +526,7 @@ def p_policy_stmt(p): | iomemcon | ioportcon | pcidevicecon + | devicetreecon ''' if p[1]: p[0] = [p[1]] @@ -703,6 +706,14 @@ def p_pcidevicecon(p): p[0] = c +def p_devicetreecon(p): + 'devicetreecon : DEVICETREECON NUMBER context' + c = refpolicy.DevicetTeeCon() + c.path = p[2] + c.context = p[3] + + p[0] = c + def p_mls_range_def(p): '''mls_range_def : mls_level_def MINUS mls_level_def | mls_level_def diff --git a/sepolgen/src/sepolgen/refpolicy.py b/sepolgen/src/sepolgen/refpolicy.py index 8ad64a9e..b8ed5c19 100644 --- a/sepolgen/src/sepolgen/refpolicy.py +++ b/sepolgen/src/sepolgen/refpolicy.py @@ -687,6 +687,15 @@ class PciDeviceCon(Leaf): def to_string(self): return "pcidevicecon %s %s" % (self.device, str(self.context)) +class DeviceTreeCon(Leaf): + def __init__(self, parent=None): + Leaf.__init__(self, parent) + self.path = "" + self.context = None + + def to_string(self): + return "devicetreecon %s %s" % (self.path, str(self.context)) + # Reference policy specific types def print_tree(head):