summaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
Diffstat (limited to 'init')
-rw-r--r--[-rwxr-xr-x]init/init.c80
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.