Integrate with unified daemon

This commit is contained in:
topjohnwu 2017-04-16 02:29:42 +08:00
parent 838b2757eb
commit a65c7ee2fc
6 changed files with 174 additions and 146 deletions

17
api.c
View File

@ -2,44 +2,55 @@
#include "sepolicy.h" #include "sepolicy.h"
int sepol_allow(char *s, char *t, char *c, char *p) { int sepol_allow(char *s, char *t, char *c, char *p) {
// printf("allow %s %s %s %s\n", s, t, c, p);
return add_rule(s, t, c, p, AVTAB_ALLOWED, 0); return add_rule(s, t, c, p, AVTAB_ALLOWED, 0);
} }
int sepol_deny(char *s, char *t, char *c, char *p) { int sepol_deny(char *s, char *t, char *c, char *p) {
// printf("deny %s %s %s %s\n", s, t, c, p);
return add_rule(s, t, c, p, AVTAB_ALLOWED, 1); return add_rule(s, t, c, p, AVTAB_ALLOWED, 1);
} }
int sepol_auditallow(char *s, char *t, char *c, char *p) { int sepol_auditallow(char *s, char *t, char *c, char *p) {
// printf("auditallow %s %s %s %s\n", s, t, c, p);
return add_rule(s, t, c, p, AVTAB_AUDITALLOW, 0); return add_rule(s, t, c, p, AVTAB_AUDITALLOW, 0);
} }
int sepol_auditdeny(char *s, char *t, char *c, char *p) { int sepol_auditdeny(char *s, char *t, char *c, char *p) {
// printf("auditdeny %s %s %s %s\n", s, t, c, p);
return add_rule(s, t, c, p, AVTAB_AUDITDENY, 0); return add_rule(s, t, c, p, AVTAB_AUDITDENY, 0);
} }
int sepol_typetrans(char *s, char *t, char *c, char *d, char *o) { int sepol_typetrans(char *s, char *t, char *c, char *d, char *o) {
if (o == NULL) if (o == NULL) {
// printf("add_trans %s %s %s %s\n", s, t, c ,d);
return add_transition(s, t, c, d); return add_transition(s, t, c, d);
else } 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); return add_file_transition(s, t, c, d, o);
} }
}
int sepol_permissive(char *s) { int sepol_permissive(char *s) {
// printf("permissive %s\n", s);
return set_domain_state(s, 1); return set_domain_state(s, 1);
} }
int sepol_enforce(char *s) { int sepol_enforce(char *s) {
// printf("enforce %s\n", s);
return set_domain_state(s, 0); return set_domain_state(s, 0);
} }
int sepol_create(char *s) { int sepol_create(char *s) {
// printf("create %s\n", s);
return create_domain(s); return create_domain(s);
} }
int sepol_attradd(char *s, char *a) { int sepol_attradd(char *s, char *a) {
// printf("attradd %s %s\n", s, a);
return add_typeattribute(s, a); return add_typeattribute(s, a);
} }
int sepol_exists(char* source) { int sepol_exists(char* source) {
return !! hashtab_search(policy->p_types.table, source); return !! hashtab_search(policydb->p_types.table, source);
} }

View File

@ -53,10 +53,10 @@ static void usage(char *arg0) {
"%s [--options...] [policystatements...]\n\n" "%s [--options...] [policystatements...]\n\n"
"Options:\n" "Options:\n"
" --live: directly load patched policy to device\n" " --live: directly load patched policy to device\n"
" --magisk: complete (very large!) patches for Magisk and MagiskSU\n" // " --magisk: complete (very large!) patches for Magisk and MagiskSU\n"
" --minimal: minimal patches, used for boot image patches\n" " --minimal: minimal patches, used for boot image patches\n"
" --load <infile>: load policies from <infile>\n" " --load <infile>: load policies from <infile>\n"
" (load from current policies if not specified)" " (load from current policies if not specified)\n"
" --save <outfile>: save policies to <outfile>\n" " --save <outfile>: save policies to <outfile>\n"
, arg0); , arg0);
statements(); statements();
@ -270,7 +270,7 @@ static void syntax_error_msg() {
int magiskpolicy_main(int argc, char *argv[]) { int magiskpolicy_main(int argc, char *argv[]) {
char *infile = NULL, *outfile = NULL, *tok, *saveptr; char *infile = NULL, *outfile = NULL, *tok, *saveptr;
int live = 0, minimal = 0, full = 0; int live = 0, minimal = 0;
struct vector rules; struct vector rules;
vec_init(&rules); vec_init(&rules);
@ -280,8 +280,6 @@ int magiskpolicy_main(int argc, char *argv[]) {
if (argv[i][0] == '-' && argv[i][1] == '-') { if (argv[i][0] == '-' && argv[i][1] == '-') {
if (strcmp(argv[i], "--live") == 0) if (strcmp(argv[i], "--live") == 0)
live = 1; live = 1;
else if (strcmp(argv[i], "--magisk") == 0)
full = 1;
else if (strcmp(argv[i], "--minimal") == 0) else if (strcmp(argv[i], "--minimal") == 0)
minimal = 1; minimal = 1;
else if (strcmp(argv[i], "--load") == 0) { else if (strcmp(argv[i], "--load") == 0) {
@ -298,28 +296,17 @@ int magiskpolicy_main(int argc, char *argv[]) {
vec_push_back(&rules, argv[i]); vec_push_back(&rules, argv[i]);
} }
policydb_t policydb;
sidtab_t sidtab;
policy = &policydb;
// Use current policy if not specified // Use current policy if not specified
if(!infile) if(!infile)
infile = "/sys/fs/selinux/policy"; infile = "/sys/fs/selinux/policy";
sepol_set_policydb(&policydb); if (load_policydb(infile)) {
sepol_set_sidtab(&sidtab);
if (load_policy(infile)) {
fprintf(stderr, "Could not load policy\n"); fprintf(stderr, "Could not load policy\n");
return 1; return 1;
} }
if (policydb_load_isids(&policydb, &sidtab)) if (minimal)
return 1; sepol_min_rules();
if (full) sepol_full_rules();
else if (minimal) sepol_min_rules();
for (int i = 0; i < rules.size; ++i) { for (int i = 0; i < rules.size; ++i) {
// Since strtok will modify the origin string, copy the policy for error messages // Since strtok will modify the origin string, copy the policy for error messages
@ -363,15 +350,15 @@ int magiskpolicy_main(int argc, char *argv[]) {
vec_destroy(&rules); vec_destroy(&rules);
if (live) if (live)
if (dump_policy("/sys/fs/selinux/load")) if (dump_policydb("/sys/fs/selinux/load"))
return 1; return 1;
if (outfile) { if (outfile) {
unlink(outfile); unlink(outfile);
if (dump_policy(outfile)) if (dump_policydb(outfile))
return 1; return 1;
} }
policydb_destroy(&policydb); destroy_policydb();
return 0; return 0;
} }

View File

@ -8,6 +8,11 @@
#define ALL NULL #define ALL NULL
// policydb functions
int load_policydb(const char *filename);
int dump_policydb(const char *filename);
void destroy_policydb();
// Handy functions // Handy functions
int sepol_allow(char *s, char *t, char *c, char *p); int sepol_allow(char *s, char *t, char *c, char *p);
int sepol_deny(char *s, char *t, char *c, char *p); int sepol_deny(char *s, char *t, char *c, char *p);
@ -21,7 +26,8 @@ int sepol_attradd(char *s, char *a);
int sepol_exists(char *source); int sepol_exists(char *source);
// Built in rules // Built in rules
void sepol_full_rules();
void sepol_min_rules(); void sepol_min_rules();
void sepol_med_rules();
void sepol_full_rules();
#endif #endif

123
rules.c
View File

@ -65,14 +65,16 @@ void samsung() {
} }
void allowSuClient(char *target) { void allowSuClient(char *target) {
sepol_allow(target, "rootfs", "file", "execute_no_trans"); sepol_allow(target, "rootfs", "file", ALL);
sepol_allow(target, "rootfs", "file", "execute"); sepol_allow(target, "rootfs", "lnk_file", ALL);
sepol_allow(target, "su", "unix_stream_socket", "connectto"); sepol_allow(target, "su", "unix_stream_socket", "connectto");
sepol_allow(target, "su", "unix_stream_socket", "getopt"); sepol_allow(target, "su", "unix_stream_socket", "getopt");
sepol_allow(target, "su_device", "dir", "search"); sepol_allow(target, "su_device", "dir", "search");
sepol_allow(target, "su_device", "dir", "read"); sepol_allow(target, "su_device", "dir", "read");
sepol_allow(target, "su_device", "sock_file", "read"); sepol_allow(target, "su_device", "sock_file", "read");
sepol_allow(target, "su_device", "sock_file", "write"); sepol_allow(target, "su_device", "sock_file", "write");
sepol_allow("su", target, "fd", "use");
sepol_allow("su", target, "fifo_file", ALL);
} }
void suRights() { void suRights() {
@ -83,6 +85,16 @@ void suRights() {
sepol_allow("servicemanager", "su", "process", "getattr"); sepol_allow("servicemanager", "su", "process", "getattr");
sepol_allow("servicemanager", "su", "binder", "transfer"); sepol_allow("servicemanager", "su", "binder", "transfer");
sepol_allow("system_server", "su", "binder", "call"); sepol_allow("system_server", "su", "binder", "call");
sepol_allow("su", "servicemanager", "dir", "search");
sepol_allow("su", "servicemanager", "dir", "read");
sepol_allow("su", "servicemanager", "file", "open");
sepol_allow("su", "servicemanager", "file", "read");
sepol_allow("su", "servicemanager", "process", "getattr");
sepol_allow("su", "servicemanager", "binder", "transfer");
sepol_allow("su", "servicemanager", "binder", "call");
sepol_allow("su", "system_server", "binder", "transfer");
sepol_allow("su", "system_server", "binder", "call");
} }
void otherToSU() { void otherToSU() {
@ -129,61 +141,17 @@ void otherToSU() {
sepol_allow("audioserver", "audioserver", "process", "execmem"); sepol_allow("audioserver", "audioserver", "process", "execmem");
} }
void sepol_full_rules() { // Minimal boot image patch, Samsung requires these patches
// Samsung specific
// Prevent system from loading policy
if(sepol_exists("knox_system_app"))
samsung();
// Min rules first
sepol_min_rules();
// Create domains if they don't exist
if (!sepol_exists("su_device"))
sepol_create("su_device");
sepol_enforce("su_device");
// Patch su to everything
sepol_allow("su", ALL, ALL, ALL);
// Autotransition su's socket to su_device
sepol_typetrans("su", "device", "file", "su_device", NULL);
sepol_typetrans("su", "device", "dir", "su_device", NULL);
sepol_allow("su_device", "tmpfs", "filesystem", "associate");
// Transition from untrusted_app to su_client
allowSuClient("shell");
allowSuClient("untrusted_app");
allowSuClient("system_app");
allowSuClient("platform_app");
if (sepol_exists("priv_app"))
allowSuClient("priv_app");
if (sepol_exists("ssd_tool"))
allowSuClient("ssd_tool");
// Allow init to execute su daemon/transition
sepol_allow("init", "su", "process", "transition");
sepol_allow("init", "su", "process", "rlimitinh");
sepol_allow("init", "su", "process", "siginh");
sepol_allow("init", "su", "process", "noatsecure");
suRights();
otherToSU();
// Need to set su_device/su as trusted to be accessible from other categories
sepol_attradd("su_device", "mlstrustedobject");
sepol_attradd("su", "mlstrustedsubject");
}
// Minimal to run Magisk script before live patching
void sepol_min_rules() { void sepol_min_rules() {
if (!sepol_exists("su")) if (!sepol_exists("su"))
sepol_create("su"); sepol_create("su");
if (!sepol_exists("su_device"))
sepol_create("su_device");
sepol_permissive("su"); sepol_permissive("su");
sepol_permissive("init"); sepol_permissive("init");
sepol_attradd("su", "mlstrustedsubject"); sepol_attradd("su", "mlstrustedsubject");
sepol_attradd("su_device", "mlstrustedobject");
// Let init run stuffs in su context // Let init run stuffs in su context
sepol_allow("kernel", "su", "fd", "use"); sepol_allow("kernel", "su", "fd", "use");
@ -192,11 +160,27 @@ void sepol_min_rules() {
sepol_allow("init", "system_file", "lnk_file", ALL); sepol_allow("init", "system_file", "lnk_file", ALL);
sepol_allow("init", "system_file", "file", ALL); sepol_allow("init", "system_file", "file", ALL);
// Misc: basic shell scripts, prop management etc. // Samsung specific
// Prevent system from loading policy
if(sepol_exists("knox_system_app"))
samsung();
// Shell, prop management, simple su rights
sepol_allow("su", "property_socket", "sock_file", "write"); sepol_allow("su", "property_socket", "sock_file", "write");
if (sepol_exists("default_prop")) if (sepol_exists("default_prop"))
sepol_allow("su", "default_prop", "property_service", "set"); sepol_allow("su", "default_prop", "property_service", "set");
sepol_allow("su", "init", "unix_stream_socket", "connectto"); sepol_allow("su", "init", "unix_stream_socket", "connectto");
sepol_allow("su", "rootfs", "file", "entrypoint");
sepol_allow("su", "devpts", "chr_file", ALL);
sepol_allow("su", "untrusted_app_devpts", "chr_file", ALL);
sepol_allow("su", "su_device", "dir", ALL);
sepol_allow("su", "su_device", "sock_file", ALL);
sepol_allow("su", "zygote_exec", "file", ALL);
sepol_allow("su", "zygote_exec", "lnk_file", ALL);
sepol_allow("su", "app_data_file", "dir", ALL);
sepol_allow("su", "app_data_file", "file", ALL);
sepol_allow("su", "toolbox_exec", "file", ALL);
sepol_allow("su", "shell_exec", "file", ALL);
sepol_allow("su", "su", "unix_dgram_socket", ALL); sepol_allow("su", "su", "unix_dgram_socket", ALL);
sepol_allow("su", "su", "unix_stream_socket", ALL); sepol_allow("su", "su", "unix_stream_socket", ALL);
sepol_allow("su", "su", "process", ALL); sepol_allow("su", "su", "process", ALL);
@ -206,10 +190,10 @@ void sepol_min_rules() {
sepol_allow("su", "su", "lnk_file", ALL); sepol_allow("su", "su", "lnk_file", ALL);
sepol_allow("su", "su", "dir", ALL); sepol_allow("su", "su", "dir", ALL);
// Allow su to do anything to files/dir/links // Autotransition su socket to su_device
sepol_allow("su", ALL, "file", ALL); sepol_typetrans("su", "device", "file", "su_device", NULL);
sepol_allow("su", ALL, "dir", ALL); sepol_typetrans("su", "device", "dir", "su_device", NULL);
sepol_allow("su", ALL, "lnk_file", ALL); sepol_allow("su_device", "tmpfs", "filesystem", "associate");
// For sepolicy live patching // For sepolicy live patching
sepol_allow("su", "kernel", "security", "read_policy"); sepol_allow("su", "kernel", "security", "read_policy");
@ -226,5 +210,32 @@ void sepol_min_rules() {
// Xposed // Xposed
sepol_allow("untrusted_app", "untrusted_app", "capability", "setgid"); sepol_allow("untrusted_app", "untrusted_app", "capability", "setgid");
sepol_allow("system_server", "dex2oat_exec", "file", ALL); sepol_allow("system_server", "dex2oat_exec", "file", ALL);
} }
void sepol_med_rules() {
sepol_min_rules();
// Allow su to do anything to any files/dir/links
sepol_allow("su", ALL, "file", ALL);
sepol_allow("su", ALL, "dir", ALL);
sepol_allow("su", ALL, "lnk_file", ALL);
// Allow these client to access su
allowSuClient("shell");
allowSuClient("untrusted_app");
allowSuClient("system_app");
allowSuClient("platform_app");
if (sepol_exists("priv_app"))
allowSuClient("priv_app");
if (sepol_exists("ssd_tool"))
allowSuClient("ssd_tool");
suRights();
otherToSU();
}
void sepol_full_rules() {
// Patch su to everything
sepol_allow("su", ALL, ALL, ALL);
}

View File

@ -1,6 +1,8 @@
#include "magiskpolicy.h" #include "magiskpolicy.h"
#include "sepolicy.h" #include "sepolicy.h"
policydb_t *policydb = NULL;
static void *cmalloc(size_t s) { static void *cmalloc(size_t s) {
void *t = malloc(s); void *t = malloc(s);
if (t == NULL) { if (t == NULL) {
@ -11,19 +13,19 @@ static void *cmalloc(size_t s) {
} }
static int get_attr(char *type, int value) { static int get_attr(char *type, int value) {
type_datum_t *attr = hashtab_search(policy->p_types.table, type); type_datum_t *attr = hashtab_search(policydb->p_types.table, type);
if (!attr) if (!attr)
return 1; return 1;
if (attr->flavor != TYPE_ATTRIB) if (attr->flavor != TYPE_ATTRIB)
return 1; return 1;
return !! ebitmap_get_bit(&policy->attr_type_map[attr->s.value-1], value-1); return !! ebitmap_get_bit(&policydb->attr_type_map[attr->s.value-1], value-1);
//return !! ebitmap_get_bit(&policy->type_attr_map[value-1], attr->s.value-1); //return !! ebitmap_get_bit(&policydb->type_attr_map[value-1], attr->s.value-1);
} }
static int get_attr_id(char *type) { static int get_attr_id(char *type) {
type_datum_t *attr = hashtab_search(policy->p_types.table, type); type_datum_t *attr = hashtab_search(policydb->p_types.table, type);
if (!attr) if (!attr)
return 1; return 1;
@ -34,16 +36,16 @@ static int get_attr_id(char *type) {
} }
static int set_attr(char *type, int value) { static int set_attr(char *type, int value) {
type_datum_t *attr = hashtab_search(policy->p_types.table, type); type_datum_t *attr = hashtab_search(policydb->p_types.table, type);
if (!attr) if (!attr)
return 1; return 1;
if (attr->flavor != TYPE_ATTRIB) if (attr->flavor != TYPE_ATTRIB)
return 1; return 1;
if(ebitmap_set_bit(&policy->type_attr_map[value-1], attr->s.value-1, 1)) if(ebitmap_set_bit(&policydb->type_attr_map[value-1], attr->s.value-1, 1))
return 1; return 1;
if(ebitmap_set_bit(&policy->attr_type_map[attr->s.value-1], value-1, 1)) if(ebitmap_set_bit(&policydb->attr_type_map[attr->s.value-1], value-1, 1))
return 1; return 1;
return 0; return 0;
@ -57,13 +59,13 @@ static int add_irule(int s, int t, int c, int p, int effect, int not) {
key.target_type = t; key.target_type = t;
key.target_class = c; key.target_class = c;
key.specified = effect; key.specified = effect;
av = avtab_search(&policy->te_avtab, &key); av = avtab_search(&policydb->te_avtab, &key);
if (av == NULL) { if (av == NULL) {
av = cmalloc(sizeof(*av)); av = cmalloc(sizeof(*av));
memset(av, 0, sizeof(*av)); memset(av, 0, sizeof(*av));
av->data |= 1U << (p - 1); av->data |= 1U << (p - 1);
int ret = avtab_insert(&policy->te_avtab, &key, av); int ret = avtab_insert(&policydb->te_avtab, &key, av);
if (ret) { if (ret) {
fprintf(stderr, "Error inserting into avtab\n"); fprintf(stderr, "Error inserting into avtab\n");
return 1; return 1;
@ -82,19 +84,19 @@ static int add_rule_auto(type_datum_t *src, type_datum_t *tgt, class_datum_t *cl
int ret = 0; int ret = 0;
if (src == NULL) { if (src == NULL) {
hashtab_for_each(policy->p_types.table, &cur) { hashtab_for_each(policydb->p_types.table, &cur) {
src = cur->datum; src = cur->datum;
if(add_rule_auto(src, tgt, cls, perm, effect, not)) if(add_rule_auto(src, tgt, cls, perm, effect, not))
return 1; return 1;
} }
} else if (tgt == NULL) { } else if (tgt == NULL) {
hashtab_for_each(policy->p_types.table, &cur) { hashtab_for_each(policydb->p_types.table, &cur) {
tgt = cur->datum; tgt = cur->datum;
if(add_rule_auto(src, tgt, cls, perm, effect, not)) if(add_rule_auto(src, tgt, cls, perm, effect, not))
return 1; return 1;
} }
} else if (cls == NULL) { } else if (cls == NULL) {
hashtab_for_each(policy->p_classes.table, &cur) { hashtab_for_each(policydb->p_classes.table, &cur) {
cls = cur->datum; cls = cur->datum;
if(add_rule_auto(src, tgt, cls, perm, effect, not)) if(add_rule_auto(src, tgt, cls, perm, effect, not))
return 1; return 1;
@ -118,18 +120,18 @@ static int add_rule_auto(type_datum_t *src, type_datum_t *tgt, class_datum_t *cl
int i, j; int i, j;
if (src->flavor == TYPE_ATTRIB) { if (src->flavor == TYPE_ATTRIB) {
if (tgt->flavor == TYPE_ATTRIB) { if (tgt->flavor == TYPE_ATTRIB) {
ebitmap_for_each_bit(&policy->attr_type_map[src->s.value-1], s_node, i) ebitmap_for_each_bit(&policydb->attr_type_map[src->s.value-1], s_node, i)
ebitmap_for_each_bit(&policy->attr_type_map[tgt->s.value-1], t_node, j) ebitmap_for_each_bit(&policydb->attr_type_map[tgt->s.value-1], t_node, j)
if(ebitmap_node_get_bit(s_node, i) && ebitmap_node_get_bit(t_node, j)) if(ebitmap_node_get_bit(s_node, i) && ebitmap_node_get_bit(t_node, j))
ret |= add_irule(i + 1, j + 1, cls->s.value, perm->s.value, effect, not); ret |= add_irule(i + 1, j + 1, cls->s.value, perm->s.value, effect, not);
} else { } else {
ebitmap_for_each_bit(&policy->attr_type_map[src->s.value-1], s_node, i) ebitmap_for_each_bit(&policydb->attr_type_map[src->s.value-1], s_node, i)
if(ebitmap_node_get_bit(s_node, i)) if(ebitmap_node_get_bit(s_node, i))
ret |= add_irule(i + 1, tgt->s.value, cls->s.value, perm->s.value, effect, not); ret |= add_irule(i + 1, tgt->s.value, cls->s.value, perm->s.value, effect, not);
} }
} else if (tgt->flavor == TYPE_ATTRIB) { } else if (tgt->flavor == TYPE_ATTRIB) {
ebitmap_for_each_bit(&policy->attr_type_map[tgt->s.value-1], t_node, j) ebitmap_for_each_bit(&policydb->attr_type_map[tgt->s.value-1], t_node, j)
if(ebitmap_node_get_bit(t_node, j)) if(ebitmap_node_get_bit(t_node, j))
ret |= add_irule(src->s.value, j + 1, cls->s.value, perm->s.value, effect, not); ret |= add_irule(src->s.value, j + 1, cls->s.value, perm->s.value, effect, not);
} else } else
@ -138,13 +140,18 @@ static int add_rule_auto(type_datum_t *src, type_datum_t *tgt, class_datum_t *cl
return ret; return ret;
} }
int load_policy(const char *filename) { int load_policydb(const char *filename) {
int fd; int fd;
struct stat sb; struct stat sb;
struct policy_file pf; struct policy_file pf;
void *map; void *map;
int ret; int ret;
if (policydb)
destroy_policydb();
policydb = cmalloc(sizeof(*policydb));
fd = open(filename, O_RDONLY); fd = open(filename, O_RDONLY);
if (fd < 0) { if (fd < 0) {
fprintf(stderr, "Can't open '%s': %s\n", fprintf(stderr, "Can't open '%s': %s\n",
@ -168,26 +175,28 @@ int load_policy(const char *filename) {
pf.type = PF_USE_MEMORY; pf.type = PF_USE_MEMORY;
pf.data = map; pf.data = map;
pf.len = sb.st_size; pf.len = sb.st_size;
if (policydb_init(policy)) { if (policydb_init(policydb)) {
fprintf(stderr, "policydb_init: Out of memory!\n"); fprintf(stderr, "policydb_init: Out of memory!\n");
return 1; return 1;
} }
ret = policydb_read(policy, &pf, 0); ret = policydb_read(policydb, &pf, 0);
if (ret) { if (ret) {
fprintf(stderr, "error(s) encountered while parsing configuration\n"); fprintf(stderr, "error(s) encountered while parsing configuration\n");
return 1; return 1;
} }
close(fd);
return 0; return 0;
} }
int dump_policy(const char *filename) { int dump_policydb(const char *filename) {
int fd, ret; int fd, ret;
void *data = NULL; void *data = NULL;
size_t len; size_t len;
policydb_to_image(NULL, policy, &data, &len); policydb_to_image(NULL, policydb, &data, &len);
if (data == NULL) { if (data == NULL) {
fprintf(stderr, "Fail to dump policydb image!"); fprintf(stderr, "Fail to dump policy image!");
return 1; return 1;
} }
@ -207,8 +216,14 @@ int dump_policy(const char *filename) {
return 0; return 0;
} }
void destroy_policydb() {
policydb_destroy(policydb);
free(policydb);
policydb = NULL;
}
int create_domain(char *d) { int create_domain(char *d) {
symtab_datum_t *src = hashtab_search(policy->p_types.table, d); symtab_datum_t *src = hashtab_search(policydb->p_types.table, d);
if(src) if(src)
return 1; return 1;
@ -218,40 +233,38 @@ int create_domain(char *d) {
typdatum->flavor = TYPE_TYPE; typdatum->flavor = TYPE_TYPE;
uint32_t value = 0; uint32_t value = 0;
int r = symtab_insert(policy, SYM_TYPES, strdup(d), typdatum, SCOPE_DECL, 1, &value); int r = symtab_insert(policydb, SYM_TYPES, strdup(d), typdatum, SCOPE_DECL, 1, &value);
typdatum->s.value = value; typdatum->s.value = value;
if (ebitmap_set_bit(&policy->global->branch_list->declared.scope[SYM_TYPES], value - 1, 1)) { if (ebitmap_set_bit(&policydb->global->branch_list->declared.scope[SYM_TYPES], value - 1, 1)) {
return 1; return 1;
} }
policy->type_attr_map = realloc(policy->type_attr_map, sizeof(ebitmap_t)*policy->p_types.nprim); policydb->type_attr_map = realloc(policydb->type_attr_map, sizeof(ebitmap_t)*policydb->p_types.nprim);
policy->attr_type_map = realloc(policy->attr_type_map, sizeof(ebitmap_t)*policy->p_types.nprim); policydb->attr_type_map = realloc(policydb->attr_type_map, sizeof(ebitmap_t)*policydb->p_types.nprim);
ebitmap_init(&policy->type_attr_map[value-1]); ebitmap_init(&policydb->type_attr_map[value-1]);
ebitmap_init(&policy->attr_type_map[value-1]); ebitmap_init(&policydb->attr_type_map[value-1]);
ebitmap_set_bit(&policy->type_attr_map[value-1], value-1, 1); ebitmap_set_bit(&policydb->type_attr_map[value-1], value-1, 1);
//Add the domain to all roles //Add the domain to all roles
for(unsigned i=0; i<policy->p_roles.nprim; ++i) { for(unsigned i=0; i<policydb->p_roles.nprim; ++i) {
//Not sure all those three calls are needed //Not sure all those three calls are needed
ebitmap_set_bit(&policy->role_val_to_struct[i]->types.negset, value-1, 0); ebitmap_set_bit(&policydb->role_val_to_struct[i]->types.negset, value-1, 0);
ebitmap_set_bit(&policy->role_val_to_struct[i]->types.types, value-1, 1); ebitmap_set_bit(&policydb->role_val_to_struct[i]->types.types, value-1, 1);
type_set_expand(&policy->role_val_to_struct[i]->types, &policy->role_val_to_struct[i]->cache, policy, 0); type_set_expand(&policydb->role_val_to_struct[i]->types, &policydb->role_val_to_struct[i]->cache, policydb, 0);
} }
src = hashtab_search(policydb->p_types.table, d);
src = hashtab_search(policy->p_types.table, d);
if(!src) if(!src)
return 1; return 1;
extern int policydb_index_decls(policydb_t * p); if(policydb_index_decls(NULL, policydb))
if(policydb_index_decls(policy))
return 1; return 1;
if(policydb_index_classes(policy)) if(policydb_index_classes(policydb))
return 1; return 1;
if(policydb_index_others(NULL, policy, 0)) if(policydb_index_others(NULL, policydb, 0))
return 1; return 1;
return set_attr("domain", value); return set_attr("domain", value);
@ -261,20 +274,20 @@ int set_domain_state(char* s, int state) {
type_datum_t *type; type_datum_t *type;
hashtab_ptr_t cur; hashtab_ptr_t cur;
if (s == NULL) { if (s == NULL) {
hashtab_for_each(policy->p_types.table, &cur) { hashtab_for_each(policydb->p_types.table, &cur) {
type = cur->datum; type = cur->datum;
if (ebitmap_set_bit(&policy->permissive_map, type->s.value, state)) { if (ebitmap_set_bit(&policydb->permissive_map, type->s.value, state)) {
fprintf(stderr, "Could not set bit in permissive map\n"); fprintf(stderr, "Could not set bit in permissive map\n");
return 1; return 1;
} }
} }
} else { } else {
type = hashtab_search(policy->p_types.table, s); type = hashtab_search(policydb->p_types.table, s);
if (type == NULL) { if (type == NULL) {
fprintf(stderr, "type %s does not exist\n", s); fprintf(stderr, "type %s does not exist\n", s);
return 1; return 1;
} }
if (ebitmap_set_bit(&policy->permissive_map, type->s.value, state)) { if (ebitmap_set_bit(&policydb->permissive_map, type->s.value, state)) {
fprintf(stderr, "Could not set bit in permissive map\n"); fprintf(stderr, "Could not set bit in permissive map\n");
return 1; return 1;
} }
@ -290,22 +303,22 @@ int add_transition(char *s, char *t, char *c, char *d) {
avtab_datum_t *av; avtab_datum_t *av;
avtab_key_t key; avtab_key_t key;
src = hashtab_search(policy->p_types.table, s); src = hashtab_search(policydb->p_types.table, s);
if (src == NULL) { if (src == NULL) {
fprintf(stderr, "source type %s does not exist\n", s); fprintf(stderr, "source type %s does not exist\n", s);
return 1; return 1;
} }
tgt = hashtab_search(policy->p_types.table, t); tgt = hashtab_search(policydb->p_types.table, t);
if (tgt == NULL) { if (tgt == NULL) {
fprintf(stderr, "target type %s does not exist\n", t); fprintf(stderr, "target type %s does not exist\n", t);
return 1; return 1;
} }
cls = hashtab_search(policy->p_classes.table, c); cls = hashtab_search(policydb->p_classes.table, c);
if (cls == NULL) { if (cls == NULL) {
fprintf(stderr, "class %s does not exist\n", c); fprintf(stderr, "class %s does not exist\n", c);
return 1; return 1;
} }
def = hashtab_search(policy->p_types.table, d); def = hashtab_search(policydb->p_types.table, d);
if (def == NULL) { if (def == NULL) {
fprintf(stderr, "default type %s does not exist\n", d); fprintf(stderr, "default type %s does not exist\n", d);
return 1; return 1;
@ -315,12 +328,12 @@ int add_transition(char *s, char *t, char *c, char *d) {
key.target_type = tgt->s.value; key.target_type = tgt->s.value;
key.target_class = cls->s.value; key.target_class = cls->s.value;
key.specified = AVTAB_TRANSITION; key.specified = AVTAB_TRANSITION;
av = avtab_search(&policy->te_avtab, &key); av = avtab_search(&policydb->te_avtab, &key);
if (av == NULL) { if (av == NULL) {
av = cmalloc(sizeof(*av)); av = cmalloc(sizeof(*av));
av->data = def->s.value; av->data = def->s.value;
int ret = avtab_insert(&policy->te_avtab, &key, av); int ret = avtab_insert(&policydb->te_avtab, &key, av);
if (ret) { if (ret) {
fprintf(stderr, "Error inserting into avtab\n"); fprintf(stderr, "Error inserting into avtab\n");
return 1; return 1;
@ -337,22 +350,22 @@ int add_file_transition(char *s, char *t, char *c, char *d, char* filename) {
type_datum_t *src, *tgt, *def; type_datum_t *src, *tgt, *def;
class_datum_t *cls; class_datum_t *cls;
src = hashtab_search(policy->p_types.table, s); src = hashtab_search(policydb->p_types.table, s);
if (src == NULL) { if (src == NULL) {
fprintf(stderr, "source type %s does not exist\n", s); fprintf(stderr, "source type %s does not exist\n", s);
return 1; return 1;
} }
tgt = hashtab_search(policy->p_types.table, t); tgt = hashtab_search(policydb->p_types.table, t);
if (tgt == NULL) { if (tgt == NULL) {
fprintf(stderr, "target type %s does not exist\n", t); fprintf(stderr, "target type %s does not exist\n", t);
return 1; return 1;
} }
cls = hashtab_search(policy->p_classes.table, c); cls = hashtab_search(policydb->p_classes.table, c);
if (cls == NULL) { if (cls == NULL) {
fprintf(stderr, "class %s does not exist\n", c); fprintf(stderr, "class %s does not exist\n", c);
return 1; return 1;
} }
def = hashtab_search(policy->p_types.table, d); def = hashtab_search(policydb->p_types.table, d);
if (def == NULL) { if (def == NULL) {
fprintf(stderr, "default type %s does not exist\n", d); fprintf(stderr, "default type %s does not exist\n", d);
return 1; return 1;
@ -367,7 +380,7 @@ int add_file_transition(char *s, char *t, char *c, char *d, char* filename) {
filename_trans_datum_t *new_trans_datam = cmalloc(sizeof(*new_trans_datam)); filename_trans_datum_t *new_trans_datam = cmalloc(sizeof(*new_trans_datam));
new_trans_datam->otype = def->s.value; new_trans_datam->otype = def->s.value;
hashtab_insert(policy->filename_trans, (hashtab_key_t) new_trans_key, new_trans_datam); hashtab_insert(policydb->filename_trans, (hashtab_key_t) new_trans_key, new_trans_datam);
return 0; return 0;
} }
@ -375,7 +388,7 @@ int add_file_transition(char *s, char *t, char *c, char *d, char* filename) {
int add_typeattribute(char *domainS, char *attr) { int add_typeattribute(char *domainS, char *attr) {
type_datum_t *domain; type_datum_t *domain;
domain = hashtab_search(policy->p_types.table, domainS); domain = hashtab_search(policydb->p_types.table, domainS);
if (domain == NULL) { if (domain == NULL) {
fprintf(stderr, "source type %s does not exist\n", domainS); fprintf(stderr, "source type %s does not exist\n", domainS);
return 1; return 1;
@ -386,8 +399,8 @@ int add_typeattribute(char *domainS, char *attr) {
int typeId = get_attr_id(attr); int typeId = get_attr_id(attr);
//Now let's update all constraints! //Now let's update all constraints!
//(kernel doesn't support (yet?) type_names rules) //(kernel doesn't support (yet?) type_names rules)
for(int i=0; i<policy->p_classes.nprim; ++i) { for(int i=0; i<policydb->p_classes.nprim; ++i) {
class_datum_t *cl = policy->class_val_to_struct[i]; class_datum_t *cl = policydb->class_val_to_struct[i];
for(constraint_node_t *n = cl->constraints; n ; n=n->next) { for(constraint_node_t *n = cl->constraints; n ; n=n->next) {
for(constraint_expr_t *e = n->expr; e; e=e->next) { for(constraint_expr_t *e = n->expr; e; e=e->next) {
if(e->expr_type == CEXPR_NAMES) { if(e->expr_type == CEXPR_NAMES) {
@ -407,7 +420,7 @@ int add_rule(char *s, char *t, char *c, char *p, int effect, int not) {
perm_datum_t *perm = NULL; perm_datum_t *perm = NULL;
if (s) { if (s) {
src = hashtab_search(policy->p_types.table, s); src = hashtab_search(policydb->p_types.table, s);
if (src == NULL) { if (src == NULL) {
fprintf(stderr, "source type %s does not exist\n", s); fprintf(stderr, "source type %s does not exist\n", s);
return 1; return 1;
@ -415,7 +428,7 @@ int add_rule(char *s, char *t, char *c, char *p, int effect, int not) {
} }
if (t) { if (t) {
tgt = hashtab_search(policy->p_types.table, t); tgt = hashtab_search(policydb->p_types.table, t);
if (tgt == NULL) { if (tgt == NULL) {
fprintf(stderr, "target type %s does not exist\n", t); fprintf(stderr, "target type %s does not exist\n", t);
return 1; return 1;
@ -423,7 +436,7 @@ int add_rule(char *s, char *t, char *c, char *p, int effect, int not) {
} }
if (c) { if (c) {
cls = hashtab_search(policy->p_classes.table, c); cls = hashtab_search(policydb->p_classes.table, c);
if (cls == NULL) { if (cls == NULL) {
fprintf(stderr, "class %s does not exist\n", c); fprintf(stderr, "class %s does not exist\n", c);
return 1; return 1;

View File

@ -33,11 +33,9 @@
for (*ptr = table->htable[_i]; *ptr != NULL; *ptr = (*ptr)->next) for (*ptr = table->htable[_i]; *ptr != NULL; *ptr = (*ptr)->next)
// Global policydb // Global policydb
policydb_t *policy; extern policydb_t *policydb;
// sepolicy manipulation functions // sepolicy manipulation functions
int load_policy(const char *filename);
int dump_policy(const char *filename);
int create_domain(char *d); int create_domain(char *d);
int set_domain_state(char* s, int state); int set_domain_state(char* s, int state);
int add_transition(char *s, char *t, char *c, char *d); int add_transition(char *s, char *t, char *c, char *d);
@ -45,4 +43,6 @@ int add_file_transition(char *s, char *t, char *c, char *d, char* filename);
int add_typeattribute(char *domainS, char *attr); int add_typeattribute(char *domainS, char *attr);
int add_rule(char *s, char *t, char *c, char *p, int effect, int not); int add_rule(char *s, char *t, char *c, char *p, int effect, int not);
extern int policydb_index_decls(sepol_handle_t * handle, policydb_t * p);
#endif #endif