diff options
Diffstat (limited to 'init')
-rw-r--r-- | init/devices.c | 11 | ||||
-rw-r--r-- | init/init.c | 5 | ||||
-rw-r--r-- | init/init.h | 1 | ||||
-rw-r--r-- | init/init_parser.c | 4 | ||||
-rw-r--r-- | init/property_service.c | 25 | ||||
-rw-r--r-- | init/readme.txt | 5 | ||||
-rw-r--r-- | init/util.c | 23 | ||||
-rw-r--r-- | init/util.h | 2 |
8 files changed, 53 insertions, 23 deletions
diff --git a/init/devices.c b/init/devices.c index 1893642..af88c5f 100644 --- a/init/devices.c +++ b/init/devices.c @@ -33,6 +33,7 @@ #include <selinux/selinux.h> #include <selinux/label.h> #include <selinux/android.h> +#include <selinux/avc.h> #include <private/android_filesystem_config.h> #include <sys/time.h> @@ -830,6 +831,15 @@ void handle_device_fd() struct uevent uevent; parse_event(msg, &uevent); + if (sehandle && selinux_status_updated() > 0) { + struct selabel_handle *sehandle2; + sehandle2 = selinux_android_file_context_handle(); + if (sehandle2) { + selabel_close(sehandle); + sehandle = sehandle2; + } + } + handle_device_event(&uevent); handle_firmware_event(&uevent); } @@ -896,6 +906,7 @@ void device_init(void) sehandle = NULL; if (is_selinux_enabled() > 0) { sehandle = selinux_android_file_context_handle(); + selinux_status_open(true); } /* is 256K enough? udev uses 16MB! */ diff --git a/init/init.c b/init/init.c index 94a2011..feac8ad 100644 --- a/init/init.c +++ b/init/init.c @@ -250,14 +250,12 @@ void service_start(struct service *svc, const char *dynamic_args) for (ei = svc->envvars; ei; ei = ei->next) add_environment(ei->name, ei->value); - setsockcreatecon(scon); - for (si = svc->sockets; si; si = si->next) { int socket_type = ( !strcmp(si->type, "stream") ? SOCK_STREAM : (!strcmp(si->type, "dgram") ? SOCK_DGRAM : SOCK_SEQPACKET)); int s = create_socket(si->name, socket_type, - si->perm, si->uid, si->gid); + si->perm, si->uid, si->gid, si->socketcon ?: scon); if (s >= 0) { publish_socket(si->name, s); } @@ -265,7 +263,6 @@ void service_start(struct service *svc, const char *dynamic_args) freecon(scon); scon = NULL; - setsockcreatecon(NULL); if (svc->ioprio_class != IoSchedClass_NONE) { if (android_set_ioprio(getpid(), svc->ioprio_class, svc->ioprio_pri)) { diff --git a/init/init.h b/init/init.h index aa6a4ab..3928d52 100644 --- a/init/init.h +++ b/init/init.h @@ -55,6 +55,7 @@ struct socketinfo { uid_t uid; gid_t gid; int perm; + const char *socketcon; }; struct svcenvinfo { diff --git a/init/init_parser.c b/init/init_parser.c index 776c699..7c2fa8c 100644 --- a/init/init_parser.c +++ b/init/init_parser.c @@ -771,7 +771,7 @@ static void parse_line_service(struct parse_state *state, int nargs, char **args svc->envvars = ei; break; } - case K_socket: {/* name type perm [ uid gid ] */ + case K_socket: {/* name type perm [ uid gid context ] */ struct socketinfo *si; if (nargs < 4) { parse_error(state, "socket option requires name, type, perm arguments\n"); @@ -794,6 +794,8 @@ static void parse_line_service(struct parse_state *state, int nargs, char **args si->uid = decode_uid(args[4]); if (nargs > 5) si->gid = decode_uid(args[5]); + if (nargs > 6) + si->socketcon = args[6]; si->next = svc->sockets; svc->sockets = si; break; diff --git a/init/property_service.c b/init/property_service.c index 9ac2781..c370769 100644 --- a/init/property_service.c +++ b/init/property_service.c @@ -81,6 +81,7 @@ struct { { "sys.powerctl", AID_SHELL, 0 }, { "service.", AID_SYSTEM, 0 }, { "wlan.", AID_SYSTEM, 0 }, + { "gps.", AID_GPS, 0 }, { "bluetooth.", AID_BLUETOOTH, 0 }, { "dhcp.", AID_SYSTEM, 0 }, { "dhcp.", AID_DHCP, 0 }, @@ -92,6 +93,7 @@ struct { { "persist.sys.", AID_SYSTEM, 0 }, { "persist.service.", AID_SYSTEM, 0 }, { "persist.security.", AID_SYSTEM, 0 }, + { "persist.gps.", AID_GPS, 0 }, { "persist.service.bdroid.", AID_BLUETOOTH, 0 }, { "selinux." , AID_SYSTEM, 0 }, { NULL, 0, 0 } @@ -437,10 +439,13 @@ void get_property_workspace(int *fd, int *sz) *sz = pa_workspace.size; } -static void load_properties(char *data) +static void load_properties(char *data, char *prefix) { char *key, *value, *eol, *sol, *tmp; + size_t plen; + if (prefix) + plen = strlen(prefix); sol = data; while((eol = strchr(sol, '\n'))) { key = sol; @@ -456,6 +461,9 @@ static void load_properties(char *data) tmp = value - 2; while((tmp > key) && isspace(*tmp)) *tmp-- = 0; + if (prefix && strncmp(key, prefix, plen)) + continue; + while(isspace(*value)) value++; tmp = eol - 2; while((tmp > value) && isspace(*tmp)) *tmp-- = 0; @@ -464,7 +472,7 @@ static void load_properties(char *data) } } -static void load_properties_from_file(const char *fn) +static void load_properties_from_file(const char *fn, char *prefix) { char *data; unsigned sz; @@ -472,7 +480,7 @@ static void load_properties_from_file(const char *fn) data = read_file(fn, &sz); if(data != 0) { - load_properties(data); + load_properties(data, prefix); free(data); } } @@ -545,7 +553,7 @@ void property_init(void) void property_load_boot_defaults(void) { - load_properties_from_file(PROP_PATH_RAMDISK_DEFAULT); + load_properties_from_file(PROP_PATH_RAMDISK_DEFAULT, NULL); } int properties_inited(void) @@ -560,7 +568,7 @@ static void load_override_properties() { ret = property_get("ro.debuggable", debuggable); if (ret && (strcmp(debuggable, "1") == 0)) { - load_properties_from_file(PROP_PATH_LOCAL_OVERRIDE); + load_properties_from_file(PROP_PATH_LOCAL_OVERRIDE, NULL); } #endif /* ALLOW_LOCAL_PROP_OVERRIDE */ } @@ -582,13 +590,14 @@ void start_property_service(void) { int fd; - load_properties_from_file(PROP_PATH_SYSTEM_BUILD); - load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT); + load_properties_from_file(PROP_PATH_SYSTEM_BUILD, NULL); + load_properties_from_file(PROP_PATH_SYSTEM_DEFAULT, NULL); + load_properties_from_file(PROP_PATH_FACTORY, "ro."); load_override_properties(); /* Read persistent properties after all default values have been loaded. */ load_persistent_properties(); - fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM, 0666, 0, 0); + fd = create_socket(PROP_SERVICE_NAME, SOCK_STREAM, 0666, 0, 0, NULL); if(fd < 0) return; fcntl(fd, F_SETFD, FD_CLOEXEC); fcntl(fd, F_SETFL, O_NONBLOCK); diff --git a/init/readme.txt b/init/readme.txt index 7a5997d..1e8c392 100644 --- a/init/readme.txt +++ b/init/readme.txt @@ -70,10 +70,13 @@ disabled setenv <name> <value> Set the environment variable <name> to <value> in the launched process. -socket <name> <type> <perm> [ <user> [ <group> ] ] +socket <name> <type> <perm> [ <user> [ <group> [ <context> ] ] ] Create a unix domain socket named /dev/socket/<name> and pass its fd to the launched process. <type> must be "dgram", "stream" or "seqpacket". User and group default to 0. + Context is the SELinux security context for the socket. + It defaults to the service security context, as specified by seclabel or + computed based on the service executable file security context. user <username> Change to username before exec'ing this service. diff --git a/init/util.c b/init/util.c index 1908b3a..078b99b 100644 --- a/init/util.c +++ b/init/util.c @@ -84,11 +84,15 @@ unsigned int decode_uid(const char *s) * daemon. We communicate the file descriptor's value via the environment * variable ANDROID_SOCKET_ENV_PREFIX<name> ("ANDROID_SOCKET_foo"). */ -int create_socket(const char *name, int type, mode_t perm, uid_t uid, gid_t gid) +int create_socket(const char *name, int type, mode_t perm, uid_t uid, + gid_t gid, const char *socketcon) { struct sockaddr_un addr; int fd, ret; - char *secon; + char *filecon; + + if (socketcon) + setsockcreatecon(socketcon); fd = socket(PF_UNIX, type, 0); if (fd < 0) { @@ -96,6 +100,9 @@ int create_socket(const char *name, int type, mode_t perm, uid_t uid, gid_t gid) return -1; } + if (socketcon) + setsockcreatecon(NULL); + memset(&addr, 0 , sizeof(addr)); addr.sun_family = AF_UNIX; snprintf(addr.sun_path, sizeof(addr.sun_path), ANDROID_SOCKET_DIR"/%s", @@ -107,11 +114,11 @@ int create_socket(const char *name, int type, mode_t perm, uid_t uid, gid_t gid) goto out_close; } - secon = NULL; + filecon = NULL; if (sehandle) { - ret = selabel_lookup(sehandle, &secon, addr.sun_path, S_IFSOCK); + ret = selabel_lookup(sehandle, &filecon, addr.sun_path, S_IFSOCK); if (ret == 0) - setfscreatecon(secon); + setfscreatecon(filecon); } ret = bind(fd, (struct sockaddr *) &addr, sizeof (addr)); @@ -121,7 +128,7 @@ int create_socket(const char *name, int type, mode_t perm, uid_t uid, gid_t gid) } setfscreatecon(NULL); - freecon(secon); + freecon(filecon); chown(addr.sun_path, uid, gid); chmod(addr.sun_path, perm); @@ -443,13 +450,13 @@ void get_hardware_name(char *hardware, unsigned int *revision) void import_kernel_cmdline(int in_qemu, void (*import_kernel_nv)(char *name, int in_qemu)) { - char cmdline[1024]; + char cmdline[2048]; char *ptr; int fd; fd = open("/proc/cmdline", O_RDONLY); if (fd >= 0) { - int n = read(fd, cmdline, 1023); + int n = read(fd, cmdline, sizeof(cmdline) - 1); if (n < 0) n = 0; /* get rid of trailing newline, it happens */ diff --git a/init/util.h b/init/util.h index 6bca4e6..04b8129 100644 --- a/init/util.h +++ b/init/util.h @@ -26,7 +26,7 @@ static const char *coldboot_done = "/dev/.coldboot_done"; int mtd_name_to_number(const char *name); int create_socket(const char *name, int type, mode_t perm, - uid_t uid, gid_t gid); + uid_t uid, gid_t gid, const char *socketcon); void *read_file(const char *fn, unsigned *_sz); time_t gettime(void); unsigned int decode_uid(const char *s); |