summaryrefslogtreecommitdiffstats
path: root/init
diff options
context:
space:
mode:
Diffstat (limited to 'init')
-rw-r--r--init/devices.c11
-rw-r--r--init/init.c5
-rw-r--r--init/init.h1
-rw-r--r--init/init_parser.c4
-rw-r--r--init/property_service.c25
-rw-r--r--init/readme.txt5
-rw-r--r--init/util.c23
-rw-r--r--init/util.h2
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);