Loading init/Android.mk +6 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,12 @@ LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED) LOCAL_STATIC_LIBRARIES := libcutils libc ifeq ($(HAVE_SELINUX),true) LOCAL_STATIC_LIBRARIES += libselinux LOCAL_C_INCLUDES := external/libselinux/include LOCAL_CFLAGS += -DHAVE_SELINUX endif include $(BUILD_EXECUTABLE) # Make a symlink from /sbin/ueventd to /init Loading init/builtins.c +85 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,11 @@ #include <cutils/partition_utils.h> #include <sys/system_properties.h> #ifdef HAVE_SELINUX #include <selinux/selinux.h> #include <selinux/label.h> #endif #include "init.h" #include "keywords.h" #include "property_service.h" Loading Loading @@ -436,6 +441,28 @@ exit_success: } int do_setcon(int nargs, char **args) { #ifdef HAVE_SELINUX if (is_selinux_enabled() <= 0) return 0; if (setcon(args[1]) < 0) { return -errno; } #endif return 0; } int do_setenforce(int nargs, char **args) { #ifdef HAVE_SELINUX if (is_selinux_enabled() <= 0) return 0; if (security_setenforce(atoi(args[1])) < 0) { return -errno; } #endif return 0; } int do_setkey(int nargs, char **args) { struct kbentry kbe; Loading Loading @@ -649,6 +676,64 @@ int do_chmod(int nargs, char **args) { return 0; } int do_restorecon(int nargs, char **args) { #ifdef HAVE_SELINUX char *secontext = NULL; struct stat sb; int i; if (is_selinux_enabled() <= 0 || !sehandle) return 0; for (i = 1; i < nargs; i++) { if (lstat(args[i], &sb) < 0) return -errno; if (selabel_lookup(sehandle, &secontext, args[i], sb.st_mode) < 0) return -errno; if (lsetfilecon(args[i], secontext) < 0) { freecon(secontext); return -errno; } freecon(secontext); } #endif return 0; } int do_setsebool(int nargs, char **args) { #ifdef HAVE_SELINUX SELboolean *b = alloca(nargs * sizeof(SELboolean)); char *v; int i; if (is_selinux_enabled() <= 0) return 0; for (i = 1; i < nargs; i++) { char *name = args[i]; v = strchr(name, '='); if (!v) { ERROR("setsebool: argument %s had no =\n", name); return -EINVAL; } *v++ = 0; b[i-1].name = name; if (!strcmp(v, "1") || !strcasecmp(v, "true") || !strcasecmp(v, "on")) b[i-1].value = 1; else if (!strcmp(v, "0") || !strcasecmp(v, "false") || !strcasecmp(v, "off")) b[i-1].value = 0; else { ERROR("setsebool: invalid value %s\n", v); return -EINVAL; } } if (security_set_boolean_list(nargs - 1, b, 0) < 0) return -errno; #endif return 0; } int do_loglevel(int nargs, char **args) { if (nargs == 2) { klog_set_level(atoi(args[1])); Loading init/devices.c +70 −12 Original line number Diff line number Diff line Loading @@ -29,6 +29,12 @@ #include <sys/socket.h> #include <sys/un.h> #include <linux/netlink.h> #ifdef HAVE_SELINUX #include <selinux/selinux.h> #include <selinux/label.h> #endif #include <private/android_filesystem_config.h> #include <sys/time.h> #include <asm/page.h> Loading @@ -45,6 +51,10 @@ #define FIRMWARE_DIR1 "/etc/firmware" #define FIRMWARE_DIR2 "/vendor/firmware" #ifdef HAVE_SELINUX static struct selabel_handle *sehandle; #endif static int device_fd = -1; struct uevent { Loading Loading @@ -180,8 +190,17 @@ static void make_device(const char *path, unsigned gid; mode_t mode; dev_t dev; #ifdef HAVE_SELINUX char *secontext = NULL; #endif mode = get_device_perm(path, &uid, &gid) | (block ? S_IFBLK : S_IFCHR); #ifdef HAVE_SELINUX if (sehandle) { selabel_lookup(sehandle, &secontext, path, mode); setfscreatecon(secontext); } #endif dev = makedev(major, minor); /* Temporarily change egid to avoid race condition setting the gid of the * device node. Unforunately changing the euid would prevent creation of Loading @@ -192,8 +211,40 @@ static void make_device(const char *path, mknod(path, mode, dev); chown(path, uid, -1); setegid(AID_ROOT); #ifdef HAVE_SELINUX if (secontext) { freecon(secontext); setfscreatecon(NULL); } #endif } static int make_dir(const char *path, mode_t mode) { int rc; #ifdef HAVE_SELINUX char *secontext = NULL; if (sehandle) { selabel_lookup(sehandle, &secontext, path, mode); setfscreatecon(secontext); } #endif rc = mkdir(path, mode); #ifdef HAVE_SELINUX if (secontext) { freecon(secontext); setfscreatecon(NULL); } #endif return rc; } static void add_platform_device(const char *name) { int name_len = strlen(name); Loading Loading @@ -506,7 +557,7 @@ static void handle_block_device_event(struct uevent *uevent) return; snprintf(devpath, sizeof(devpath), "%s%s", base, name); mkdir(base, 0755); make_dir(base, 0755); if (!strncmp(uevent->path, "/devices/platform/", 18)) links = parse_platform_block_device(uevent); Loading Loading @@ -535,10 +586,10 @@ static void handle_generic_device_event(struct uevent *uevent) int bus_id = uevent->minor / 128 + 1; int device_id = uevent->minor % 128 + 1; /* build directories */ mkdir("/dev/bus", 0755); mkdir("/dev/bus/usb", 0755); make_dir("/dev/bus", 0755); make_dir("/dev/bus/usb", 0755); snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d", bus_id); mkdir(devpath, 0755); make_dir(devpath, 0755); snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d/%03d", bus_id, device_id); } else { /* ignore other USB events */ Loading @@ -546,29 +597,29 @@ static void handle_generic_device_event(struct uevent *uevent) } } else if (!strncmp(uevent->subsystem, "graphics", 8)) { base = "/dev/graphics/"; mkdir(base, 0755); make_dir(base, 0755); } else if (!strncmp(uevent->subsystem, "oncrpc", 6)) { base = "/dev/oncrpc/"; mkdir(base, 0755); make_dir(base, 0755); } else if (!strncmp(uevent->subsystem, "adsp", 4)) { base = "/dev/adsp/"; mkdir(base, 0755); make_dir(base, 0755); } else if (!strncmp(uevent->subsystem, "msm_camera", 10)) { base = "/dev/msm_camera/"; mkdir(base, 0755); make_dir(base, 0755); } else if(!strncmp(uevent->subsystem, "input", 5)) { base = "/dev/input/"; mkdir(base, 0755); make_dir(base, 0755); } else if(!strncmp(uevent->subsystem, "mtd", 3)) { base = "/dev/mtd/"; mkdir(base, 0755); make_dir(base, 0755); } else if(!strncmp(uevent->subsystem, "sound", 5)) { base = "/dev/snd/"; mkdir(base, 0755); make_dir(base, 0755); } else if(!strncmp(uevent->subsystem, "misc", 4) && !strncmp(name, "log_", 4)) { base = "/dev/log/"; mkdir(base, 0755); make_dir(base, 0755); name += 4; } else base = "/dev/"; Loading Loading @@ -819,7 +870,14 @@ void device_init(void) suseconds_t t0, t1; 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); #endif /* is 64K enough? udev uses 16MB! */ device_fd = uevent_open_socket(64*1024, true); if(device_fd < 0) Loading init/init.c +175 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,13 @@ #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #ifdef HAVE_SELINUX #include <sys/mman.h> #include <selinux/selinux.h> #include <selinux/label.h> #endif #include <libgen.h> #include <cutils/list.h> Loading @@ -52,6 +59,10 @@ #include "util.h" #include "ueventd.h" #ifdef HAVE_SELINUX struct selabel_handle *sehandle; #endif static int property_triggers_enabled = 0; #if BOOTCHART Loading @@ -64,6 +75,11 @@ static char hardware[32]; static unsigned revision = 0; static char qemu[32]; #ifdef HAVE_SELINUX static int selinux_enabled = 1; static int selinux_enforcing = 0; #endif static struct action *cur_action = NULL; static struct command *cur_command = NULL; static struct listnode *command_queue = NULL; Loading Loading @@ -145,7 +161,10 @@ void service_start(struct service *svc, const char *dynamic_args) pid_t pid; int needs_console; int n; #ifdef HAVE_SELINUX char *scon = NULL; int rc; #endif /* starting a service removes it from the disabled or reset * state and immediately takes it out of the restarting * state if it was in there Loading Loading @@ -182,6 +201,34 @@ void service_start(struct service *svc, const char *dynamic_args) return; } #ifdef HAVE_SELINUX if (is_selinux_enabled() > 0) { char *mycon = NULL, *fcon = NULL; INFO("computing context for service '%s'\n", svc->args[0]); rc = getcon(&mycon); if (rc < 0) { ERROR("could not get context while starting '%s'\n", svc->name); return; } rc = getfilecon(svc->args[0], &fcon); if (rc < 0) { ERROR("could not get context while starting '%s'\n", svc->name); freecon(mycon); return; } rc = security_compute_create(mycon, fcon, string_to_security_class("process"), &scon); freecon(mycon); freecon(fcon); if (rc < 0) { ERROR("could not get context while starting '%s'\n", svc->name); return; } } #endif NOTICE("starting '%s'\n", svc->name); pid = fork(); Loading @@ -201,6 +248,10 @@ void service_start(struct service *svc, const char *dynamic_args) for (ei = svc->envvars; ei; ei = ei->next) add_environment(ei->name, ei->value); #ifdef HAVE_SELINUX setsockcreatecon(scon); #endif for (si = svc->sockets; si; si = si->next) { int socket_type = ( !strcmp(si->type, "stream") ? SOCK_STREAM : Loading @@ -212,6 +263,12 @@ void service_start(struct service *svc, const char *dynamic_args) } } #ifdef HAVE_SELINUX freecon(scon); scon = NULL; setsockcreatecon(NULL); #endif if (svc->ioprio_class != IoSchedClass_NONE) { if (android_set_ioprio(getpid(), svc->ioprio_class, svc->ioprio_pri)) { ERROR("Failed to set pid %d ioprio = %d,%d: %s\n", Loading Loading @@ -257,6 +314,15 @@ void service_start(struct service *svc, const char *dynamic_args) } } #ifdef HAVE_SELINUX if (svc->seclabel) { if (is_selinux_enabled() > 0 && setexeccon(svc->seclabel) < 0) { ERROR("cannot setexeccon('%s'): %s\n", svc->seclabel, strerror(errno)); _exit(127); } } #endif if (!dynamic_args) { if (execve(svc->args[0], (char**) svc->args, (char**) ENV) < 0) { ERROR("cannot execve('%s'): %s\n", svc->args[0], strerror(errno)); Loading @@ -282,6 +348,10 @@ void service_start(struct service *svc, const char *dynamic_args) _exit(127); } #ifdef HAVE_SELINUX freecon(scon); #endif if (pid < 0) { ERROR("failed to start '%s'\n", svc->name); svc->pid = 0; Loading Loading @@ -531,6 +601,14 @@ static void import_kernel_nv(char *name, int for_emulator) *value++ = 0; if (name_len == 0) return; #ifdef HAVE_SELINUX if (!strcmp(name,"enforcing")) { selinux_enforcing = atoi(value); } else if (!strcmp(name,"selinux")) { selinux_enabled = atoi(value); } #endif if (for_emulator) { /* in the emulator, export any kernel option with the * ro.kernel. prefix */ Loading Loading @@ -678,6 +756,97 @@ static int bootchart_init_action(int nargs, char **args) } #endif #ifdef HAVE_SELINUX void selinux_load_policy(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 = NULL; if (!selinux_enabled) { INFO("SELinux: Disabled by command line option\n"); return; } 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); 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; } rc = security_load_policy(map, sb.st_size); if (rc < 0) { ERROR("SELinux: Could not load policy: %s\n", strerror(errno)); return; } 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; } #endif int main(int argc, char **argv) { int fd_count = 0; Loading Loading @@ -728,6 +897,11 @@ int main(int argc, char **argv) process_kernel_cmdline(); #ifdef HAVE_SELINUX INFO("loading selinux policy\n"); selinux_load_policy(); #endif is_charger = !strcmp(bootmode, "charger"); INFO("property init\n"); Loading init/init.h +8 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,10 @@ struct service { gid_t supp_gids[NR_SVC_SUPP_GIDS]; size_t nr_supp_gids; #ifdef HAVE_SELINUX char *seclabel; #endif struct socketinfo *sockets; struct svcenvinfo *envvars; Loading Loading @@ -132,4 +136,8 @@ void property_changed(const char *name, const char *value); int load_565rle_image( char *file_name ); #ifdef HAVE_SELINUX extern struct selabel_handle *sehandle; #endif #endif /* _INIT_INIT_H */ Loading
init/Android.mk +6 −0 Original line number Diff line number Diff line Loading @@ -30,6 +30,12 @@ LOCAL_UNSTRIPPED_PATH := $(TARGET_ROOT_OUT_UNSTRIPPED) LOCAL_STATIC_LIBRARIES := libcutils libc ifeq ($(HAVE_SELINUX),true) LOCAL_STATIC_LIBRARIES += libselinux LOCAL_C_INCLUDES := external/libselinux/include LOCAL_CFLAGS += -DHAVE_SELINUX endif include $(BUILD_EXECUTABLE) # Make a symlink from /sbin/ueventd to /init Loading
init/builtins.c +85 −0 Original line number Diff line number Diff line Loading @@ -33,6 +33,11 @@ #include <cutils/partition_utils.h> #include <sys/system_properties.h> #ifdef HAVE_SELINUX #include <selinux/selinux.h> #include <selinux/label.h> #endif #include "init.h" #include "keywords.h" #include "property_service.h" Loading Loading @@ -436,6 +441,28 @@ exit_success: } int do_setcon(int nargs, char **args) { #ifdef HAVE_SELINUX if (is_selinux_enabled() <= 0) return 0; if (setcon(args[1]) < 0) { return -errno; } #endif return 0; } int do_setenforce(int nargs, char **args) { #ifdef HAVE_SELINUX if (is_selinux_enabled() <= 0) return 0; if (security_setenforce(atoi(args[1])) < 0) { return -errno; } #endif return 0; } int do_setkey(int nargs, char **args) { struct kbentry kbe; Loading Loading @@ -649,6 +676,64 @@ int do_chmod(int nargs, char **args) { return 0; } int do_restorecon(int nargs, char **args) { #ifdef HAVE_SELINUX char *secontext = NULL; struct stat sb; int i; if (is_selinux_enabled() <= 0 || !sehandle) return 0; for (i = 1; i < nargs; i++) { if (lstat(args[i], &sb) < 0) return -errno; if (selabel_lookup(sehandle, &secontext, args[i], sb.st_mode) < 0) return -errno; if (lsetfilecon(args[i], secontext) < 0) { freecon(secontext); return -errno; } freecon(secontext); } #endif return 0; } int do_setsebool(int nargs, char **args) { #ifdef HAVE_SELINUX SELboolean *b = alloca(nargs * sizeof(SELboolean)); char *v; int i; if (is_selinux_enabled() <= 0) return 0; for (i = 1; i < nargs; i++) { char *name = args[i]; v = strchr(name, '='); if (!v) { ERROR("setsebool: argument %s had no =\n", name); return -EINVAL; } *v++ = 0; b[i-1].name = name; if (!strcmp(v, "1") || !strcasecmp(v, "true") || !strcasecmp(v, "on")) b[i-1].value = 1; else if (!strcmp(v, "0") || !strcasecmp(v, "false") || !strcasecmp(v, "off")) b[i-1].value = 0; else { ERROR("setsebool: invalid value %s\n", v); return -EINVAL; } } if (security_set_boolean_list(nargs - 1, b, 0) < 0) return -errno; #endif return 0; } int do_loglevel(int nargs, char **args) { if (nargs == 2) { klog_set_level(atoi(args[1])); Loading
init/devices.c +70 −12 Original line number Diff line number Diff line Loading @@ -29,6 +29,12 @@ #include <sys/socket.h> #include <sys/un.h> #include <linux/netlink.h> #ifdef HAVE_SELINUX #include <selinux/selinux.h> #include <selinux/label.h> #endif #include <private/android_filesystem_config.h> #include <sys/time.h> #include <asm/page.h> Loading @@ -45,6 +51,10 @@ #define FIRMWARE_DIR1 "/etc/firmware" #define FIRMWARE_DIR2 "/vendor/firmware" #ifdef HAVE_SELINUX static struct selabel_handle *sehandle; #endif static int device_fd = -1; struct uevent { Loading Loading @@ -180,8 +190,17 @@ static void make_device(const char *path, unsigned gid; mode_t mode; dev_t dev; #ifdef HAVE_SELINUX char *secontext = NULL; #endif mode = get_device_perm(path, &uid, &gid) | (block ? S_IFBLK : S_IFCHR); #ifdef HAVE_SELINUX if (sehandle) { selabel_lookup(sehandle, &secontext, path, mode); setfscreatecon(secontext); } #endif dev = makedev(major, minor); /* Temporarily change egid to avoid race condition setting the gid of the * device node. Unforunately changing the euid would prevent creation of Loading @@ -192,8 +211,40 @@ static void make_device(const char *path, mknod(path, mode, dev); chown(path, uid, -1); setegid(AID_ROOT); #ifdef HAVE_SELINUX if (secontext) { freecon(secontext); setfscreatecon(NULL); } #endif } static int make_dir(const char *path, mode_t mode) { int rc; #ifdef HAVE_SELINUX char *secontext = NULL; if (sehandle) { selabel_lookup(sehandle, &secontext, path, mode); setfscreatecon(secontext); } #endif rc = mkdir(path, mode); #ifdef HAVE_SELINUX if (secontext) { freecon(secontext); setfscreatecon(NULL); } #endif return rc; } static void add_platform_device(const char *name) { int name_len = strlen(name); Loading Loading @@ -506,7 +557,7 @@ static void handle_block_device_event(struct uevent *uevent) return; snprintf(devpath, sizeof(devpath), "%s%s", base, name); mkdir(base, 0755); make_dir(base, 0755); if (!strncmp(uevent->path, "/devices/platform/", 18)) links = parse_platform_block_device(uevent); Loading Loading @@ -535,10 +586,10 @@ static void handle_generic_device_event(struct uevent *uevent) int bus_id = uevent->minor / 128 + 1; int device_id = uevent->minor % 128 + 1; /* build directories */ mkdir("/dev/bus", 0755); mkdir("/dev/bus/usb", 0755); make_dir("/dev/bus", 0755); make_dir("/dev/bus/usb", 0755); snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d", bus_id); mkdir(devpath, 0755); make_dir(devpath, 0755); snprintf(devpath, sizeof(devpath), "/dev/bus/usb/%03d/%03d", bus_id, device_id); } else { /* ignore other USB events */ Loading @@ -546,29 +597,29 @@ static void handle_generic_device_event(struct uevent *uevent) } } else if (!strncmp(uevent->subsystem, "graphics", 8)) { base = "/dev/graphics/"; mkdir(base, 0755); make_dir(base, 0755); } else if (!strncmp(uevent->subsystem, "oncrpc", 6)) { base = "/dev/oncrpc/"; mkdir(base, 0755); make_dir(base, 0755); } else if (!strncmp(uevent->subsystem, "adsp", 4)) { base = "/dev/adsp/"; mkdir(base, 0755); make_dir(base, 0755); } else if (!strncmp(uevent->subsystem, "msm_camera", 10)) { base = "/dev/msm_camera/"; mkdir(base, 0755); make_dir(base, 0755); } else if(!strncmp(uevent->subsystem, "input", 5)) { base = "/dev/input/"; mkdir(base, 0755); make_dir(base, 0755); } else if(!strncmp(uevent->subsystem, "mtd", 3)) { base = "/dev/mtd/"; mkdir(base, 0755); make_dir(base, 0755); } else if(!strncmp(uevent->subsystem, "sound", 5)) { base = "/dev/snd/"; mkdir(base, 0755); make_dir(base, 0755); } else if(!strncmp(uevent->subsystem, "misc", 4) && !strncmp(name, "log_", 4)) { base = "/dev/log/"; mkdir(base, 0755); make_dir(base, 0755); name += 4; } else base = "/dev/"; Loading Loading @@ -819,7 +870,14 @@ void device_init(void) suseconds_t t0, t1; 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); #endif /* is 64K enough? udev uses 16MB! */ device_fd = uevent_open_socket(64*1024, true); if(device_fd < 0) Loading
init/init.c +175 −1 Original line number Diff line number Diff line Loading @@ -31,6 +31,13 @@ #include <sys/types.h> #include <sys/socket.h> #include <sys/un.h> #ifdef HAVE_SELINUX #include <sys/mman.h> #include <selinux/selinux.h> #include <selinux/label.h> #endif #include <libgen.h> #include <cutils/list.h> Loading @@ -52,6 +59,10 @@ #include "util.h" #include "ueventd.h" #ifdef HAVE_SELINUX struct selabel_handle *sehandle; #endif static int property_triggers_enabled = 0; #if BOOTCHART Loading @@ -64,6 +75,11 @@ static char hardware[32]; static unsigned revision = 0; static char qemu[32]; #ifdef HAVE_SELINUX static int selinux_enabled = 1; static int selinux_enforcing = 0; #endif static struct action *cur_action = NULL; static struct command *cur_command = NULL; static struct listnode *command_queue = NULL; Loading Loading @@ -145,7 +161,10 @@ void service_start(struct service *svc, const char *dynamic_args) pid_t pid; int needs_console; int n; #ifdef HAVE_SELINUX char *scon = NULL; int rc; #endif /* starting a service removes it from the disabled or reset * state and immediately takes it out of the restarting * state if it was in there Loading Loading @@ -182,6 +201,34 @@ void service_start(struct service *svc, const char *dynamic_args) return; } #ifdef HAVE_SELINUX if (is_selinux_enabled() > 0) { char *mycon = NULL, *fcon = NULL; INFO("computing context for service '%s'\n", svc->args[0]); rc = getcon(&mycon); if (rc < 0) { ERROR("could not get context while starting '%s'\n", svc->name); return; } rc = getfilecon(svc->args[0], &fcon); if (rc < 0) { ERROR("could not get context while starting '%s'\n", svc->name); freecon(mycon); return; } rc = security_compute_create(mycon, fcon, string_to_security_class("process"), &scon); freecon(mycon); freecon(fcon); if (rc < 0) { ERROR("could not get context while starting '%s'\n", svc->name); return; } } #endif NOTICE("starting '%s'\n", svc->name); pid = fork(); Loading @@ -201,6 +248,10 @@ void service_start(struct service *svc, const char *dynamic_args) for (ei = svc->envvars; ei; ei = ei->next) add_environment(ei->name, ei->value); #ifdef HAVE_SELINUX setsockcreatecon(scon); #endif for (si = svc->sockets; si; si = si->next) { int socket_type = ( !strcmp(si->type, "stream") ? SOCK_STREAM : Loading @@ -212,6 +263,12 @@ void service_start(struct service *svc, const char *dynamic_args) } } #ifdef HAVE_SELINUX freecon(scon); scon = NULL; setsockcreatecon(NULL); #endif if (svc->ioprio_class != IoSchedClass_NONE) { if (android_set_ioprio(getpid(), svc->ioprio_class, svc->ioprio_pri)) { ERROR("Failed to set pid %d ioprio = %d,%d: %s\n", Loading Loading @@ -257,6 +314,15 @@ void service_start(struct service *svc, const char *dynamic_args) } } #ifdef HAVE_SELINUX if (svc->seclabel) { if (is_selinux_enabled() > 0 && setexeccon(svc->seclabel) < 0) { ERROR("cannot setexeccon('%s'): %s\n", svc->seclabel, strerror(errno)); _exit(127); } } #endif if (!dynamic_args) { if (execve(svc->args[0], (char**) svc->args, (char**) ENV) < 0) { ERROR("cannot execve('%s'): %s\n", svc->args[0], strerror(errno)); Loading @@ -282,6 +348,10 @@ void service_start(struct service *svc, const char *dynamic_args) _exit(127); } #ifdef HAVE_SELINUX freecon(scon); #endif if (pid < 0) { ERROR("failed to start '%s'\n", svc->name); svc->pid = 0; Loading Loading @@ -531,6 +601,14 @@ static void import_kernel_nv(char *name, int for_emulator) *value++ = 0; if (name_len == 0) return; #ifdef HAVE_SELINUX if (!strcmp(name,"enforcing")) { selinux_enforcing = atoi(value); } else if (!strcmp(name,"selinux")) { selinux_enabled = atoi(value); } #endif if (for_emulator) { /* in the emulator, export any kernel option with the * ro.kernel. prefix */ Loading Loading @@ -678,6 +756,97 @@ static int bootchart_init_action(int nargs, char **args) } #endif #ifdef HAVE_SELINUX void selinux_load_policy(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 = NULL; if (!selinux_enabled) { INFO("SELinux: Disabled by command line option\n"); return; } 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); 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; } rc = security_load_policy(map, sb.st_size); if (rc < 0) { ERROR("SELinux: Could not load policy: %s\n", strerror(errno)); return; } 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; } #endif int main(int argc, char **argv) { int fd_count = 0; Loading Loading @@ -728,6 +897,11 @@ int main(int argc, char **argv) process_kernel_cmdline(); #ifdef HAVE_SELINUX INFO("loading selinux policy\n"); selinux_load_policy(); #endif is_charger = !strcmp(bootmode, "charger"); INFO("property init\n"); Loading
init/init.h +8 −0 Original line number Diff line number Diff line Loading @@ -95,6 +95,10 @@ struct service { gid_t supp_gids[NR_SVC_SUPP_GIDS]; size_t nr_supp_gids; #ifdef HAVE_SELINUX char *seclabel; #endif struct socketinfo *sockets; struct svcenvinfo *envvars; Loading Loading @@ -132,4 +136,8 @@ void property_changed(const char *name, const char *value); int load_565rle_image( char *file_name ); #ifdef HAVE_SELINUX extern struct selabel_handle *sehandle; #endif #endif /* _INIT_INIT_H */