@@ -84,6 +84,8 @@ char *CIL_KEY_CONS_INCOMP;
char *CIL_KEY_CONDTRUE;
char *CIL_KEY_CONDFALSE;
char *CIL_KEY_SELF;
+char *CIL_KEY_NOTSELF;
+char *CIL_KEY_MINUSSELF;
char *CIL_KEY_OBJECT_R;
char *CIL_KEY_STAR;
char *CIL_KEY_TCP;
@@ -253,6 +255,8 @@ static void cil_init_keys(void)
CIL_KEY_CONDTRUE = cil_strpool_add("true");
CIL_KEY_CONDFALSE = cil_strpool_add("false");
CIL_KEY_SELF = cil_strpool_add("self");
+ CIL_KEY_NOTSELF = cil_strpool_add("notself");
+ CIL_KEY_MINUSSELF = cil_strpool_add("minusself");
CIL_KEY_OBJECT_R = cil_strpool_add("object_r");
CIL_KEY_STAR = cil_strpool_add("*");
CIL_KEY_UDP = cil_strpool_add("udp");
@@ -430,6 +434,12 @@ void cil_db_init(struct cil_db **db)
cil_type_init(&(*db)->selftype);
(*db)->selftype->datum.name = CIL_KEY_SELF;
(*db)->selftype->datum.fqn = CIL_KEY_SELF;
+ cil_type_init(&(*db)->notselftype);
+ (*db)->notselftype->datum.name = CIL_KEY_NOTSELF;
+ (*db)->notselftype->datum.fqn = CIL_KEY_NOTSELF;
+ cil_type_init(&(*db)->minusselftype);
+ (*db)->minusselftype->datum.name = CIL_KEY_MINUSSELF;
+ (*db)->minusselftype->datum.fqn = CIL_KEY_MINUSSELF;
(*db)->num_types_and_attrs = 0;
(*db)->num_classes = 0;
(*db)->num_types = 0;
@@ -483,6 +493,8 @@ void cil_db_destroy(struct cil_db **db)
cil_list_destroy(&(*db)->names, CIL_TRUE);
cil_destroy_type((*db)->selftype);
+ cil_destroy_type((*db)->notselftype);
+ cil_destroy_type((*db)->minusselftype);
cil_strpool_destroy();
free((*db)->val_to_type);
@@ -1519,6 +1519,46 @@ static int __cil_avrule_to_avtab(policydb_t *pdb, const struct cil_db *db, struc
}
}
ebitmap_destroy(&src_bitmap);
+ } else if (tgt->fqn == CIL_KEY_NOTSELF) {
+ rc = __cil_expand_type(src, &src_bitmap);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ ebitmap_for_each_positive_bit(&src_bitmap, snode, s) {
+ src = DATUM(db->val_to_type[s]);
+ for (t = 0; t < (unsigned int)db->num_types; t++) {
+ if (s != t) {
+ tgt = DATUM(db->val_to_type[t]);
+ rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor);
+ if (rc != SEPOL_OK) {
+ ebitmap_destroy(&src_bitmap);
+ goto exit;
+ }
+ }
+ }
+ }
+ ebitmap_destroy(&src_bitmap);
+ } else if (tgt->fqn == CIL_KEY_MINUSSELF) {
+ rc = __cil_expand_type(src, &src_bitmap);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ ebitmap_for_each_positive_bit(&src_bitmap, snode, s) {
+ src = DATUM(db->val_to_type[s]);
+ ebitmap_for_each_positive_bit(&src_bitmap, tnode, t) {
+ if (s != t) {
+ tgt = DATUM(db->val_to_type[t]);
+ rc = __cil_avrule_expand(pdb, kind, src, tgt, classperms, cond_node, cond_flavor);
+ if (rc != SEPOL_OK) {
+ ebitmap_destroy(&src_bitmap);
+ goto exit;
+ }
+ }
+ }
+ }
+ ebitmap_destroy(&src_bitmap);
} else {
int expand_src = __cil_should_expand_attribute(db, src);
int expand_tgt = __cil_should_expand_attribute(db, tgt);
@@ -1875,10 +1915,51 @@ static int cil_avrulex_to_hashtable(policydb_t *pdb, const struct cil_db *db, st
src = DATUM(db->val_to_type[s]);
rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, src, cil_avrulex->perms.x.permx, args);
if (rc != SEPOL_OK) {
+ ebitmap_destroy(&src_bitmap);
goto exit;
}
}
ebitmap_destroy(&src_bitmap);
+ } else if (tgt->fqn == CIL_KEY_NOTSELF) {
+ rc = __cil_expand_type(src, &src_bitmap);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ ebitmap_for_each_positive_bit(&src_bitmap, snode, s) {
+ src = DATUM(db->val_to_type[s]);
+ for (t = 0; t < (unsigned int)db->num_types; t++) {
+ if (s != t) {
+ tgt = DATUM(db->val_to_type[t]);
+ rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args);
+ if (rc != SEPOL_OK) {
+ ebitmap_destroy(&src_bitmap);
+ goto exit;
+ }
+ }
+ }
+ }
+ ebitmap_destroy(&src_bitmap);
+ } else if (tgt->fqn == CIL_KEY_MINUSSELF) {
+ rc = __cil_expand_type(src, &src_bitmap);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ ebitmap_for_each_positive_bit(&src_bitmap, snode, s) {
+ src = DATUM(db->val_to_type[s]);
+ ebitmap_for_each_positive_bit(&src_bitmap, tnode, t) {
+ if (s != t) {
+ tgt = DATUM(db->val_to_type[t]);
+ rc = __cil_avrulex_to_hashtable_helper(pdb, kind, src, tgt, cil_avrulex->perms.x.permx, args);
+ if (rc != SEPOL_OK) {
+ ebitmap_destroy(&src_bitmap);
+ goto exit;
+ }
+ }
+ }
+ }
+ ebitmap_destroy(&src_bitmap);
} else {
int expand_src = __cil_should_expand_attribute(db, src);
int expand_tgt = __cil_should_expand_attribute(db, tgt);
@@ -4813,8 +4894,16 @@ static int cil_check_neverallow(const struct cil_db *db, policydb_t *pdb, struct
if (tgt->fqn == CIL_KEY_SELF) {
rule->flags = RULE_SELF;
+ } else if (tgt->fqn == CIL_KEY_NOTSELF) {
+ rule->flags = RULE_NOTSELF;
+ } else if (tgt->fqn == CIL_KEY_MINUSSELF) {
+ rule->flags = RULE_NOTSELF;
+ rc = __cil_add_sepol_type(pdb, db, cil_rule->src, &rule->ttypes.types);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
} else {
- rc = __cil_add_sepol_type(pdb, db, cil_rule->tgt, &rule->ttypes.types);
+ rc = __cil_add_sepol_type(pdb, db, tgt, &rule->ttypes.types);
if (rc != SEPOL_OK) {
goto exit;
}
@@ -3126,9 +3126,13 @@ int cil_gen_aliasactual(struct cil_db *db, struct cil_tree_node *parse_current,
goto exit;
}
- if ((flavor == CIL_TYPEALIAS && parse_current->next->data == CIL_KEY_SELF) || parse_current->next->next->data == CIL_KEY_SELF) {
- cil_log(CIL_ERR, "The keyword '%s' is reserved\n", CIL_KEY_SELF);
- rc = SEPOL_ERR;
+ rc = cil_verify_name(db, parse_current->next->data, flavor);
+ if (rc != SEPOL_OK) {
+ goto exit;
+ }
+
+ rc = cil_verify_name(db, parse_current->next->next->data, flavor);
+ if (rc != SEPOL_OK) {
goto exit;
}
@@ -115,12 +115,13 @@ static int cil_type_matches(ebitmap_t *matches, struct cil_symtab_datum *d1, str
/* s1 is the src type that is matched with a self
* s2, and t2 are the source and type of the other rule
+ * Assumes there is a match between s1 and s2
*/
static int cil_self_match_any(struct cil_symtab_datum *s1, struct cil_symtab_datum *s2, struct cil_symtab_datum *t2)
{
int rc;
- struct cil_tree_node *n1 = NODE(s1);
- if (n1->flavor != CIL_TYPEATTRIBUTE) {
+
+ if (FLAVOR(s1) != CIL_TYPEATTRIBUTE) {
rc = cil_type_match_any(s1, t2);
} else {
struct cil_typeattribute *a = (struct cil_typeattribute *)s1;
@@ -129,20 +130,149 @@ static int cil_self_match_any(struct cil_symtab_datum *s1, struct cil_symtab_dat
rc = cil_type_matches(&map, s2, t2);
if (rc < 0) {
ebitmap_destroy(&map);
- goto exit;
+ return rc;
}
- if (map.node == NULL) {
- rc = CIL_FALSE;
- goto exit;
+ if (!ebitmap_startnode(&map)) {
+ ebitmap_destroy(&map);
+ return CIL_FALSE;
}
rc = ebitmap_match_any(&map, a->types);
ebitmap_destroy(&map);
}
-exit:
return rc;
}
+/* s1 is the src type that is matched with a notself
+ * s2 and t2 are the source and type of the other rule
+ * Assumes there is a match between s1 and s2
+ */
+static int cil_notself_match_any(struct cil_symtab_datum *s1, struct cil_symtab_datum *s2, struct cil_symtab_datum *t2)
+{
+ int rc;
+ ebitmap_node_t *snode, *tnode;
+ unsigned int s,t;
+
+ if (FLAVOR(s1) != CIL_TYPEATTRIBUTE) {
+ struct cil_type *ts1 = (struct cil_type *)s1;
+ if (FLAVOR(t2) != CIL_TYPEATTRIBUTE) {
+ struct cil_type *tt2 = (struct cil_type *)t2;
+ if (ts1->value != tt2->value) {
+ return CIL_TRUE;
+ }
+ } else {
+ struct cil_typeattribute *at2 = (struct cil_typeattribute *)t2;
+ ebitmap_for_each_positive_bit(at2->types, tnode, t) {
+ if (t != (unsigned int)ts1->value) {
+ return CIL_TRUE;
+ }
+ }
+ }
+ } else {
+ ebitmap_t smap;
+ ebitmap_init(&smap);
+ rc = cil_type_matches(&smap, s1, s2);
+ if (rc < 0) {
+ ebitmap_destroy(&smap);
+ return rc;
+ }
+ if (!ebitmap_startnode(&smap)) {
+ ebitmap_destroy(&smap);
+ return CIL_FALSE;
+ }
+ if (FLAVOR(t2) != CIL_TYPEATTRIBUTE) {
+ struct cil_type *tt2 = (struct cil_type *)t2;
+ ebitmap_for_each_positive_bit(&smap, snode, s) {
+ if (s != (unsigned int)tt2->value) {
+ ebitmap_destroy(&smap);
+ return CIL_TRUE;
+ }
+ }
+ } else {
+ struct cil_typeattribute *at2 = (struct cil_typeattribute *)t2;
+ ebitmap_for_each_positive_bit(&smap, snode, s) {
+ ebitmap_for_each_positive_bit(at2->types, tnode, t) {
+ if (s != t) {
+ ebitmap_destroy(&smap);
+ return CIL_TRUE;
+ }
+ }
+ }
+ }
+ ebitmap_destroy(&smap);
+ }
+
+ return CIL_FALSE;
+}
+
+/* s1 is the src type that is matched with a minusself
+ * s2, and t2 are the source and type of the other rule
+ * Assumes there is a match between s1 and s2
+ */
+static int cil_minusself_match_any(struct cil_symtab_datum *s1, struct cil_symtab_datum *s2, struct cil_symtab_datum *t2)
+{
+ int rc;
+
+ if (FLAVOR(s1) != CIL_TYPEATTRIBUTE) {
+ return CIL_FALSE;
+ } else {
+ ebitmap_t smap, tmap;
+ ebitmap_node_t *snode, *tnode;
+ unsigned int s,t;
+
+ ebitmap_init(&smap);
+ rc = cil_type_matches(&smap, s1, s2);
+ if (rc < 0) {
+ ebitmap_destroy(&smap);
+ return rc;
+ }
+
+ ebitmap_init(&tmap);
+ rc = cil_type_matches(&tmap, s1, t2);
+ if (rc < 0) {
+ ebitmap_destroy(&smap);
+ ebitmap_destroy(&tmap);
+ return rc;
+ }
+
+ if (!ebitmap_startnode(&smap) || !ebitmap_startnode(&tmap)) {
+ ebitmap_destroy(&smap);
+ ebitmap_destroy(&tmap);
+ return CIL_FALSE;
+ }
+
+ ebitmap_for_each_positive_bit(&smap, snode, s) {
+ ebitmap_for_each_positive_bit(&tmap, tnode, t) {
+ if (s != t) {
+ ebitmap_destroy(&smap);
+ ebitmap_destroy(&tmap);
+ return CIL_TRUE;
+ }
+ }
+ }
+
+ ebitmap_destroy(&smap);
+ ebitmap_destroy(&tmap);
+ }
+
+ return CIL_FALSE;
+}
+
+/* s2 is the src type that is matched with a minusself
+ * Assumes there is a match between s1 and s2
+ * s1 is not needed, since it is known that there is a match
+ */
+static int cil_notself_minusself_match_any(struct cil_symtab_datum *s2)
+{
+ if (FLAVOR(s2) == CIL_TYPEATTRIBUTE) {
+ struct cil_typeattribute *as2 = (struct cil_typeattribute *)s2;
+ if (ebitmap_cardinality(as2->types) > 1) {
+ return CIL_TRUE;
+ }
+ }
+ return CIL_FALSE;
+}
+
static int cil_classperms_match_any(struct cil_classperms *cp1, struct cil_classperms *cp2)
{
struct cil_class *c1 = cp1->class;
@@ -308,30 +438,56 @@ static int cil_find_matching_avrule(struct cil_tree_node *node, struct cil_avrul
if (!cil_type_match_any(s1, s2)) goto exit;
- if (t1->fqn != CIL_KEY_SELF && t2->fqn != CIL_KEY_SELF) {
- if (!cil_type_match_any(t1, t2)) goto exit;
- } else {
- if (t1->fqn == CIL_KEY_SELF && t2->fqn == CIL_KEY_SELF) {
+ if (t1->fqn == CIL_KEY_SELF) {
+ if (t2->fqn == CIL_KEY_SELF) {
/* The earlier check whether s1 and s2 matches is all that is needed */
- } else if (t1->fqn == CIL_KEY_SELF) {
+ rc = CIL_TRUE;
+ } else if (t2->fqn == CIL_KEY_NOTSELF || t2->fqn == CIL_KEY_MINUSSELF) {
+ rc = CIL_FALSE;
+ } else {
rc = cil_self_match_any(s1, s2, t2);
- if (rc < 0) {
- goto exit;
- } else if (rc == CIL_FALSE) {
- rc = SEPOL_OK;
- goto exit;
- }
- } else if (t2->fqn == CIL_KEY_SELF) {
+ }
+ } else if (t1->fqn == CIL_KEY_NOTSELF) {
+ if (t2->fqn == CIL_KEY_SELF) {
+ rc = CIL_FALSE;
+ } else if (t2->fqn == CIL_KEY_NOTSELF) {
+ /* The earlier check whether s1 and s2 matches is all that is needed */
+ rc = CIL_TRUE;
+ } else if (t2->fqn == CIL_KEY_MINUSSELF) {
+ rc = cil_notself_minusself_match_any(s2);
+ } else {
+ rc = cil_notself_match_any(s1, s2, t2);
+ }
+ } else if (t1->fqn == CIL_KEY_MINUSSELF) {
+ if (t2->fqn == CIL_KEY_SELF) {
+ rc = CIL_FALSE;
+ } else if (t2->fqn == CIL_KEY_NOTSELF) {
+ rc = cil_notself_minusself_match_any(s1);
+ } else if (t2->fqn == CIL_KEY_MINUSSELF) {
+ /* The earlier check whether s1 and s2 matches is all that is needed */
+ rc = CIL_TRUE;
+ } else {
+ rc = cil_minusself_match_any(s1, s2, t2);
+ }
+ } else {
+ if (t2->fqn == CIL_KEY_SELF) {
rc = cil_self_match_any(s2, s1, t1);
- if (rc < 0) {
- goto exit;
- } else if (rc == CIL_FALSE) {
- rc = SEPOL_OK;
- goto exit;
- }
+ } else if (t2->fqn == CIL_KEY_NOTSELF) {
+ rc = cil_notself_match_any(s2, s1, t1);
+ } else if (t2->fqn == CIL_KEY_MINUSSELF) {
+ rc = cil_minusself_match_any(s2, s1, t1);
+ } else {
+ rc = cil_type_match_any(t1, t2);
}
}
+ if (rc < 0) {
+ goto exit;
+ } else if (rc == CIL_FALSE) {
+ rc = SEPOL_OK;
+ goto exit;
+ }
+
if (!target->is_extended) {
if (cil_classperms_list_match_any(avrule->perms.classperms, target->perms.classperms)) {
cil_list_append(matching, CIL_NODE, node);
@@ -101,6 +101,8 @@ extern char *CIL_KEY_CONS_INCOMP;
extern char *CIL_KEY_CONDTRUE;
extern char *CIL_KEY_CONDFALSE;
extern char *CIL_KEY_SELF;
+extern char *CIL_KEY_NOTSELF;
+extern char *CIL_KEY_MINUSSELF;
extern char *CIL_KEY_OBJECT_R;
extern char *CIL_KEY_STAR;
extern char *CIL_KEY_TCP;
@@ -289,6 +291,8 @@ struct cil_db {
struct cil_tree *parse;
struct cil_tree *ast;
struct cil_type *selftype;
+ struct cil_type *notselftype;
+ struct cil_type *minusselftype;
struct cil_list *sidorder;
struct cil_list *classorder;
struct cil_list *catorder;
@@ -333,6 +333,10 @@ int cil_resolve_avrule(struct cil_tree_node *current, void *extra_args)
if (rule->tgt_str == CIL_KEY_SELF) {
rule->tgt = db->selftype;
+ } else if (rule->tgt_str == CIL_KEY_NOTSELF) {
+ rule->tgt = db->notselftype;
+ } else if (rule->tgt_str == CIL_KEY_MINUSSELF) {
+ rule->tgt = db->minusselftype;
} else {
rc = cil_resolve_name(current, rule->tgt_str, CIL_SYM_TYPES, args, &tgt_datum);
if (rc != SEPOL_OK) {
@@ -68,7 +68,8 @@ static int __cil_is_reserved_name(const char *name, enum cil_flavor flavor)
case CIL_TYPE:
case CIL_TYPEATTRIBUTE:
case CIL_TYPEALIAS:
- if ((name == CIL_KEY_ALL) || (name == CIL_KEY_SELF))
+ if ((name == CIL_KEY_ALL) || (name == CIL_KEY_SELF) || (name == CIL_KEY_NOTSELF)
+ || (name == CIL_KEY_MINUSSELF))
return CIL_TRUE;
break;
case CIL_CAT: