@@ -95,6 +95,8 @@ char *CIL_KEY_TUNABLEIF;
char *CIL_KEY_ALLOW;
char *CIL_KEY_DONTAUDIT;
char *CIL_KEY_TYPETRANSITION;
+char *CIL_KEY_PREFIX;
+char *CIL_KEY_SUFFIX;
char *CIL_KEY_TYPECHANGE;
char *CIL_KEY_CALL;
char *CIL_KEY_TUNABLE;
@@ -264,6 +266,8 @@ static void cil_init_keys(void)
CIL_KEY_ALLOW = cil_strpool_add("allow");
CIL_KEY_DONTAUDIT = cil_strpool_add("dontaudit");
CIL_KEY_TYPETRANSITION = cil_strpool_add("typetransition");
+ CIL_KEY_PREFIX = cil_strpool_add("prefix");
+ CIL_KEY_SUFFIX = cil_strpool_add("suffix");
CIL_KEY_TYPECHANGE = cil_strpool_add("typechange");
CIL_KEY_CALL = cil_strpool_add("call");
CIL_KEY_TUNABLE = cil_strpool_add("tunable");
@@ -2387,6 +2391,8 @@ void cil_nametypetransition_init(struct cil_nametypetransition **nametypetrans)
(*nametypetrans)->obj = NULL;
(*nametypetrans)->name_str = NULL;
(*nametypetrans)->name = NULL;
+ (*nametypetrans)->name_match_str = NULL;
+ (*nametypetrans)->name_match = NAME_TRANS_MATCH_EXACT;
(*nametypetrans)->result_str = NULL;
(*nametypetrans)->result = NULL;
}
@@ -1193,7 +1193,7 @@ static int __cil_typetransition_to_avtab_helper(policydb_t *pdb,
type_datum_t *sepol_src,
type_datum_t *sepol_tgt,
struct cil_list *class_list,
- char *name,
+ char *name, uint8_t name_match,
type_datum_t *sepol_result)
{
int rc;
@@ -1211,7 +1211,7 @@ static int __cil_typetransition_to_avtab_helper(policydb_t *pdb,
avt_key.target_type = sepol_tgt->s.value;
avt_key.target_class = sepol_obj->s.value;
rc = avtab_insert_filename_trans(&pdb->te_avtab, &avt_key,
- sepol_result->s.value, name, NAME_TRANS_MATCH_EXACT,
+ sepol_result->s.value, name, name_match,
&otype);
if (rc != SEPOL_OK) {
if (rc == SEPOL_EEXIST) {
@@ -1280,7 +1280,7 @@ static int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *d
rc = __cil_typetransition_to_avtab_helper(
pdb, sepol_src, sepol_src, class_list,
- name, sepol_result
+ name, typetrans->name_match, sepol_result
);
if (rc != SEPOL_OK) goto exit;
}
@@ -1298,7 +1298,7 @@ static int __cil_typetransition_to_avtab(policydb_t *pdb, const struct cil_db *d
rc = __cil_typetransition_to_avtab_helper(
pdb, sepol_src, sepol_tgt, class_list,
- name, sepol_result
+ name, typetrans->name_match, sepol_result
);
if (rc != SEPOL_OK) goto exit;
}
@@ -3334,10 +3334,11 @@ int cil_gen_typetransition(struct cil_db *db, struct cil_tree_node *parse_curren
CIL_SYN_STRING,
CIL_SYN_STRING,
CIL_SYN_STRING | CIL_SYN_END,
- CIL_SYN_END
+ CIL_SYN_STRING | CIL_SYN_END,
+ CIL_SYN_END,
};
size_t syntax_len = sizeof(syntax)/sizeof(*syntax);
- char *s1, *s2, *s3, *s4, *s5;
+ char *s1, *s2, *s3, *s4, *s5, *s6;
if (db == NULL || parse_current == NULL || ast_node == NULL ) {
goto exit;
@@ -3353,12 +3354,22 @@ int cil_gen_typetransition(struct cil_db *db, struct cil_tree_node *parse_curren
s3 = parse_current->next->next->next->data;
s4 = parse_current->next->next->next->next->data;
s5 = NULL;
+ s6 = NULL;
if (parse_current->next->next->next->next->next) {
if (s4 == CIL_KEY_STAR) {
- s4 = parse_current->next->next->next->next->next->data;
+ if (parse_current->next->next->next->next->next->next) {
+ s4 = parse_current->next->next->next->next->next->next->data;
+ } else {
+ s4 = parse_current->next->next->next->next->next->data;
+ }
} else {
- s5 = parse_current->next->next->next->next->next->data;
+ if (parse_current->next->next->next->next->next->next) {
+ s5 = parse_current->next->next->next->next->next->data;
+ s6 = parse_current->next->next->next->next->next->next->data;
+ } else {
+ s5 = parse_current->next->next->next->next->next->data;
+ }
}
}
@@ -3370,8 +3381,13 @@ int cil_gen_typetransition(struct cil_db *db, struct cil_tree_node *parse_curren
nametypetrans->src_str = s1;
nametypetrans->tgt_str = s2;
nametypetrans->obj_str = s3;
- nametypetrans->result_str = s5;
nametypetrans->name_str = s4;
+ if (s6) {
+ nametypetrans->name_match_str = s5;
+ nametypetrans->result_str = s6;
+ } else {
+ nametypetrans->result_str = s5;
+ }
ast_node->data = nametypetrans;
ast_node->flavor = CIL_NAMETYPETRANSITION;
@@ -726,6 +726,7 @@ int cil_copy_nametypetransition(__attribute__((unused)) struct cil_db *db, void
new->tgt_str = orig->tgt_str;
new->obj_str = orig->obj_str;
new->name_str = orig->name_str;
+ new->name_match_str = orig->name_match_str;
new->result_str = orig->result_str;
@@ -112,6 +112,8 @@ extern char *CIL_KEY_TUNABLEIF;
extern char *CIL_KEY_ALLOW;
extern char *CIL_KEY_DONTAUDIT;
extern char *CIL_KEY_TYPETRANSITION;
+extern char *CIL_KEY_PREFIX;
+extern char *CIL_KEY_SUFFIX;
extern char *CIL_KEY_TYPECHANGE;
extern char *CIL_KEY_CALL;
extern char *CIL_KEY_TUNABLE;
@@ -575,6 +577,8 @@ struct cil_nametypetransition {
struct cil_class *obj;
char *name_str;
struct cil_name *name;
+ char *name_match_str;
+ uint8_t name_match;
char *result_str;
void *result; /* type or alias */
@@ -1260,6 +1260,7 @@ static void cil_nametypetransition_to_policy(FILE *out, struct cil_nametypetrans
struct cil_name *name;
struct cil_list *class_list;
struct cil_list_item *i1;
+ const char *name_match_str = "";
src = trans->src;
tgt = trans->tgt;
@@ -1268,7 +1269,21 @@ static void cil_nametypetransition_to_policy(FILE *out, struct cil_nametypetrans
class_list = cil_expand_class(trans->obj);
cil_list_for_each(i1, class_list) {
- fprintf(out, "type_transition %s %s : %s %s \"%s\";\n", src->fqn, tgt->fqn, DATUM(i1->data)->fqn, res->fqn, name->datum.fqn);
+ switch (trans->name_match) {
+ case NAME_TRANS_MATCH_EXACT:
+ name_match_str = "";
+ break;
+ case NAME_TRANS_MATCH_PREFIX:
+ name_match_str = " PREFIX";
+ break;
+ case NAME_TRANS_MATCH_SUFFIX:
+ name_match_str = " SUFFIX";
+ break;
+ default:
+ name_match_str = "???";
+ break;
+ }
+ fprintf(out, "type_transition %s %s : %s %s \"%s\"%s;\n", src->fqn, tgt->fqn, DATUM(i1->data)->fqn, res->fqn, name->datum.fqn, name_match_str);
}
cil_list_destroy(&class_list, CIL_FALSE);
}
@@ -668,6 +668,16 @@ int cil_resolve_nametypetransition(struct cil_tree_node *current, void *extra_ar
nametypetrans->name = (struct cil_name *)name_datum;
}
+ if (nametypetrans->name_match_str == NULL) {
+ nametypetrans->name_match = NAME_TRANS_MATCH_EXACT;
+ } else if (nametypetrans->name_match_str == CIL_KEY_PREFIX) {
+ nametypetrans->name_match = NAME_TRANS_MATCH_PREFIX;
+ } else if (nametypetrans->name_match_str == CIL_KEY_SUFFIX) {
+ nametypetrans->name_match = NAME_TRANS_MATCH_SUFFIX;
+ } else {
+ cil_tree_log(current, CIL_ERR, "Invalid name match type \"%s\"", nametypetrans->name_match_str);
+ }
+
rc = cil_resolve_name(current, nametypetrans->result_str, CIL_SYM_TYPES, extra_args, &result_datum);
if (rc != SEPOL_OK) {
goto exit;
@@ -1168,6 +1168,8 @@ void cil_write_ast_node(FILE *out, struct cil_tree_node *node)
fprintf(out, "%s ", datum_or_str(DATUM(rule->tgt), rule->tgt_str));
fprintf(out, "%s ", datum_or_str(DATUM(rule->obj), rule->obj_str));
fprintf(out, "\"%s\" ", datum_or_str(DATUM(rule->name), rule->name_str));
+ if (rule->name_match != NAME_TRANS_MATCH_EXACT)
+ fprintf(out, "%s ", rule->name_match_str);
fprintf(out, "%s", datum_or_str(DATUM(rule->result), rule->result_str));
fprintf(out, ")\n");
break;