mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-01-04 17:57:39 +00:00
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:
parent
a9f265a591
commit
3b071116ac
@ -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);
|
||||||
|
@ -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()); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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);
|
||||||
|
@ -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;
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
};
|
};
|
||||||
|
Loading…
x
Reference in New Issue
Block a user