diff options
Diffstat (limited to 'init')
| -rw-r--r--[-rwxr-xr-x] | init/init.c | 80 |
1 files changed, 62 insertions, 18 deletions
diff --git a/init/init.c b/init/init.c index 28d2863..d75adca 100755..100644 --- a/init/init.c +++ b/init/init.c @@ -39,6 +39,7 @@ #include <libgen.h> #include <cutils/list.h> +#include <cutils/android_reboot.h> #include <cutils/sockets.h> #include <cutils/iosched_policy.h> #include <private/android_filesystem_config.h> @@ -73,8 +74,6 @@ static char hardware[32]; static unsigned revision = 0; static char qemu[32]; -static int selinux_enabled = 1; - static struct action *cur_action = NULL; static struct command *cur_command = NULL; static struct listnode *command_queue = NULL; @@ -614,10 +613,6 @@ static void import_kernel_nv(char *name, int for_emulator) *value++ = 0; if (name_len == 0) return; - if (!strcmp(name,"selinux")) { - selinux_enabled = atoi(value); - } - if (for_emulator) { /* in the emulator, export any kernel option with the * ro.kernel. prefix */ @@ -798,9 +793,49 @@ void selinux_init_all_handles(void) sehandle_prop = selinux_android_prop_context_handle(); } +static bool selinux_is_disabled(void) +{ + char tmp[PROP_VALUE_MAX]; + + if (access("/sys/fs/selinux", F_OK) != 0) { + /* SELinux is not compiled into the kernel, or has been disabled + * via the kernel command line "selinux=0". + */ + return true; + } + + if ((property_get("ro.boot.selinux", tmp) != 0) && (strcmp(tmp, "disabled") == 0)) { + /* SELinux is compiled into the kernel, but we've been told to disable it. */ + return true; + } + + return false; +} + +static bool selinux_is_enforcing(void) +{ + char tmp[PROP_VALUE_MAX]; + + if (property_get("ro.boot.selinux", tmp) == 0) { + /* Property is not set. Assume enforcing */ + return true; + } + + if (strcmp(tmp, "permissive") == 0) { + /* SELinux is in the kernel, but we've been told to go into permissive mode */ + return false; + } + + if (strcmp(tmp, "enforcing") != 0) { + ERROR("SELinux: Unknown value of ro.boot.selinux. Got: \"%s\". Assuming enforcing.\n", tmp); + } + + return true; +} + int selinux_reload_policy(void) { - if (!selinux_enabled) { + if (selinux_is_disabled()) { return -1; } @@ -826,6 +861,25 @@ int audit_callback(void *data, security_class_t cls, char *buf, size_t len) return 0; } +static void selinux_initialize(void) +{ + if (selinux_is_disabled()) { + return; + } + + INFO("loading selinux policy\n"); + if (selinux_android_load_policy() < 0) { + ERROR("SELinux: Failed to load policy; rebooting into recovery mode\n"); + android_reboot(ANDROID_RB_RESTART2, 0, "recovery"); + while (1) { pause(); } // never reached + } + + selinux_init_all_handles(); + bool is_enforcing = selinux_is_enforcing(); + INFO("SELinux: security_setenforce(%d)\n", is_enforcing); + security_setenforce(is_enforcing); +} + int main(int argc, char **argv) { int fd_count = 0; @@ -886,17 +940,7 @@ int main(int argc, char **argv) cb.func_audit = audit_callback; selinux_set_callback(SELINUX_CB_AUDIT, cb); - INFO("loading selinux policy\n"); - 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"); - } + selinux_initialize(); /* 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. |
