libsepol, checkpolicy: add device tree ocontext nodes to Xen policy
In Xen on ARM, device tree nodes identified by a path (string) need to be labeled by the security policy. Signed-off-by: Daniel De Graaf <dgdegra@tycho.nsa.gov>
This commit is contained in:
parent
82030de5dc
commit
f029067709
22 changed files with 379 additions and 5 deletions
|
@ -4116,6 +4116,61 @@ bad:
|
||||||
return -1;
|
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)
|
int define_port_context(unsigned int low, unsigned int high)
|
||||||
{
|
{
|
||||||
ocontext_t *newc, *c, *l, *head;
|
ocontext_t *newc, *c, *l, *head;
|
||||||
|
|
|
@ -49,6 +49,7 @@ int define_pirq_context(unsigned int pirq);
|
||||||
int define_iomem_context(uint64_t low, uint64_t high);
|
int define_iomem_context(uint64_t low, uint64_t high);
|
||||||
int define_ioport_context(unsigned long low, unsigned long high);
|
int define_ioport_context(unsigned long low, unsigned long high);
|
||||||
int define_pcidevice_context(unsigned long device);
|
int define_pcidevice_context(unsigned long device);
|
||||||
|
int define_devicetree_context(void);
|
||||||
int define_range_trans(int class_specified);
|
int define_range_trans(int class_specified);
|
||||||
int define_role_allow(void);
|
int define_role_allow(void);
|
||||||
int define_role_trans(int class_specified);
|
int define_role_trans(int class_specified);
|
||||||
|
|
|
@ -130,7 +130,7 @@ typedef int (* require_func_t)(int pass);
|
||||||
%token TARGET
|
%token TARGET
|
||||||
%token SAMEUSER
|
%token SAMEUSER
|
||||||
%token FSCON PORTCON NETIFCON NODECON
|
%token FSCON PORTCON NETIFCON NODECON
|
||||||
%token PIRQCON IOMEMCON IOPORTCON PCIDEVICECON
|
%token PIRQCON IOMEMCON IOPORTCON PCIDEVICECON DEVICETREECON
|
||||||
%token FSUSEXATTR FSUSETASK FSUSETRANS
|
%token FSUSEXATTR FSUSETASK FSUSETRANS
|
||||||
%token GENFSCON
|
%token GENFSCON
|
||||||
%token U1 U2 U3 R1 R2 R3 T1 T2 T3 L1 L2 H1 H2
|
%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 |
|
dev_context_def : pirq_context_def |
|
||||||
iomem_context_def |
|
iomem_context_def |
|
||||||
ioport_context_def |
|
ioport_context_def |
|
||||||
pci_context_def
|
pci_context_def |
|
||||||
|
dtree_context_def
|
||||||
;
|
;
|
||||||
pirq_context_def : PIRQCON number security_context_def
|
pirq_context_def : PIRQCON number security_context_def
|
||||||
{if (define_pirq_context($2)) return -1;}
|
{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
|
pci_context_def : PCIDEVICECON number security_context_def
|
||||||
{if (define_pcidevice_context($2)) return -1;}
|
{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
|
opt_fs_contexts : fs_contexts
|
||||||
|
|
|
|
||||||
;
|
;
|
||||||
|
|
|
@ -187,6 +187,8 @@ ioportcon |
|
||||||
IOPORTCON { return(IOPORTCON);}
|
IOPORTCON { return(IOPORTCON);}
|
||||||
pcidevicecon |
|
pcidevicecon |
|
||||||
PCIDEVICECON { return(PCIDEVICECON);}
|
PCIDEVICECON { return(PCIDEVICECON);}
|
||||||
|
devicetreecon |
|
||||||
|
DEVICETREECON { return(DEVICETREECON);}
|
||||||
fs_use_xattr |
|
fs_use_xattr |
|
||||||
FS_USE_XATTR { return(FSUSEXATTR);}
|
FS_USE_XATTR { return(FSUSEXATTR);}
|
||||||
fs_use_task |
|
fs_use_task |
|
||||||
|
|
|
@ -189,6 +189,7 @@ static void cil_init_keys(void)
|
||||||
CIL_KEY_IOMEMCON = cil_strpool_add("iomemcon");
|
CIL_KEY_IOMEMCON = cil_strpool_add("iomemcon");
|
||||||
CIL_KEY_IOPORTCON = cil_strpool_add("ioportcon");
|
CIL_KEY_IOPORTCON = cil_strpool_add("ioportcon");
|
||||||
CIL_KEY_PCIDEVICECON = cil_strpool_add("pcidevicecon");
|
CIL_KEY_PCIDEVICECON = cil_strpool_add("pcidevicecon");
|
||||||
|
CIL_KEY_DEVICETREECON = cil_strpool_add("devicetreecon");
|
||||||
CIL_KEY_FSUSE = cil_strpool_add("fsuse");
|
CIL_KEY_FSUSE = cil_strpool_add("fsuse");
|
||||||
CIL_KEY_POLICYCAP = cil_strpool_add("policycap");
|
CIL_KEY_POLICYCAP = cil_strpool_add("policycap");
|
||||||
CIL_KEY_OPTIONAL = cil_strpool_add("optional");
|
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)->iomemcon);
|
||||||
cil_sort_init(&(*db)->ioportcon);
|
cil_sort_init(&(*db)->ioportcon);
|
||||||
cil_sort_init(&(*db)->pcidevicecon);
|
cil_sort_init(&(*db)->pcidevicecon);
|
||||||
|
cil_sort_init(&(*db)->devicetreecon);
|
||||||
cil_sort_init(&(*db)->fsuse);
|
cil_sort_init(&(*db)->fsuse);
|
||||||
cil_list_init(&(*db)->userprefixes, CIL_LIST_ITEM);
|
cil_list_init(&(*db)->userprefixes, CIL_LIST_ITEM);
|
||||||
cil_list_init(&(*db)->selinuxusers, 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)->iomemcon);
|
||||||
cil_sort_destroy(&(*db)->ioportcon);
|
cil_sort_destroy(&(*db)->ioportcon);
|
||||||
cil_sort_destroy(&(*db)->pcidevicecon);
|
cil_sort_destroy(&(*db)->pcidevicecon);
|
||||||
|
cil_sort_destroy(&(*db)->devicetreecon);
|
||||||
cil_sort_destroy(&(*db)->fsuse);
|
cil_sort_destroy(&(*db)->fsuse);
|
||||||
cil_list_destroy(&(*db)->userprefixes, CIL_FALSE);
|
cil_list_destroy(&(*db)->userprefixes, CIL_FALSE);
|
||||||
cil_list_destroy(&(*db)->selinuxusers, 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:
|
case CIL_PCIDEVICECON:
|
||||||
cil_destroy_pcidevicecon(*data);
|
cil_destroy_pcidevicecon(*data);
|
||||||
break;
|
break;
|
||||||
|
case CIL_DEVICETREECON:
|
||||||
|
cil_destroy_devicetreecon(*data);
|
||||||
|
break;
|
||||||
case CIL_POLICYCAP:
|
case CIL_POLICYCAP:
|
||||||
cil_destroy_policycap(*data);
|
cil_destroy_policycap(*data);
|
||||||
break;
|
break;
|
||||||
|
@ -1026,6 +1032,8 @@ const char * cil_node_to_string(struct cil_tree_node *node)
|
||||||
return CIL_KEY_IOPORTCON;
|
return CIL_KEY_IOPORTCON;
|
||||||
case CIL_PCIDEVICECON:
|
case CIL_PCIDEVICECON:
|
||||||
return CIL_KEY_PCIDEVICECON;
|
return CIL_KEY_PCIDEVICECON;
|
||||||
|
case CIL_DEVICETREECON:
|
||||||
|
return CIL_KEY_DEVICETREECON;
|
||||||
case CIL_POLICYCAP:
|
case CIL_POLICYCAP:
|
||||||
return CIL_KEY_POLICYCAP;
|
return CIL_KEY_POLICYCAP;
|
||||||
case CIL_DEFAULTUSER:
|
case CIL_DEFAULTUSER:
|
||||||
|
@ -2181,6 +2189,15 @@ void cil_pcidevicecon_init(struct cil_pcidevicecon **pcidevicecon)
|
||||||
(*pcidevicecon)->context = NULL;
|
(*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)
|
void cil_fsuse_init(struct cil_fsuse **fsuse)
|
||||||
{
|
{
|
||||||
*fsuse = cil_malloc(sizeof(**fsuse));
|
*fsuse = cil_malloc(sizeof(**fsuse));
|
||||||
|
|
|
@ -2993,6 +2993,30 @@ exit:
|
||||||
return rc;
|
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)
|
int cil_default_to_policydb(policydb_t *pdb, struct cil_default *def)
|
||||||
{
|
{
|
||||||
struct cil_list_item *curr;
|
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) {
|
if (rc != SEPOL_OK) {
|
||||||
goto exit;
|
goto exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
rc = cil_devicetreecon_to_policydb(pdb, db->devicetreecon);
|
||||||
|
if (rc != SEPOL_OK) {
|
||||||
|
goto exit;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return SEPOL_OK;
|
return SEPOL_OK;
|
||||||
exit:
|
exit:
|
||||||
|
|
|
@ -4529,6 +4529,69 @@ void cil_destroy_pcidevicecon(struct cil_pcidevicecon *pcidevicecon)
|
||||||
free(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)
|
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[] = {
|
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) {
|
} else if (parse_current->data == CIL_KEY_PCIDEVICECON) {
|
||||||
rc = cil_gen_pcidevicecon(db, parse_current, ast_node);
|
rc = cil_gen_pcidevicecon(db, parse_current, ast_node);
|
||||||
*finished = CIL_TREE_SKIP_NEXT;
|
*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) {
|
} else if (parse_current->data == CIL_KEY_FSUSE) {
|
||||||
rc = cil_gen_fsuse(db, parse_current, ast_node);
|
rc = cil_gen_fsuse(db, parse_current, ast_node);
|
||||||
*finished = CIL_TREE_SKIP_NEXT;
|
*finished = CIL_TREE_SKIP_NEXT;
|
||||||
|
|
|
@ -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);
|
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);
|
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);
|
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);
|
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_fsuse(struct cil_fsuse *fsuse);
|
||||||
void cil_destroy_param(struct cil_param *param);
|
void cil_destroy_param(struct cil_param *param);
|
||||||
|
|
|
@ -1211,6 +1211,27 @@ int cil_copy_pcidevicecon(struct cil_db *db, void *data, void **copy, __attribut
|
||||||
return SEPOL_OK;
|
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)
|
int cil_copy_fsuse(struct cil_db *db, void *data, void **copy, __attribute__((unused)) symtab_t *symtab)
|
||||||
{
|
{
|
||||||
struct cil_fsuse *orig = data;
|
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:
|
case CIL_PCIDEVICECON:
|
||||||
copy_func = &cil_copy_pcidevicecon;
|
copy_func = &cil_copy_pcidevicecon;
|
||||||
break;
|
break;
|
||||||
|
case CIL_DEVICETREECON:
|
||||||
|
copy_func = &cil_copy_devicetreecon;
|
||||||
|
break;
|
||||||
case CIL_FSUSE:
|
case CIL_FSUSE:
|
||||||
copy_func = &cil_copy_fsuse;
|
copy_func = &cil_copy_fsuse;
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -102,6 +102,7 @@ enum cil_flavor {
|
||||||
CIL_IOMEMCON,
|
CIL_IOMEMCON,
|
||||||
CIL_IOPORTCON,
|
CIL_IOPORTCON,
|
||||||
CIL_PCIDEVICECON,
|
CIL_PCIDEVICECON,
|
||||||
|
CIL_DEVICETREECON,
|
||||||
CIL_DEFAULTUSER,
|
CIL_DEFAULTUSER,
|
||||||
CIL_DEFAULTROLE,
|
CIL_DEFAULTROLE,
|
||||||
CIL_DEFAULTTYPE,
|
CIL_DEFAULTTYPE,
|
||||||
|
|
|
@ -206,6 +206,7 @@ char *CIL_KEY_PIRQCON;
|
||||||
char *CIL_KEY_IOMEMCON;
|
char *CIL_KEY_IOMEMCON;
|
||||||
char *CIL_KEY_IOPORTCON;
|
char *CIL_KEY_IOPORTCON;
|
||||||
char *CIL_KEY_PCIDEVICECON;
|
char *CIL_KEY_PCIDEVICECON;
|
||||||
|
char *CIL_KEY_DEVICETREECON;
|
||||||
char *CIL_KEY_FSUSE;
|
char *CIL_KEY_FSUSE;
|
||||||
char *CIL_KEY_POLICYCAP;
|
char *CIL_KEY_POLICYCAP;
|
||||||
char *CIL_KEY_OPTIONAL;
|
char *CIL_KEY_OPTIONAL;
|
||||||
|
@ -273,6 +274,7 @@ struct cil_db {
|
||||||
struct cil_sort *iomemcon;
|
struct cil_sort *iomemcon;
|
||||||
struct cil_sort *ioportcon;
|
struct cil_sort *ioportcon;
|
||||||
struct cil_sort *pcidevicecon;
|
struct cil_sort *pcidevicecon;
|
||||||
|
struct cil_sort *devicetreecon;
|
||||||
struct cil_sort *fsuse;
|
struct cil_sort *fsuse;
|
||||||
struct cil_list *userprefixes;
|
struct cil_list *userprefixes;
|
||||||
struct cil_list *selinuxusers;
|
struct cil_list *selinuxusers;
|
||||||
|
@ -738,6 +740,13 @@ struct cil_pcidevicecon {
|
||||||
struct cil_context *context;
|
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 */
|
/* Ensure that CIL uses the same values as sepol services.h */
|
||||||
enum cil_fsuse_types {
|
enum cil_fsuse_types {
|
||||||
CIL_FSUSE_XATTR = SECURITY_FS_USE_XATTR,
|
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_iomemcon_init(struct cil_iomemcon **iomemcon);
|
||||||
void cil_ioportcon_init(struct cil_ioportcon **ioportcon);
|
void cil_ioportcon_init(struct cil_ioportcon **ioportcon);
|
||||||
void cil_pcidevicecon_init(struct cil_pcidevicecon **pcidevicecon);
|
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_fsuse_init(struct cil_fsuse **fsuse);
|
||||||
void cil_constrain_init(struct cil_constrain **constrain);
|
void cil_constrain_init(struct cil_constrain **constrain);
|
||||||
void cil_validatetrans_init(struct cil_validatetrans **validtrans);
|
void cil_validatetrans_init(struct cil_validatetrans **validtrans);
|
||||||
|
|
|
@ -296,6 +296,17 @@ int cil_post_pcidevicecon_compare(const void *a, const void *b)
|
||||||
return rc;
|
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 cil_post_fsuse_compare(const void *a, const void *b)
|
||||||
{
|
{
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -377,6 +388,9 @@ static int __cil_post_db_count_helper(struct cil_tree_node *node, uint32_t *fini
|
||||||
case CIL_PCIDEVICECON:
|
case CIL_PCIDEVICECON:
|
||||||
db->pcidevicecon->count++;
|
db->pcidevicecon->count++;
|
||||||
break;
|
break;
|
||||||
|
case CIL_DEVICETREECON:
|
||||||
|
db->devicetreecon->count++;
|
||||||
|
break;
|
||||||
case CIL_FSUSE:
|
case CIL_FSUSE:
|
||||||
db->fsuse->count++;
|
db->fsuse->count++;
|
||||||
break;
|
break;
|
||||||
|
@ -540,6 +554,17 @@ static int __cil_post_db_array_helper(struct cil_tree_node *node, __attribute__(
|
||||||
sort->index++;
|
sort->index++;
|
||||||
break;
|
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:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -1305,6 +1330,14 @@ static int __cil_post_db_cat_helper(struct cil_tree_node *node, uint32_t *finish
|
||||||
}
|
}
|
||||||
break;
|
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: {
|
case CIL_FSUSE: {
|
||||||
struct cil_fsuse *fsuse = node->data;
|
struct cil_fsuse *fsuse = node->data;
|
||||||
rc = __evaluate_levelrange_expression(fsuse->context->range, db);
|
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->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->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->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:
|
exit:
|
||||||
return rc;
|
return rc;
|
||||||
|
|
|
@ -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)
|
static void cil_reset_fsuse(struct cil_fsuse *fsuse)
|
||||||
{
|
{
|
||||||
if (fsuse->context_str == NULL) {
|
if (fsuse->context_str == NULL) {
|
||||||
|
@ -475,6 +482,9 @@ int __cil_reset_node(struct cil_tree_node *node, __attribute__((unused)) uint32
|
||||||
case CIL_PCIDEVICECON:
|
case CIL_PCIDEVICECON:
|
||||||
cil_reset_pcidevicecon(node->data);
|
cil_reset_pcidevicecon(node->data);
|
||||||
break;
|
break;
|
||||||
|
case CIL_DEVICETREECON:
|
||||||
|
cil_reset_devicetreecon(node->data);
|
||||||
|
break;
|
||||||
case CIL_FSUSE:
|
case CIL_FSUSE:
|
||||||
cil_reset_fsuse(node->data);
|
cil_reset_fsuse(node->data);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1969,6 +1969,31 @@ exit:
|
||||||
return rc;
|
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)
|
int cil_resolve_fsuse(struct cil_tree_node *current, void *extra_args)
|
||||||
{
|
{
|
||||||
struct cil_fsuse *fsuse = current->data;
|
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:
|
case CIL_PCIDEVICECON:
|
||||||
rc = cil_resolve_pcidevicecon(node, args);
|
rc = cil_resolve_pcidevicecon(node, args);
|
||||||
break;
|
break;
|
||||||
|
case CIL_DEVICETREECON:
|
||||||
|
rc = cil_resolve_devicetreecon(node, args);
|
||||||
|
break;
|
||||||
case CIL_FSUSE:
|
case CIL_FSUSE:
|
||||||
rc = cil_resolve_fsuse(node, args);
|
rc = cil_resolve_fsuse(node, args);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -1429,6 +1429,19 @@ void cil_tree_print_node(struct cil_tree_node *node)
|
||||||
cil_log(CIL_INFO, "\n");
|
cil_log(CIL_INFO, "\n");
|
||||||
return;
|
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: {
|
case CIL_FSUSE: {
|
||||||
struct cil_fsuse *fsuse = node->data;
|
struct cil_fsuse *fsuse = node->data;
|
||||||
cil_log(CIL_INFO, "FSUSE: ");
|
cil_log(CIL_INFO, "FSUSE: ");
|
||||||
|
|
|
@ -1181,6 +1181,27 @@ exit:
|
||||||
return rc;
|
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 __cil_verify_fsuse(struct cil_db *db, struct cil_tree_node *node)
|
||||||
{
|
{
|
||||||
int rc = SEPOL_ERR;
|
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:
|
case CIL_PCIDEVICECON:
|
||||||
rc = __cil_verify_pcidevicecon(db, node);
|
rc = __cil_verify_pcidevicecon(db, node);
|
||||||
break;
|
break;
|
||||||
|
case CIL_DEVICETREECON:
|
||||||
|
rc = __cil_verify_devicetreecon(db, node);
|
||||||
|
break;
|
||||||
case CIL_FSUSE:
|
case CIL_FSUSE:
|
||||||
rc = __cil_verify_fsuse(db, node);
|
rc = __cil_verify_fsuse(db, node);
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -375,6 +375,7 @@ typedef struct genfs {
|
||||||
#define OCON_XEN_IOPORT 2 /* io ports */
|
#define OCON_XEN_IOPORT 2 /* io ports */
|
||||||
#define OCON_XEN_IOMEM 3 /* io memory */
|
#define OCON_XEN_IOMEM 3 /* io memory */
|
||||||
#define OCON_XEN_PCIDEVICE 4 /* pci devices */
|
#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 */
|
/* OCON_NUM needs to be the largest index in any platform's ocontext array */
|
||||||
#define OCON_NUM 7
|
#define OCON_NUM 7
|
||||||
|
|
|
@ -2091,6 +2091,13 @@ static int ocontext_copy_xen(expand_state_t *state)
|
||||||
case OCON_XEN_PCIDEVICE:
|
case OCON_XEN_PCIDEVICE:
|
||||||
n->u.device = c->u.device;
|
n->u.device = c->u.device;
|
||||||
break;
|
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:
|
default:
|
||||||
/* shouldn't get here */
|
/* shouldn't get here */
|
||||||
ERR(state->handle, "Unknown ocontext");
|
ERR(state->handle, "Unknown ocontext");
|
||||||
|
|
|
@ -70,7 +70,7 @@ static struct policydb_compat_info policydb_compat[] = {
|
||||||
.type = POLICY_KERN,
|
.type = POLICY_KERN,
|
||||||
.version = POLICYDB_VERSION_XEN_DEVICETREE,
|
.version = POLICYDB_VERSION_XEN_DEVICETREE,
|
||||||
.sym_num = SYM_NUM,
|
.sym_num = SYM_NUM,
|
||||||
.ocon_num = OCON_XEN_PCIDEVICE + 1,
|
.ocon_num = OCON_XEN_DEVICETREE + 1,
|
||||||
.target_platform = SEPOL_TARGET_XEN,
|
.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)
|
policydb_t *p, struct policy_file *fp)
|
||||||
{
|
{
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
size_t nel;
|
size_t nel, len;
|
||||||
ocontext_t *l, *c;
|
ocontext_t *l, *c;
|
||||||
uint32_t buf[8];
|
uint32_t buf[8];
|
||||||
int rc;
|
int rc;
|
||||||
|
@ -2555,6 +2555,20 @@ static int ocontext_read_xen(struct policydb_compat_info *info,
|
||||||
(&c->context[0], p, fp))
|
(&c->context[0], p, fp))
|
||||||
return -1;
|
return -1;
|
||||||
break;
|
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:
|
default:
|
||||||
/* should never get here */
|
/* should never get here */
|
||||||
ERR(fp->handle, "Unknown Xen ocontext");
|
ERR(fp->handle, "Unknown Xen ocontext");
|
||||||
|
|
|
@ -1211,7 +1211,7 @@ static int ocontext_write_xen(struct policydb_compat_info *info, policydb_t *p,
|
||||||
struct policy_file *fp)
|
struct policy_file *fp)
|
||||||
{
|
{
|
||||||
unsigned int i, j;
|
unsigned int i, j;
|
||||||
size_t nel, items;
|
size_t nel, items, len;
|
||||||
uint32_t buf[32];
|
uint32_t buf[32];
|
||||||
ocontext_t *c;
|
ocontext_t *c;
|
||||||
for (i = 0; i < info->ocon_num; i++) {
|
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))
|
if (context_write(p, &c->context[0], fp))
|
||||||
return POLICYDB_ERROR;
|
return POLICYDB_ERROR;
|
||||||
break;
|
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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -88,6 +88,7 @@ tokens = (
|
||||||
'IOMEMCON',
|
'IOMEMCON',
|
||||||
'IOPORTCON',
|
'IOPORTCON',
|
||||||
'PCIDEVICECON',
|
'PCIDEVICECON',
|
||||||
|
'DEVICETREECON',
|
||||||
# object classes
|
# object classes
|
||||||
'CLASS',
|
'CLASS',
|
||||||
# types and attributes
|
# types and attributes
|
||||||
|
@ -152,6 +153,7 @@ reserved = {
|
||||||
'iomemcon' : 'IOMEMCON',
|
'iomemcon' : 'IOMEMCON',
|
||||||
'ioportcon' : 'IOPORTCON',
|
'ioportcon' : 'IOPORTCON',
|
||||||
'pcidevicecon' : 'PCIDEVICECON',
|
'pcidevicecon' : 'PCIDEVICECON',
|
||||||
|
'devicetreecon' : 'DEVICETREECON',
|
||||||
# object classes
|
# object classes
|
||||||
'class' : 'CLASS',
|
'class' : 'CLASS',
|
||||||
# types and attributes
|
# types and attributes
|
||||||
|
@ -524,6 +526,7 @@ def p_policy_stmt(p):
|
||||||
| iomemcon
|
| iomemcon
|
||||||
| ioportcon
|
| ioportcon
|
||||||
| pcidevicecon
|
| pcidevicecon
|
||||||
|
| devicetreecon
|
||||||
'''
|
'''
|
||||||
if p[1]:
|
if p[1]:
|
||||||
p[0] = [p[1]]
|
p[0] = [p[1]]
|
||||||
|
@ -703,6 +706,14 @@ def p_pcidevicecon(p):
|
||||||
|
|
||||||
p[0] = c
|
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):
|
def p_mls_range_def(p):
|
||||||
'''mls_range_def : mls_level_def MINUS mls_level_def
|
'''mls_range_def : mls_level_def MINUS mls_level_def
|
||||||
| mls_level_def
|
| mls_level_def
|
||||||
|
|
|
@ -687,6 +687,15 @@ class PciDeviceCon(Leaf):
|
||||||
def to_string(self):
|
def to_string(self):
|
||||||
return "pcidevicecon %s %s" % (self.device, str(self.context))
|
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
|
# Reference policy specific types
|
||||||
|
|
||||||
def print_tree(head):
|
def print_tree(head):
|
||||||
|
|
Loading…
Reference in a new issue