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:
Daniel De Graaf 2015-03-17 16:43:24 -04:00 committed by Stephen Smalley
parent 82030de5dc
commit f029067709
22 changed files with 379 additions and 5 deletions

View file

@ -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;

View file

@ -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);

View file

@ -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
| |
; ;

View file

@ -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 |

View file

@ -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));

View file

@ -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:

View file

@ -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;

View file

@ -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);

View file

@ -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;

View file

@ -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,

View file

@ -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);

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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: ");

View file

@ -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;

View file

@ -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

View file

@ -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");

View file

@ -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");

View file

@ -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;
} }
} }
} }

View file

@ -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

View file

@ -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):