diff options
-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 | 2 | ||||
-rw-r--r-- | init/readme.txt | 5 | ||||
-rw-r--r-- | init/util.c | 19 | ||||
-rw-r--r-- | init/util.h | 2 |
7 files changed, 24 insertions, 14 deletions
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 9afc756..a20f7ab 100644 --- a/init/property_service.c +++ b/init/property_service.c @@ -555,7 +555,7 @@ void start_property_service(void) /* 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..154bb2d 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); 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); |