From 4a762357d05fe2152dbe5d4b7085d01a5d4ccbf2 Mon Sep 17 00:00:00 2001 From: Jack Veenstra Date: Tue, 5 May 2009 11:48:17 -0700 Subject: Make the /dev/qemu_trace device readable and writable by all. This is needed so that the Dalvik interpreter can add information about Java method entry/exit to the traces when running in the qemu emulator. --- init/devices.c | 1 + 1 file changed, 1 insertion(+) (limited to 'init') diff --git a/init/devices.c b/init/devices.c index b1ef6ab2..b914c539 100644 --- a/init/devices.c +++ b/init/devices.c @@ -126,6 +126,7 @@ static struct perms_ devperms[] = { { "/dev/msm_audpre", 0660, AID_SYSTEM, AID_AUDIO, 0 }, { "/dev/htc-acoustic", 0660, AID_SYSTEM, AID_AUDIO, 0 }, { "/dev/smd0", 0640, AID_RADIO, AID_RADIO, 0 }, + { "/dev/qemu_trace", 0666, AID_SYSTEM, AID_SYSTEM, 0 }, { "/dev/qmi", 0640, AID_RADIO, AID_RADIO, 0 }, { "/dev/qmi0", 0640, AID_RADIO, AID_RADIO, 0 }, { "/dev/qmi1", 0640, AID_RADIO, AID_RADIO, 0 }, -- cgit v1.2.3 From 770354d7e6cd471daed426fcf04bf7246e7cb18b Mon Sep 17 00:00:00 2001 From: Dima Zavin Date: Tue, 5 May 2009 18:33:07 -0700 Subject: init: Fix segfault when log_write() was missing an arg to format. Also, flag log_write() as a printf-like beast to gcc. Signed-off-by: Dima Zavin --- init/init.c | 2 +- init/init.h | 3 ++- 2 files changed, 3 insertions(+), 2 deletions(-) (limited to 'init') diff --git a/init/init.c b/init/init.c index b8b4f403..a748ec36 100644 --- a/init/init.c +++ b/init/init.c @@ -421,7 +421,7 @@ static void msg_stop(const char *name) if (svc) { service_stop(svc); } else { - ERROR("no such service '%s'\n"); + ERROR("no such service '%s'\n", name); } } diff --git a/init/init.h b/init/init.h index b6868693..c9363daf 100644 --- a/init/init.h +++ b/init/init.h @@ -29,7 +29,8 @@ void *read_file(const char *fn, unsigned *_sz); void log_init(void); void log_set_level(int level); void log_close(void); -void log_write(int level, const char *fmt, ...); +void log_write(int level, const char *fmt, ...) + __attribute__ ((format(printf, 2, 3))); #define ERROR(x...) log_write(3, "<3>init: " x) #define NOTICE(x...) log_write(5, "<5>init: " x) -- cgit v1.2.3 From b3779558dcfbe99f0b9c1ef796e3728edad25672 Mon Sep 17 00:00:00 2001 From: Mike Lockwood Date: Fri, 8 May 2009 14:27:42 -0400 Subject: init: Fix some broken code that did not cause problems until switching to gcc 4.4 Signed-off-by: Mike Lockwood --- init/parser.c | 4 ++-- init/property_service.c | 7 +++---- 2 files changed, 5 insertions(+), 6 deletions(-) (limited to 'init') diff --git a/init/parser.c b/init/parser.c index 6a22d242..30fa3de6 100644 --- a/init/parser.c +++ b/init/parser.c @@ -536,7 +536,7 @@ void queue_all_property_triggers() const char* name = act->name + strlen("property:"); const char* equals = strchr(name, '='); if (equals) { - char* prop_name[PROP_NAME_MAX + 1]; + char prop_name[PROP_NAME_MAX + 1]; const char* value; int length = equals - name; if (length > PROP_NAME_MAX) { @@ -546,7 +546,7 @@ void queue_all_property_triggers() prop_name[length] = 0; /* does the property exist, and match the trigger value? */ - value = property_get((const char *)&prop_name[0]); + value = property_get(prop_name); if (value && !strcmp(equals + 1, value)) { action_add_queue_tail(act); } diff --git a/init/property_service.c b/init/property_service.c index 0bc62392..48ca3ea3 100644 --- a/init/property_service.c +++ b/init/property_service.c @@ -296,7 +296,7 @@ int property_set(const char *name, const char *value) __futex_wake(&pa->serial, INT32_MAX); } /* If name starts with "net." treat as a DNS property. */ - if (strncmp("net.", name, sizeof("net.") - 1) == 0) { + if (strncmp("net.", name, strlen("net.")) == 0) { if (strcmp("net.change", name) == 0) { return 0; } @@ -307,7 +307,7 @@ int property_set(const char *name, const char *value) */ property_set("net.change", name); } else if (persistent_properties_loaded && - strncmp("persist.", name, sizeof("persist.") - 1) == 0) { + strncmp("persist.", name, strlen("persist.")) == 0) { /* * Don't write properties to disk until after we have read all default properties * to prevent them from being overwritten by default values. @@ -446,8 +446,7 @@ static void load_persistent_properties() if (dir) { while ((entry = readdir(dir)) != NULL) { - if (!strcmp(entry->d_name, ".") || !strcmp(entry->d_name, "..") || - strncmp("persist.", entry->d_name, sizeof("persist.") - 1)) + if (strncmp("persist.", entry->d_name, strlen("persist."))) continue; #if HAVE_DIRENT_D_TYPE if (entry->d_type != DT_REG) -- cgit v1.2.3 From c83cd879d45e667fbb4763f18c908928ee9d67d8 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Thu, 14 May 2009 14:54:22 -0700 Subject: init: Fix heap corruption for services with arguments The 'args' array *must* be the last entry in the structure. This fixes a longstanding issue (apparently since tc3) where a service with an argument would corrupt the heap. The more arguments, the more corruption :|. This will probably also end up making key-code bound services more reliable (ie: bugreports triggered via the keyboard) Signed-off-by: San Mehat --- init/init.h | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'init') diff --git a/init/init.h b/init/init.h index c9363daf..b93eb50a 100644 --- a/init/init.h +++ b/init/init.h @@ -137,15 +137,17 @@ struct service { struct socketinfo *sockets; struct svcenvinfo *envvars; - int nargs; - char *args[1]; struct action onrestart; /* Actions to execute on restart. */ /* keycodes for triggering this service via /dev/keychord */ int *keycodes; int nkeycodes; int keychord_id; -}; + + int nargs; + /* "MUST BE AT THE END OF THE STRUCT" */ + char *args[1]; +}; /* ^-------'args' MUST be at the end of this struct! */ int parse_config_file(const char *fn); -- cgit v1.2.3 From 4a6f2321e76685b9489d020980dffb1d9ac73fc0 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Thu, 14 May 2009 19:44:59 -0700 Subject: init: Create new 'vpn' user/group and set owner of '/dev/tun' to it. Signed-off-by: San Mehat --- init/devices.c | 1 + 1 file changed, 1 insertion(+) (limited to 'init') diff --git a/init/devices.c b/init/devices.c index b914c539..c278607d 100644 --- a/init/devices.c +++ b/init/devices.c @@ -131,6 +131,7 @@ static struct perms_ devperms[] = { { "/dev/qmi0", 0640, AID_RADIO, AID_RADIO, 0 }, { "/dev/qmi1", 0640, AID_RADIO, AID_RADIO, 0 }, { "/dev/qmi2", 0640, AID_RADIO, AID_RADIO, 0 }, + { "/dev/tun", 0640, AID_VPN , AID_VPN, 0 }, { NULL, 0, 0, 0, 0 }, }; -- cgit v1.2.3 From f24e252903ca0f71c7fbfb135cf17e83e0c2ea90 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Tue, 19 May 2009 13:30:46 -0700 Subject: init: Add the ability to start services with dynamic arguments. To add arguments dynamically to a service, start the service like so: setprop ctl.start service_to_run:arg1 arg2 arg3... To start a service with *no* dynamic arguments, start the service normally: setprop ctl.start service_to_run Dynamic arguments are only supported on 'oneshot' services Signed-off-by: San Mehat --- init/builtins.c | 6 ++--- init/init.c | 77 ++++++++++++++++++++++++++++++++++++++++++++++++++++----- init/init.h | 4 ++- init/parser.c | 6 ++--- 4 files changed, 79 insertions(+), 14 deletions(-) (limited to 'init') diff --git a/init/builtins.c b/init/builtins.c index 95fb2230..17df0af5 100644 --- a/init/builtins.c +++ b/init/builtins.c @@ -126,7 +126,7 @@ done: static void service_start_if_not_disabled(struct service *svc) { if (!(svc->flags & SVC_DISABLED)) { - service_start(svc); + service_start(svc, NULL); } } @@ -316,7 +316,7 @@ int do_start(int nargs, char **args) struct service *svc; svc = service_find_by_name(args[1]); if (svc) { - service_start(svc); + service_start(svc, NULL); } return 0; } @@ -337,7 +337,7 @@ int do_restart(int nargs, char **args) svc = service_find_by_name(args[1]); if (svc) { service_stop(svc); - service_start(svc); + service_start(svc, NULL); } return 0; } diff --git a/init/init.c b/init/init.c index a748ec36..b3505691 100644 --- a/init/init.c +++ b/init/init.c @@ -156,7 +156,7 @@ static void publish_socket(const char *name, int fd) fcntl(fd, F_SETFD, 0); } -void service_start(struct service *svc) +void service_start(struct service *svc, const char *dynamic_args) { struct stat s; pid_t pid; @@ -192,6 +192,12 @@ void service_start(struct service *svc) return; } + if ((!(svc->flags & SVC_ONESHOT)) && dynamic_args) { + ERROR("service '%s' must be one-shot to use dynamic args, disabling\n", svc->args[0]); + svc->flags |= SVC_DISABLED; + return; + } + NOTICE("starting '%s'\n", svc->name); pid = fork(); @@ -248,7 +254,50 @@ void service_start(struct service *svc) setuid(svc->uid); } - execve(svc->args[0], (char**) svc->args, (char**) ENV); + if (!dynamic_args) + execve(svc->args[0], (char**) svc->args, (char**) ENV); + else { + char *arg_ptrs[SVC_MAXARGS+1]; + int arg_idx; + char *tmp = strdup(dynamic_args); + char *p = tmp; + + /* Copy the static arguments */ + for (arg_idx = 0; arg_idx < svc->nargs; arg_idx++) { + arg_ptrs[arg_idx] = svc->args[arg_idx]; + } + + int done = 0; + while(!done) { + + if (arg_idx == SVC_MAXARGS) + break; + + /* Advance over any leading whitespace */ + if (*p == ' ') { + for (p; *p != ' '; p++); + p++; + } + /* Locate next argument */ + char *q = p; + while(1) { + if (*q == ' ') { + *q = '\0'; + break; + } else if (*q == '\0') { + done = 1; + break; + } + q++; + } + arg_ptrs[arg_idx++] = p; + + q++; // Advance q to the next string + p = q; + } + arg_ptrs[arg_idx] = '\0'; + execve(svc->args[0], (char**) arg_ptrs, (char**) ENV); + } _exit(127); } @@ -379,7 +428,7 @@ static void restart_service_if_needed(struct service *svc) if (next_start_time <= gettime()) { svc->flags &= (~SVC_RESTARTING); - service_start(svc); + service_start(svc, NULL); return; } @@ -405,13 +454,29 @@ static void sigchld_handler(int s) static void msg_start(const char *name) { - struct service *svc = service_find_by_name(name); + struct service *svc; + char *tmp = NULL; + char *args = NULL; + + if (!strchr(name, ':')) + svc = service_find_by_name(name); + else { + tmp = strdup(name); + strcpy(tmp, name); + args = strchr(tmp, ':'); + *args = '\0'; + args++; + + svc = service_find_by_name(tmp); + } if (svc) { - service_start(svc); + service_start(svc, args); } else { ERROR("no such service '%s'\n", name); } + if (tmp) + free(tmp); } static void msg_stop(const char *name) @@ -737,7 +802,7 @@ void handle_keychord(int fd) svc = service_find_by_keychord(id); if (svc) { INFO("starting service %s from keychord\n", svc->name); - service_start(svc); + service_start(svc, NULL); } else { ERROR("service for keychord %d not found\n", id); } diff --git a/init/init.h b/init/init.h index b93eb50a..f306b7bc 100644 --- a/init/init.h +++ b/init/init.h @@ -116,6 +116,8 @@ struct svcenvinfo { #define NR_SVC_SUPP_GIDS 6 /* six supplementary groups */ +#define SVC_MAXARGS 64 + struct service { /* list of all services */ struct listnode slist; @@ -160,7 +162,7 @@ void service_for_each_class(const char *classname, void service_for_each_flags(unsigned matchflags, void (*func)(struct service *svc)); void service_stop(struct service *svc); -void service_start(struct service *svc); +void service_start(struct service *svc, const char *dynamic_args); void property_changed(const char *name, const char *value); struct action *action_remove_queue_head(void); diff --git a/init/parser.c b/init/parser.c index 30fa3de6..33c1a681 100644 --- a/init/parser.c +++ b/init/parser.c @@ -60,8 +60,6 @@ void DUMP(void) #endif } -#define MAXARGS 64 - #define T_EOF 0 #define T_TEXT 1 #define T_NEWLINE 2 @@ -357,7 +355,7 @@ void parse_new_section(struct parse_state *state, int kw, static void parse_config(const char *fn, char *s) { struct parse_state state; - char *args[MAXARGS]; + char *args[SVC_MAXARGS]; int nargs; nargs = 0; @@ -384,7 +382,7 @@ static void parse_config(const char *fn, char *s) } break; case T_TEXT: - if (nargs < MAXARGS) { + if (nargs < SVC_MAXARGS) { args[nargs++] = state.text; } break; -- cgit v1.2.3 From d4cdd13f6f56f3fe8d8511b609e823925fdd83f9 Mon Sep 17 00:00:00 2001 From: San Mehat Date: Wed, 20 May 2009 09:52:16 -0700 Subject: init: Clean up dynamic argument handling for services Signed-off-by: San Mehat --- init/init.c | 44 ++++++++++---------------------------------- 1 file changed, 10 insertions(+), 34 deletions(-) (limited to 'init') diff --git a/init/init.c b/init/init.c index b3505691..0c1ad3fa 100644 --- a/init/init.c +++ b/init/init.c @@ -193,7 +193,8 @@ void service_start(struct service *svc, const char *dynamic_args) } if ((!(svc->flags & SVC_ONESHOT)) && dynamic_args) { - ERROR("service '%s' must be one-shot to use dynamic args, disabling\n", svc->args[0]); + ERROR("service '%s' must be one-shot to use dynamic args, disabling\n", + svc->args[0]); svc->flags |= SVC_DISABLED; return; } @@ -258,42 +259,18 @@ void service_start(struct service *svc, const char *dynamic_args) execve(svc->args[0], (char**) svc->args, (char**) ENV); else { char *arg_ptrs[SVC_MAXARGS+1]; - int arg_idx; + int arg_idx = svc->nargs; char *tmp = strdup(dynamic_args); - char *p = tmp; + char *next = tmp; + char *bword; /* Copy the static arguments */ - for (arg_idx = 0; arg_idx < svc->nargs; arg_idx++) { - arg_ptrs[arg_idx] = svc->args[arg_idx]; - } - - int done = 0; - while(!done) { + memcpy(arg_ptrs, svc->args, (svc->nargs * sizeof(char *))); - if (arg_idx == SVC_MAXARGS) + while((bword = strsep(&next, " "))) { + arg_ptrs[arg_idx++] = bword; + if (arg_idx == SVC_MAXARGS) break; - - /* Advance over any leading whitespace */ - if (*p == ' ') { - for (p; *p != ' '; p++); - p++; - } - /* Locate next argument */ - char *q = p; - while(1) { - if (*q == ' ') { - *q = '\0'; - break; - } else if (*q == '\0') { - done = 1; - break; - } - q++; - } - arg_ptrs[arg_idx++] = p; - - q++; // Advance q to the next string - p = q; } arg_ptrs[arg_idx] = '\0'; execve(svc->args[0], (char**) arg_ptrs, (char**) ENV); @@ -462,7 +439,6 @@ static void msg_start(const char *name) svc = service_find_by_name(name); else { tmp = strdup(name); - strcpy(tmp, name); args = strchr(tmp, ':'); *args = '\0'; args++; @@ -802,7 +778,7 @@ void handle_keychord(int fd) svc = service_find_by_keychord(id); if (svc) { INFO("starting service %s from keychord\n", svc->name); - service_start(svc, NULL); + service_start(svc, NULL); } else { ERROR("service for keychord %d not found\n", id); } -- cgit v1.2.3 From fc0182eb1db0620eb71fb6ca219b15a17dcd912f Mon Sep 17 00:00:00 2001 From: Iliyan Malchev Date: Fri, 1 May 2009 10:25:05 -0700 Subject: add support and proper permissions for /dev/msm_camera/ Signed-off-by: Iliyan Malchev --- init/devices.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'init') diff --git a/init/devices.c b/init/devices.c index c278607d..49335a55 100644 --- a/init/devices.c +++ b/init/devices.c @@ -115,6 +115,7 @@ static struct perms_ devperms[] = { { "/dev/oncrpc/", 0660, AID_ROOT, AID_SYSTEM, 1 }, { "/dev/adsp/", 0660, AID_SYSTEM, AID_AUDIO, 1 }, { "/dev/mt9t013", 0660, AID_SYSTEM, AID_SYSTEM, 0 }, + { "/dev/msm_camera/", 0660, AID_SYSTEM, AID_SYSTEM, 1 }, { "/dev/akm8976_daemon",0640, AID_COMPASS, AID_SYSTEM, 0 }, { "/dev/akm8976_aot", 0640, AID_COMPASS, AID_SYSTEM, 0 }, { "/dev/akm8976_pffd", 0640, AID_COMPASS, AID_SYSTEM, 0 }, @@ -382,7 +383,10 @@ static void handle_device_event(struct uevent *uevent) } else if (!strncmp(uevent->subsystem, "adsp", 4)) { base = "/dev/adsp/"; mkdir(base, 0755); - } else if(!strncmp(uevent->subsystem, "input", 5)) { + } else if (!strncmp(uevent->subsystem, "msm_camera", 10)) { + base = "/dev/msm_camera/"; + mkdir(base, 0755); + } else if(!strncmp(uevent->subsystem, "input", 5)) { base = "/dev/input/"; mkdir(base, 0755); } else if(!strncmp(uevent->subsystem, "mtd", 3)) { -- cgit v1.2.3 From 88dc657d50cb3289a9011828c497eee996ed958c Mon Sep 17 00:00:00 2001 From: Chia-chi Yeh Date: Fri, 19 Jun 2009 14:59:08 +0800 Subject: Add device, property, directory, and file permissions for VPN. --- init/devices.c | 3 ++- init/property_service.c | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-) (limited to 'init') diff --git a/init/devices.c b/init/devices.c index 49335a55..ac72b345 100644 --- a/init/devices.c +++ b/init/devices.c @@ -132,7 +132,8 @@ static struct perms_ devperms[] = { { "/dev/qmi0", 0640, AID_RADIO, AID_RADIO, 0 }, { "/dev/qmi1", 0640, AID_RADIO, AID_RADIO, 0 }, { "/dev/qmi2", 0640, AID_RADIO, AID_RADIO, 0 }, - { "/dev/tun", 0640, AID_VPN , AID_VPN, 0 }, + { "/dev/ppp", 0660, AID_RADIO, AID_VPN, 0 }, + { "/dev/tun", 0640, AID_VPN, AID_VPN, 0 }, { NULL, 0, 0, 0, 0 }, }; diff --git a/init/property_service.c b/init/property_service.c index 48ca3ea3..23a8821d 100644 --- a/init/property_service.c +++ b/init/property_service.c @@ -67,6 +67,8 @@ struct { { "wlan.", AID_SYSTEM }, { "dhcp.", AID_SYSTEM }, { "dhcp.", AID_DHCP }, + { "vpn.", AID_SYSTEM }, + { "vpn.", AID_VPN }, { "debug.", AID_SHELL }, { "log.", AID_SHELL }, { "service.adb.root", AID_SHELL }, -- cgit v1.2.3