diff --git a/init/devices.c b/init/devices.c index c367de876..597f9583e 100644 --- a/init/devices.c +++ b/init/devices.c @@ -33,6 +33,7 @@ #ifdef HAVE_SELINUX #include #include +#include #endif #include @@ -871,12 +872,10 @@ void device_init(void) struct stat info; int fd; #ifdef HAVE_SELINUX - struct selinux_opt seopts[] = { - { SELABEL_OPT_PATH, "/file_contexts" } - }; - - if (is_selinux_enabled() > 0) - sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); + sehandle = NULL; + if (is_selinux_enabled() > 0) { + sehandle = selinux_android_file_context_handle(); + } #endif /* is 64K enough? udev uses 16MB! */ device_fd = uevent_open_socket(64*1024, true); diff --git a/init/init.c b/init/init.c index cc98afcf5..d11db618c 100755 --- a/init/init.c +++ b/init/init.c @@ -33,9 +33,9 @@ #include #ifdef HAVE_SELINUX -#include #include #include +#include #endif #include @@ -77,7 +77,6 @@ static char qemu[32]; #ifdef HAVE_SELINUX static int selinux_enabled = 1; -static int selinux_enforcing = 0; #endif static struct action *cur_action = NULL; @@ -604,9 +603,7 @@ static void import_kernel_nv(char *name, int for_emulator) if (name_len == 0) return; #ifdef HAVE_SELINUX - if (!strcmp(name,"enforcing")) { - selinux_enforcing = atoi(value); - } else if (!strcmp(name,"selinux")) { + if (!strcmp(name,"selinux")) { selinux_enabled = atoi(value); } #endif @@ -758,93 +755,28 @@ static int bootchart_init_action(int nargs, char **args) #endif #ifdef HAVE_SELINUX -void selinux_load_policy(void) +void selinux_init_all_handles(void) { - const char path_prefix[] = "/sepolicy"; - struct selinux_opt seopts[] = { - { SELABEL_OPT_PATH, "/file_contexts" } - }; - char path[PATH_MAX]; - int fd, rc, vers; - struct stat sb; - void *map; + sehandle = selinux_android_file_context_handle(); +} - sehandle = NULL; +int selinux_reload_policy(void) +{ if (!selinux_enabled) { - INFO("SELinux: Disabled by command line option\n"); - return; + return -1; } - mkdir(SELINUXMNT, 0755); - if (mount("selinuxfs", SELINUXMNT, "selinuxfs", 0, NULL)) { - if (errno == ENODEV) { - /* SELinux not enabled in kernel */ - return; - } - ERROR("SELinux: Could not mount selinuxfs: %s\n", - strerror(errno)); - return; - } - set_selinuxmnt(SELINUXMNT); + INFO("SELinux: Attempting to reload policy files\n"); - vers = security_policyvers(); - if (vers <= 0) { - ERROR("SELinux: Unable to read policy version\n"); - return; - } - INFO("SELinux: Maximum supported policy version: %d\n", vers); - - snprintf(path, sizeof(path), "%s.%d", - path_prefix, vers); - fd = open(path, O_RDONLY); - while (fd < 0 && errno == ENOENT && --vers) { - snprintf(path, sizeof(path), "%s.%d", - path_prefix, vers); - fd = open(path, O_RDONLY); - } - if (fd < 0) { - ERROR("SELinux: Could not open %s: %s\n", - path, strerror(errno)); - return; - } - if (fstat(fd, &sb) < 0) { - ERROR("SELinux: Could not stat %s: %s\n", - path, strerror(errno)); - return; - } - map = mmap(NULL, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); - if (map == MAP_FAILED) { - ERROR("SELinux: Could not map %s: %s\n", - path, strerror(errno)); - return; + if (selinux_android_reload_policy() == -1) { + return -1; } - rc = security_load_policy(map, sb.st_size); - if (rc < 0) { - ERROR("SELinux: Could not load policy: %s\n", - strerror(errno)); - return; - } + if (sehandle) + selabel_close(sehandle); - rc = security_setenforce(selinux_enforcing); - if (rc < 0) { - ERROR("SELinux: Could not set enforcing mode to %s: %s\n", - selinux_enforcing ? "enforcing" : "permissive", strerror(errno)); - return; - } - - munmap(map, sb.st_size); - close(fd); - INFO("SELinux: Loaded policy from %s\n", path); - - sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); - if (!sehandle) { - ERROR("SELinux: Could not load file_contexts: %s\n", - strerror(errno)); - return; - } - INFO("SELinux: Loaded file contexts from %s\n", seopts[0].value); - return; + selinux_init_all_handles(); + return 0; } #endif @@ -900,8 +832,17 @@ int main(int argc, char **argv) #ifdef HAVE_SELINUX INFO("loading selinux policy\n"); - selinux_load_policy(); - /* These directories were necessarily created before policy load + if (selinux_enabled) { + if (selinux_android_load_policy() < 0) { + selinux_enabled = 0; + INFO("SELinux: Disabled due to failed policy load\n"); + } else { + selinux_init_all_handles(); + } + } else { + INFO("SELinux: Disabled by command line option\n"); + } + /* These directories were necessarily created before initial policy load * and therefore need their security context restored to the proper value. * This must happen before /dev is populated by ueventd. */ diff --git a/init/init.h b/init/init.h index 58bbbfe9b..e2d990e69 100644 --- a/init/init.h +++ b/init/init.h @@ -138,6 +138,7 @@ int load_565rle_image( char *file_name ); #ifdef HAVE_SELINUX extern struct selabel_handle *sehandle; +extern int selinux_reload_policy(void); #endif #endif /* _INIT_INIT_H */ diff --git a/init/property_service.c b/init/property_service.c index 79914cde5..471c3dc4b 100644 --- a/init/property_service.c +++ b/init/property_service.c @@ -86,6 +86,7 @@ struct { { "persist.sys.", AID_SYSTEM, 0 }, { "persist.service.", AID_SYSTEM, 0 }, { "persist.security.", AID_SYSTEM, 0 }, + { "selinux." , AID_SYSTEM, 0 }, { NULL, 0, 0 } }; @@ -334,6 +335,11 @@ int property_set(const char *name, const char *value) * to prevent them from being overwritten by default values. */ write_persistent_property(name, value); +#ifdef HAVE_SELINUX + } else if (strcmp("selinux.reload_policy", name) == 0 && + strcmp("1", value) == 0) { + selinux_reload_policy(); +#endif } property_changed(name, value); return 0; diff --git a/rootdir/init.rc b/rootdir/init.rc index 76a4ff105..47653e47a 100644 --- a/rootdir/init.rc +++ b/rootdir/init.rc @@ -355,6 +355,10 @@ service ueventd /sbin/ueventd critical seclabel u:r:ueventd:s0 +on property:selinux.reload_policy=1 + restart ueventd + restart installd + service console /system/bin/sh class core console diff --git a/toolbox/restorecon.c b/toolbox/restorecon.c index 5ef0ef1fb..f9f604f79 100644 --- a/toolbox/restorecon.c +++ b/toolbox/restorecon.c @@ -7,8 +7,7 @@ #include #include #include - -#define FCPATH "/file_contexts" +#include static struct selabel_handle *sehandle; static const char *progname; @@ -17,7 +16,7 @@ static int verbose; static void usage(void) { - fprintf(stderr, "usage: %s [-f file_contexts] [-nrRv] pathname...\n", progname); + fprintf(stderr, "usage: %s [-nrRv] pathname...\n", progname); exit(1); } @@ -54,21 +53,16 @@ static int restore(const char *pathname, const struct stat *sb) int restorecon_main(int argc, char **argv) { - struct selinux_opt seopts[] = { - { SELABEL_OPT_PATH, FCPATH } - }; int ch, recurse = 0, ftsflags = FTS_PHYSICAL; + int i = 0; progname = argv[0]; do { - ch = getopt(argc, argv, "f:nrRv"); + ch = getopt(argc, argv, "nrRv"); if (ch == EOF) break; switch (ch) { - case 'f': - seopts[0].value = optarg; - break; case 'n': nochange = 1; break; @@ -89,9 +83,10 @@ int restorecon_main(int argc, char **argv) if (!argc) usage(); - sehandle = selabel_open(SELABEL_CTX_FILE, seopts, 1); + sehandle = selinux_android_file_context_handle(); + if (!sehandle) { - fprintf(stderr, "Could not load file contexts from %s: %s\n", seopts[0].value, + fprintf(stderr, "Could not load file_contexts: %s\n", strerror(errno)); return -1; }