Update magiskpolicy

- Generalize avtab node extraction and insertion
- Add new supported rules: type_change, type_member
- Update help message with official policy language
This commit is contained in:
topjohnwu 2018-11-29 03:46:29 -05:00
parent a9f265a591
commit 3b071116ac
5 changed files with 227 additions and 171 deletions

View File

@ -21,16 +21,6 @@ int sepol_auditdeny(const char *s, const char *t, const char *c, const char *p)
return add_rule(s, t, c, p, AVTAB_AUDITDENY, 0); return add_rule(s, t, c, p, AVTAB_AUDITDENY, 0);
} }
int sepol_typetrans(const char *s, const char *t, const char *c, const char *d, const char *o) {
if (o == nullptr) {
// printf("add_trans %s %s %s %s\n", s, t, c ,d);
return add_transition(s, t, c, d);
} else {
// printf("add_file_trans %s %s %s %s %s\n", s, t, c ,d, o);
return add_file_transition(s, t, c, d, o);
}
}
int sepol_allowxperm(const char *s, const char *t, const char *c, const char *range) { int sepol_allowxperm(const char *s, const char *t, const char *c, const char *range) {
// printf("allowxperm %s %s %s %s\n", s, t, c, range); // printf("allowxperm %s %s %s %s\n", s, t, c, range);
return add_xperm_rule(s, t, c, range, AVTAB_XPERMS_ALLOWED, 0); return add_xperm_rule(s, t, c, range, AVTAB_XPERMS_ALLOWED, 0);
@ -46,6 +36,21 @@ int sepol_dontauditxperm(const char *s, const char *t, const char *c, const char
return add_xperm_rule(s, t, c, range, AVTAB_XPERMS_DONTAUDIT, 0); return add_xperm_rule(s, t, c, range, AVTAB_XPERMS_DONTAUDIT, 0);
} }
int sepol_typetrans(const char *s, const char *t, const char *c, const char *d) {
// printf("type_transition %s %s %s %s\n", s, t, c, d);
return add_type_rule(s, t, c, d, AVTAB_TRANSITION);
}
int sepol_typechange(const char *s, const char *t, const char *c, const char *d) {
// printf("type_change %s %s %s %s\n", s, t, c, d);
return add_type_rule(s, t, c, d, AVTAB_CHANGE);
}
int sepol_typemember(const char *s, const char *t, const char *c, const char *d) {
// printf("type_member %s %s %s %s\n", s, t, c, d);
return add_type_rule(s, t, c, d, AVTAB_MEMBER);
}
int sepol_permissive(const char *s) { int sepol_permissive(const char *s) {
// printf("permissive %s\n", s); // printf("permissive %s\n", s);
return set_domain_state(s, 1); return set_domain_state(s, 1);

View File

@ -14,18 +14,20 @@
static const char *type_msg_1 = static const char *type_msg_1 =
"Type 1:\n" "Type 1:\n"
"\"<action> source-class target-class permission-class permission\"\n" "\"<rule_name> source_type target_type class perm_set\"\n"
"Action: allow, deny, auditallow, auditdeny\n"; "Rules: allow, deny, auditallow, auditdeny\n";
static const char *type_msg_2 = static const char *type_msg_2 =
"Type 2:\n" "Type 2:\n"
"\"<action> source-class target-class permission-class ioctl range\"\n" "\"<rule_name> source_type target_type class operation xperm_set\"\n"
"Action: allowxperm, auditallowxperm, dontauditxperm\n"; "Rules: allowxperm, auditallowxperm, dontauditxperm\n"
"* The only supported operation is ioctl\n"
"* The only supported xperm_set format is range ([low-high])\n";
static const char *type_msg_3 = static const char *type_msg_3 =
"Type 3:\n" "Type 3:\n"
"\"<action> class\"\n" "\"<rule_name> class\"\n"
"Action: create, permissive, enforcing\n"; "Rules: create, permissive, enforcing\n";
static const char *type_msg_4 = static const char *type_msg_4 =
"Type 4:\n" "Type 4:\n"
@ -33,7 +35,12 @@ static const char *type_msg_4 =
static const char *type_msg_5 = static const char *type_msg_5 =
"Type 5:\n" "Type 5:\n"
"\"typetrans source-class target-class permission-class default-class (optional: object-name)\"\n"; "\"<rule_name> source_type target_type class default_type\"\n"
"Rules: type_transition, type_change, type_member\n";
static const char *type_msg_6 =
"Type 6:\n"
"\"name_transition source_type target_type class default_type object_name\"\n";
[[noreturn]] static void statements() { [[noreturn]] static void statements() {
@ -42,9 +49,10 @@ static const char *type_msg_5 =
"this means a full policy statement should be enclosed in quotes;\n" "this means a full policy statement should be enclosed in quotes;\n"
"multiple policy statements can be provided in a single command\n" "multiple policy statements can be provided in a single command\n"
"\n" "\n"
"The statements has a format of \"<action> [args...]\"\n" "The statements has a format of \"<rule_name> [args...]\"\n"
"Use '*' in args to represent every possible match.\n" "Multiple types and permissions can be grouped into collections\n"
"Collections wrapped in curly brackets can also be used as args.\n" "wrapped in curly brackets.\n"
"'*' represents a collection containing all valid matches.\n"
"\n" "\n"
"Supported policy statements:\n" "Supported policy statements:\n"
"\n" "\n"
@ -53,20 +61,21 @@ static const char *type_msg_5 =
"%s\n" "%s\n"
"%s\n" "%s\n"
"%s\n" "%s\n"
"%s\n"
"Notes:\n" "Notes:\n"
"- typetrans does not support the all match '*' syntax\n" "* Type 4 - 6 does not support collections\n"
"- permission-class cannot be collections\n" "* Object classes cannot be collections\n"
"- source-class and target-class can also be attributes\n" "* source_type and target_type can also be attributes\n"
"\n" "\n"
"Example: allow { source1 source2 } { target1 target2 } permission-class *\n" "Example: allow { s1 s2 } { t1 t2 } class *\n"
"Will be expanded to:\n" "Will be expanded to:\n"
"\n" "\n"
"allow source1 target1 permission-class { all-permissions }\n" "allow s1 t1 class { all permissions }\n"
"allow source1 target2 permission-class { all-permissions }\n" "allow s1 t2 class { all permissions }\n"
"allow source2 target1 permission-class { all-permissions }\n" "allow s2 t1 class { all permissions }\n"
"allow source2 target2 permission-class { all-permissions }\n" "allow s2 t2 class { all permissions }\n"
"\n", "\n",
type_msg_1, type_msg_2, type_msg_3, type_msg_4, type_msg_5); type_msg_1, type_msg_2, type_msg_3, type_msg_4, type_msg_5, type_msg_6);
exit(0); exit(0);
} }
@ -207,6 +216,8 @@ static int parse_pattern_2(int action, const char *action_str, char *stmt) {
break; break;
case 3: case 3:
// Currently only support ioctl // Currently only support ioctl
if (strcmp(cur, "ioctl"))
return 1;
vec = nullptr; vec = nullptr;
break; break;
case 4: case 4:
@ -310,11 +321,25 @@ static int parse_pattern_4(int action, const char *action_str, char *stmt) {
return 0; return 0;
} }
// Pattern 5: action source target class default (filename) // Pattern 5: action source target class default
static int parse_pattern_5(int action, const char *action_str, char *stmt) { static int parse_pattern_5(int action, const char *action_str, char *stmt) {
int (*action_func)(const char*, const char*, const char*, const char*);
switch (action) {
case 0:
action_func = sepol_typetrans;
break;
case 1:
action_func = sepol_typechange;
break;
case 2:
action_func = sepol_typemember;
break;
default:
return 1;
}
int state = 0; int state = 0;
char *cur; char *cur;
char *source, *target, *cls, *def, *filename = nullptr; char *source, *target, *cls, *def;
while ((cur = strtok_r(nullptr, " ", &stmt)) != nullptr) { while ((cur = strtok_r(nullptr, " ", &stmt)) != nullptr) {
switch(state) { switch(state) {
case 0: case 0:
@ -329,18 +354,48 @@ static int parse_pattern_5(int action, const char *action_str, char *stmt) {
case 3: case 3:
def = cur; def = cur;
break; break;
case 4:
filename = cur;
break;
default: default:
return 1; return 1;
} }
++state; ++state;
} }
if (state < 4) return 1; if (state < 4) return 1;
if (sepol_typetrans(source, target, cls, def, filename)) if (action_func(source, target, cls, def))
fprintf(stderr, "Error in: %s %s %s %s %s\n", action_str, source, target, cls, def);
return 0;
}
// Pattern 6: action source target class default filename
static int parse_pattern_6(int action, const char *action_str, char *stmt) {
int state = 0;
char *cur;
char *source, *target, *cls, *def, *filename;
while ((cur = strtok_r(nullptr, " ", &stmt)) != nullptr) {
switch(state) {
case 0:
source = cur;
break;
case 1:
target = cur;
break;
case 2:
cls = cur;
break;
case 3:
def = cur;
break;
case 4:
filename = cur;
break;
default:
return 1;
}
++state;
}
if (state < 4) return 1;
if (sepol_nametrans(source, target, cls, def, filename))
fprintf(stderr, "Error in: %s %s %s %s %s %s\n", fprintf(stderr, "Error in: %s %s %s %s %s %s\n",
action_str, source, target, cls, def, filename ? filename : ""); action_str, source, target, cls, def, filename);
return 0; return 0;
} }
@ -371,7 +426,10 @@ static void parse_statement(char *statement) {
add_action("permissive", 3, 1) add_action("permissive", 3, 1)
add_action("enforce", 3, 2) add_action("enforce", 3, 2)
add_action("attradd", 4, 0) add_action("attradd", 4, 0)
add_action("typetrans", 5, 0) add_action("type_transition", 5, 0)
add_action("type_change", 5, 1)
add_action("type_member", 5, 2)
add_action("name_transition", 6, 0)
else { fprintf(stderr, "Unknown statement: '%s'\n\n", orig.c_str()); } else { fprintf(stderr, "Unknown statement: '%s'\n\n", orig.c_str()); }
} }

View File

@ -31,7 +31,10 @@ int sepol_allow(const char *s, const char *t, const char *c, const char *p);
int sepol_deny(const char *s, const char *t, const char *c, const char *p); int sepol_deny(const char *s, const char *t, const char *c, const char *p);
int sepol_auditallow(const char *s, const char *t, const char *c, const char *p); int sepol_auditallow(const char *s, const char *t, const char *c, const char *p);
int sepol_auditdeny(const char *s, const char *t, const char *c, const char *p); int sepol_auditdeny(const char *s, const char *t, const char *c, const char *p);
int sepol_typetrans(const char *s, const char *t, const char *c, const char *d, const char *o); int sepol_typetrans(const char *s, const char *t, const char *c, const char *d);
int sepol_typechange(const char *s, const char *t, const char *c, const char *d);
int sepol_typemember(const char *s, const char *t, const char *c, const char *d);
int sepol_nametrans(const char *s, const char *t, const char *c, const char *d, const char *o);
int sepol_allowxperm(const char *s, const char *t, const char *c, const char *range); int sepol_allowxperm(const char *s, const char *t, const char *c, const char *range);
int sepol_auditallowxperm(const char *s, const char *t, const char *c, const char *range); int sepol_auditallowxperm(const char *s, const char *t, const char *c, const char *range);
int sepol_dontauditxperm(const char *s, const char *t, const char *c, const char *range); int sepol_dontauditxperm(const char *s, const char *t, const char *c, const char *range);

View File

@ -27,15 +27,6 @@
policydb_t *policydb = NULL; policydb_t *policydb = NULL;
extern int policydb_index_decls(sepol_handle_t * handle, policydb_t * p); extern int policydb_index_decls(sepol_handle_t * handle, policydb_t * p);
static void *cmalloc(size_t s) {
void *t = calloc(s, 1);
if (t == NULL) {
LOGE("Out of memory\n");
exit(1);
}
return t;
}
static int get_attr(const char *type, int value) { static int get_attr(const char *type, int value) {
type_datum_t *attr = hashtab_search(policydb->p_types.table, type); type_datum_t *attr = hashtab_search(policydb->p_types.table, type);
if (!attr) if (!attr)
@ -44,7 +35,7 @@ static int get_attr(const char *type, int value) {
if (attr->flavor != TYPE_ATTRIB) if (attr->flavor != TYPE_ATTRIB)
return 1; return 1;
return !! ebitmap_get_bit(&policydb->attr_type_map[attr->s.value-1], value-1); return ebitmap_get_bit(&policydb->attr_type_map[attr->s.value - 1], value - 1) != 0;
} }
static int get_attr_id(const char *type) { static int get_attr_id(const char *type) {
@ -74,46 +65,62 @@ static int set_attr(const char *type, int value) {
return 0; return 0;
} }
static int __add_rule(int s, int t, int c, int p, int effect, int not) { static avtab_ptr_t get_avtab_node(avtab_key_t *key, avtab_extended_perms_t *xperms) {
avtab_key_t key; avtab_ptr_t node;
avtab_datum_t *av; avtab_datum_t avdatum;
int new_rule = 0; int match = 0;
key.source_type = s; /* AVTAB_XPERMS entries are not necessarily unique */
key.target_type = t; if (key->specified & AVTAB_XPERMS) {
key.target_class = c; node = avtab_search_node(&policydb->te_avtab, key);
key.specified = effect; while (node) {
if ((node->datum.xperms->specified == xperms->specified) &&
av = avtab_search(&policydb->te_avtab, &key); (node->datum.xperms->driver == xperms->driver)) {
if (av == NULL) { match = 1;
av = cmalloc(sizeof(*av)); break;
new_rule = 1; }
node = avtab_search_node_next(node, key->specified);
}
if (!match)
node = NULL;
} else {
node = avtab_search_node(&policydb->te_avtab, key);
} }
if (!node) {
memset(&avdatum, 0, sizeof avdatum);
/*
* AUDITDENY, aka DONTAUDIT, are &= assigned, versus |= for
* others. Initialize the data accordingly.
*/
avdatum.data = key->specified == AVTAB_AUDITDENY ? ~0U : 0U;
/* this is used to get the node - insertion is actually unique */
node = avtab_insert_nonunique(&policydb->te_avtab, key, &avdatum);
}
return node;
}
static int add_avrule(avtab_key_t *key, int p, int not) {
avtab_datum_t *datum = &get_avtab_node(key, NULL)->datum;
if(not) { if(not) {
if (p < 0) if (p < 0)
av->data = 0U; datum->data = 0U;
else else
av->data &= ~(1U << (p - 1)); datum->data &= ~(1U << (p - 1));
} else { } else {
if (p < 0) if (p < 0)
av->data = ~0U; datum->data = ~0U;
else else
av->data |= 1U << (p - 1); datum->data |= 1U << (p - 1);
}
if (new_rule) {
if (avtab_insert(&policydb->te_avtab, &key, av)) {
LOGW("Error inserting into avtab\n");
return 1;
}
free(av);
} }
return 0; return 0;
} }
static int add_rule_auto(type_datum_t *src, type_datum_t *tgt, class_datum_t *cls, perm_datum_t *perm, int effect, int not) { static int add_rule_auto(type_datum_t *src, type_datum_t *tgt, class_datum_t *cls,
perm_datum_t *perm, int effect, int not) {
avtab_key_t key;
hashtab_ptr_t cur; hashtab_ptr_t cur;
int ret = 0; int ret = 0;
@ -130,10 +137,14 @@ static int add_rule_auto(type_datum_t *src, type_datum_t *tgt, class_datum_t *cl
} else if (cls == NULL) { } else if (cls == NULL) {
hashtab_for_each(policydb->p_classes.table, &cur) { hashtab_for_each(policydb->p_classes.table, &cur) {
cls = cur->datum; cls = cur->datum;
ret |= __add_rule(src->s.value, tgt->s.value, cls->s.value, -1, effect, not); ret |= add_rule_auto(src, tgt, cls, perm, effect, not);
} }
} else { } else {
return __add_rule(src->s.value, tgt->s.value, cls->s.value, perm ? perm->s.value : -1, effect, not); key.source_type = src->s.value;
key.target_type = tgt->s.value;
key.target_class = cls->s.value;
key.specified = effect;
return add_avrule(&key, perm ? perm->s.value : -1, not);
} }
return ret; return ret;
} }
@ -141,59 +152,47 @@ static int add_rule_auto(type_datum_t *src, type_datum_t *tgt, class_datum_t *cl
#define ioctl_driver(x) (x>>8 & 0xFF) #define ioctl_driver(x) (x>>8 & 0xFF)
#define ioctl_func(x) (x & 0xFF) #define ioctl_func(x) (x & 0xFF)
static int __add_xperm_rule(int s, int t, int c, uint16_t low, uint16_t high, int effect, int not) { static int add_avxrule(avtab_key_t *key, uint16_t low, uint16_t high, int not) {
avtab_key_t key; avtab_datum_t *datum;
avtab_datum_t *av; avtab_extended_perms_t xperms;
int new_rule = 0;
key.source_type = s; memset(&xperms, 0, sizeof(xperms));
key.target_type = t; if (ioctl_driver(low) != ioctl_driver(high)) {
key.target_class = c; xperms.specified = AVTAB_XPERMS_IOCTLDRIVER;
key.specified = effect; xperms.driver = 0;
} else {
av = avtab_search(&policydb->te_avtab, &key); xperms.specified = AVTAB_XPERMS_IOCTLFUNCTION;
if (av == NULL) { xperms.driver = ioctl_driver(low);
av = cmalloc(sizeof(*av));
av->xperms = cmalloc(sizeof(avtab_extended_perms_t));
new_rule = 1;
if (ioctl_driver(low) != ioctl_driver(high)) {
av->xperms->specified = AVTAB_XPERMS_IOCTLDRIVER;
av->xperms->driver = 0;
} else {
av->xperms->specified = AVTAB_XPERMS_IOCTLFUNCTION;
av->xperms->driver = ioctl_driver(low);
}
} }
if (av->xperms->specified == AVTAB_XPERMS_IOCTLDRIVER) { if (xperms.specified == AVTAB_XPERMS_IOCTLDRIVER) {
for (unsigned i = ioctl_driver(low); i <= ioctl_driver(high); ++i) { for (int i = ioctl_driver(low); i <= ioctl_driver(high); ++i) {
if (not) if (not)
xperm_clear(i, av->xperms->perms); xperm_clear(i, xperms.perms);
else else
xperm_set(i, av->xperms->perms); xperm_set(i, xperms.perms);
} }
} else { } else {
for (unsigned i = ioctl_func(low); i <= ioctl_func(high); ++i) { for (int i = ioctl_func(low); i <= ioctl_func(high); ++i) {
if (not) if (not)
xperm_clear(i, av->xperms->perms); xperm_clear(i, xperms.perms);
else else
xperm_set(i, av->xperms->perms); xperm_set(i, xperms.perms);
} }
} }
if (new_rule) { datum = &get_avtab_node(key, &xperms)->datum;
if (avtab_insert(&policydb->te_avtab, &key, av)) {
LOGW("Error inserting into avtab\n");
return 1;
}
free(av);
}
if (datum->xperms == NULL)
datum->xperms = xmalloc(sizeof(xperms));
memcpy(datum->xperms, &xperms, sizeof(xperms));
return 0; return 0;
} }
static int add_xperm_rule_auto(type_datum_t *src, type_datum_t *tgt, class_datum_t *cls, static int add_xperm_rule_auto(type_datum_t *src, type_datum_t *tgt, class_datum_t *cls,
uint16_t low, uint16_t high, int effect, int not) { uint16_t low, uint16_t high, int effect, int not) {
avtab_key_t key;
hashtab_ptr_t cur; hashtab_ptr_t cur;
int ret = 0; int ret = 0;
@ -210,10 +209,14 @@ static int add_xperm_rule_auto(type_datum_t *src, type_datum_t *tgt, class_datum
} else if (cls == NULL) { } else if (cls == NULL) {
hashtab_for_each(policydb->p_classes.table, &cur) { hashtab_for_each(policydb->p_classes.table, &cur) {
cls = cur->datum; cls = cur->datum;
ret |= __add_xperm_rule(src->s.value, tgt->s.value, cls->s.value, low, high, effect, not); ret |= add_xperm_rule_auto(src, tgt, cls, low, high, effect, not);
} }
} else { } else {
return __add_xperm_rule(src->s.value, tgt->s.value, cls->s.value, low, high, effect, not); key.source_type = src->s.value;
key.target_type = tgt->s.value;
key.target_class = cls->s.value;
key.specified = effect;
return add_avxrule(&key, low, high, not);
} }
return ret; return ret;
} }
@ -227,7 +230,7 @@ int load_policydb(const char *filename) {
if (policydb) if (policydb)
destroy_policydb(); destroy_policydb();
policydb = cmalloc(sizeof(*policydb)); policydb = xcalloc(sizeof(*policydb), 1);
mmap_ro(filename, &map, &size); mmap_ro(filename, &map, &size);
@ -417,59 +420,7 @@ int set_domain_state(const char *s, int state) {
return 0; return 0;
} }
int add_transition(const char *s, const char *t, const char *c, const char *d) { int sepol_nametrans(const char *s, const char *t, const char *c, const char *d, const char *o) {
type_datum_t *src, *tgt, *def;
class_datum_t *cls;
avtab_key_t key;
avtab_datum_t *av;
int new_rule = 0;
src = hashtab_search(policydb->p_types.table, s);
if (src == NULL) {
LOGW("source type %s does not exist\n", s);
return 1;
}
tgt = hashtab_search(policydb->p_types.table, t);
if (tgt == NULL) {
LOGW("target type %s does not exist\n", t);
return 1;
}
cls = hashtab_search(policydb->p_classes.table, c);
if (cls == NULL) {
LOGW("class %s does not exist\n", c);
return 1;
}
def = hashtab_search(policydb->p_types.table, d);
if (def == NULL) {
LOGW("default type %s does not exist\n", d);
return 1;
}
key.source_type = src->s.value;
key.target_type = tgt->s.value;
key.target_class = cls->s.value;
key.specified = AVTAB_TRANSITION;
av = avtab_search(&policydb->te_avtab, &key);
if (av == NULL) {
av = cmalloc(sizeof(*av));
new_rule = 1;
}
av->data = def->s.value;
if (new_rule) {
if (avtab_insert(&policydb->te_avtab, &key, av)) {
LOGW("Error inserting into avtab\n");
return 1;
}
free(av);
}
return 0;
}
int add_file_transition(const char *s, const char *t, const char *c, const char *d,
const char *filename) {
type_datum_t *src, *tgt, *def; type_datum_t *src, *tgt, *def;
class_datum_t *cls; class_datum_t *cls;
@ -498,13 +449,13 @@ int add_file_transition(const char *s, const char *t, const char *c, const char
trans_key.stype = src->s.value; trans_key.stype = src->s.value;
trans_key.ttype = tgt->s.value; trans_key.ttype = tgt->s.value;
trans_key.tclass = cls->s.value; trans_key.tclass = cls->s.value;
trans_key.name = (char *) filename; trans_key.name = (char *) o;
filename_trans_datum_t *trans_datum; filename_trans_datum_t *trans_datum;
trans_datum = hashtab_search(policydb->p_types.table, (hashtab_key_t) &trans_key); trans_datum = hashtab_search(policydb->p_types.table, (hashtab_key_t) &trans_key);
if (trans_datum == NULL) { if (trans_datum == NULL) {
trans_datum = cmalloc(sizeof(*trans_datum)); trans_datum = xcalloc(sizeof(*trans_datum), 1);
hashtab_insert(policydb->filename_trans, (hashtab_key_t) &trans_key, trans_datum); hashtab_insert(policydb->filename_trans, (hashtab_key_t) &trans_key, trans_datum);
} }
@ -634,3 +585,42 @@ int add_xperm_rule(const char *s, const char *t, const char *c, const char *rang
return add_xperm_rule_auto(src, tgt, cls, low, high, effect, n); return add_xperm_rule_auto(src, tgt, cls, low, high, effect, n);
} }
int add_type_rule(const char *s, const char *t, const char *c, const char *d, int effect) {
type_datum_t *src, *tgt, *def;
class_datum_t *cls;
avtab_key_t key;
avtab_datum_t *av;
src = hashtab_search(policydb->p_types.table, s);
if (src == NULL) {
LOGW("source type %s does not exist\n", s);
return 1;
}
tgt = hashtab_search(policydb->p_types.table, t);
if (tgt == NULL) {
LOGW("target type %s does not exist\n", t);
return 1;
}
cls = hashtab_search(policydb->p_classes.table, c);
if (cls == NULL) {
LOGW("class %s does not exist\n", c);
return 1;
}
def = hashtab_search(policydb->p_types.table, d);
if (def == NULL) {
LOGW("default type %s does not exist\n", d);
return 1;
}
key.source_type = src->s.value;
key.target_type = tgt->s.value;
key.target_class = cls->s.value;
key.specified = effect;
av = &get_avtab_node(&key, NULL)->datum;
av->data = def->s.value;
return 0;
}

View File

@ -21,12 +21,12 @@ extern policydb_t *policydb;
// sepolicy manipulation functions // sepolicy manipulation functions
int create_domain(const char *d); int create_domain(const char *d);
int set_domain_state(const char *s, int state); int set_domain_state(const char *s, int state);
int add_transition(const char *s, const char *t, const char *c, const char *d);
int add_file_transition(const char *s, const char *t, const char *c, const char *d, int add_file_transition(const char *s, const char *t, const char *c, const char *d,
const char *filename); const char *o);
int add_typeattribute(const char *domainS, const char *attr); int add_typeattribute(const char *domainS, const char *attr);
int add_rule(const char *s, const char *t, const char *c, const char *p, int effect, int n); int add_rule(const char *s, const char *t, const char *c, const char *p, int effect, int n);
int add_xperm_rule(const char *s, const char *t, const char *c, const char *range, int effect, int n); int add_xperm_rule(const char *s, const char *t, const char *c, const char *range, int effect, int n);
int add_type_rule(const char *s, const char *t, const char *c, const char *d, int effect);
#ifdef __cplusplus #ifdef __cplusplus
}; };