Merge "Add support for socket security context specification."
This commit is contained in:
commit
a8ba1f2f0b
7 changed files with 24 additions and 14 deletions
|
@ -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)) {
|
||||
|
|
|
@ -55,6 +55,7 @@ struct socketinfo {
|
|||
uid_t uid;
|
||||
gid_t gid;
|
||||
int perm;
|
||||
const char *socketcon;
|
||||
};
|
||||
|
||||
struct svcenvinfo {
|
||||
|
|
|
@ -768,7 +768,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");
|
||||
|
@ -791,6 +791,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;
|
||||
|
|
|
@ -554,7 +554,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);
|
||||
|
|
|
@ -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.
|
||||
|
|
19
init/util.c
19
init/util.c
|
@ -83,11 +83,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) {
|
||||
|
@ -95,6 +99,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",
|
||||
|
@ -106,11 +113,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));
|
||||
|
@ -120,7 +127,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);
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in a new issue