Merge changes Ia7b337e1,I7a2d8aa5,Iacc2b42b,Idf6100d1,If3fba2cc

* changes:
  init: fix copying boot properties
  toolbox: hide property implementation from watchprops
  init: verify size of property buffers passed to property_get
  init: move the system property writer implementation
  init: switch property_get to use __system_property_get
This commit is contained in:
Colin Cross 2013-06-18 01:11:59 +00:00 committed by Gerrit Code Review
commit 95a41f6b20
6 changed files with 76 additions and 107 deletions

View file

@ -625,7 +625,7 @@ static void import_kernel_nv(char *name, int for_emulator)
static void export_kernel_boot_props(void)
{
char tmp[PROP_VALUE_MAX];
const char *pval;
int ret;
unsigned i;
struct {
const char *src_prop;
@ -639,22 +639,26 @@ static void export_kernel_boot_props(void)
};
for (i = 0; i < ARRAY_SIZE(prop_map); i++) {
pval = property_get(prop_map[i].src_prop);
property_set(prop_map[i].dest_prop, pval ?: prop_map[i].def_val);
ret = property_get(prop_map[i].src_prop, tmp);
if (ret > 0)
property_set(prop_map[i].dest_prop, tmp);
else
property_set(prop_map[i].dest_prop, prop_map[i].def_val);
}
pval = property_get("ro.boot.console");
if (pval)
strlcpy(console, pval, sizeof(console));
ret = property_get("ro.boot.console", tmp);
if (ret)
strlcpy(console, tmp, sizeof(console));
/* save a copy for init's usage during boot */
strlcpy(bootmode, property_get("ro.bootmode"), sizeof(bootmode));
property_get("ro.bootmode", tmp);
strlcpy(bootmode, tmp, sizeof(bootmode));
/* if this was given on kernel command line, override what we read
* before (e.g. from /proc/cpuinfo), if anything */
pval = property_get("ro.boot.hardware");
if (pval)
strlcpy(hardware, pval, sizeof(hardware));
ret = property_get("ro.boot.hardware", tmp);
if (ret)
strlcpy(hardware, tmp, sizeof(hardware));
property_set("ro.hardware", hardware);
snprintf(tmp, PROP_VALUE_MAX, "%d", revision);

View file

@ -206,8 +206,9 @@ int expand_props(char *dst, const char *src, int dst_size)
while (*src_ptr && left > 0) {
char *c;
char prop[PROP_NAME_MAX + 1];
const char *prop_val;
char prop_val[PROP_VALUE_MAX];
int prop_len = 0;
int prop_val_len;
c = strchr(src_ptr, '$');
if (!c) {
@ -265,14 +266,14 @@ int expand_props(char *dst, const char *src, int dst_size)
goto err;
}
prop_val = property_get(prop);
if (!prop_val) {
prop_val_len = property_get(prop, prop_val);
if (!prop_val_len) {
ERROR("property '%s' doesn't exist while expanding '%s'\n",
prop, src);
goto err;
}
ret = push_chars(&dst_ptr, &left, prop_val, strlen(prop_val));
ret = push_chars(&dst_ptr, &left, prop_val, prop_val_len);
if (ret < 0)
goto err_nospace;
src_ptr = c;
@ -543,7 +544,7 @@ void queue_all_property_triggers()
const char* equals = strchr(name, '=');
if (equals) {
char prop_name[PROP_NAME_MAX + 1];
const char* value;
char value[PROP_VALUE_MAX];
int length = equals - name;
if (length > PROP_NAME_MAX) {
ERROR("property name too long in trigger %s", act->name);
@ -552,9 +553,8 @@ void queue_all_property_triggers()
prop_name[length] = 0;
/* does the property exist, and match the trigger value? */
value = property_get(prop_name);
if (value && (!strcmp(equals + 1, value) ||
!strcmp(equals + 1, "*"))) {
property_get(prop_name, value);
if (!strcmp(equals + 1, value) ||!strcmp(equals + 1, "*")) {
action_add_queue_tail(act);
}
}

View file

@ -95,24 +95,23 @@ void keychord_init()
void handle_keychord()
{
struct service *svc;
const char* debuggable;
const char* adb_enabled;
char debuggable[PROP_VALUE_MAX];
char adb_enabled[PROP_VALUE_MAX];
int ret;
__u16 id;
// only handle keychords if ro.debuggable is set or adb is enabled.
// the logic here is that bugreports should be enabled in userdebug or eng builds
// and on user builds for users that are developers.
debuggable = property_get("ro.debuggable");
adb_enabled = property_get("init.svc.adbd");
property_get("ro.debuggable", debuggable);
property_get("init.svc.adbd", adb_enabled);
ret = read(keychord_fd, &id, sizeof(id));
if (ret != sizeof(id)) {
ERROR("could not read keychord id\n");
return;
}
if ((debuggable && !strcmp(debuggable, "1")) ||
(adb_enabled && !strcmp(adb_enabled, "running"))) {
if (!strcmp(debuggable, "1") || !strcmp(adb_enabled, "running")) {
svc = service_find_by_keychord(id);
if (svc) {
INFO("starting service %s from keychord\n", svc->name);

View file

@ -152,23 +152,11 @@ out:
return -1;
}
/* (8 header words + 247 toc words) = 1020 bytes */
/* 1024 bytes header and toc + 247 prop_infos @ 128 bytes = 32640 bytes */
#define PA_COUNT_MAX 247
#define PA_INFO_START 1024
#define PA_SIZE 32768
static workspace pa_workspace;
static prop_info *pa_info_array;
extern prop_area *__system_property_area__;
static int init_property_area(void)
{
prop_area *pa;
if(pa_info_array)
if (property_area_inited)
return -1;
if(init_workspace(&pa_workspace, PA_SIZE))
@ -176,27 +164,12 @@ static int init_property_area(void)
fcntl(pa_workspace.fd, F_SETFD, FD_CLOEXEC);
pa_info_array = (void*) (((char*) pa_workspace.data) + PA_INFO_START);
__system_property_area_init(pa_workspace.data);
pa = pa_workspace.data;
memset(pa, 0, PA_SIZE);
pa->magic = PROP_AREA_MAGIC;
pa->version = PROP_AREA_VERSION;
/* plug into the lib property services */
__system_property_area__ = pa;
property_area_inited = 1;
return 0;
}
static void update_prop_info(prop_info *pi, const char *value, unsigned len)
{
pi->serial = pi->serial | 1;
memcpy(pi->value, value, len + 1);
pi->serial = (len << 24) | ((pi->serial + 1) & 0xffffff);
__futex_wake(&pi->serial, INT32_MAX);
}
static int check_mac_perms(const char *name, char *sctx)
{
if (is_selinux_enabled() <= 0)
@ -292,19 +265,9 @@ static int check_perms(const char *name, unsigned int uid, unsigned int gid, cha
return 0;
}
const char* property_get(const char *name)
int __property_get(const char *name, char *value)
{
prop_info *pi;
if(strlen(name) >= PROP_NAME_MAX) return 0;
pi = (prop_info*) __system_property_find(name);
if(pi != 0) {
return pi->value;
} else {
return 0;
}
return __system_property_get(name, value);
}
static void write_persistent_property(const char *name, const char *value)
@ -331,8 +294,8 @@ static void write_persistent_property(const char *name, const char *value)
int property_set(const char *name, const char *value)
{
prop_area *pa;
prop_info *pi;
int ret;
size_t namelen = strlen(name);
size_t valuelen = strlen(value);
@ -347,29 +310,13 @@ int property_set(const char *name, const char *value)
/* ro.* properties may NEVER be modified once set */
if(!strncmp(name, "ro.", 3)) return -1;
pa = __system_property_area__;
update_prop_info(pi, value, valuelen);
pa->serial++;
__futex_wake(&pa->serial, INT32_MAX);
__system_property_update(pi, value, valuelen);
} else {
pa = __system_property_area__;
if(pa->count == PA_COUNT_MAX) {
ERROR("Failed to set '%s'='%s', property pool is exhausted at %d entries",
name, value, PA_COUNT_MAX);
return -1;
ret = __system_property_add(name, namelen, value, valuelen);
if (ret < 0) {
ERROR("Failed to set '%s'='%s'", name, value);
return ret;
}
pi = pa_info_array + pa->count;
pi->serial = (valuelen << 24);
memcpy(pi->name, name, namelen + 1);
memcpy(pi->value, value, valuelen + 1);
pa->toc[pa->count] =
(namelen << 24) | (((unsigned) pi) - ((unsigned) pa));
pa->count++;
pa->serial++;
__futex_wake(&pa->serial, INT32_MAX);
}
/* If name starts with "net." treat as a DNS property. */
if (strncmp("net.", name, strlen("net.")) == 0) {
@ -591,8 +538,11 @@ int properties_inited(void)
static void load_override_properties() {
#ifdef ALLOW_LOCAL_PROP_OVERRIDE
const char *debuggable = property_get("ro.debuggable");
if (debuggable && (strcmp(debuggable, "1") == 0)) {
char debuggable[PROP_VALUE_MAX];
int ret;
ret = property_get("ro.debuggable", debuggable);
if (ret && (strcmp(debuggable, "1") == 0)) {
load_properties_from_file(PROP_PATH_LOCAL_OVERRIDE);
}
#endif /* ALLOW_LOCAL_PROP_OVERRIDE */

View file

@ -18,6 +18,7 @@
#define _INIT_PROPERTY_H
#include <stdbool.h>
#include <sys/system_properties.h>
extern void handle_property_set_fd(void);
extern void property_init(void);
@ -25,9 +26,25 @@ extern void property_load_boot_defaults(void);
extern void load_persist_props(void);
extern void start_property_service(void);
void get_property_workspace(int *fd, int *sz);
extern const char* property_get(const char *name);
extern int __property_get(const char *name, char *value);
extern int property_set(const char *name, const char *value);
extern int properties_inited();
int get_property_set_fd(void);
extern void __property_get_size_error()
__attribute__((__error__("property_get called with too small buffer")));
static inline
__attribute__ ((always_inline))
__attribute__ ((gnu_inline))
__attribute__ ((artificial))
int property_get(const char *name, char *value)
{
size_t value_len = __builtin_object_size(value, 0);
if (value_len != PROP_VALUE_MAX)
__property_get_size_error();
return __property_get(name, value);
}
#endif /* _INIT_PROPERTY_H */

View file

@ -9,9 +9,6 @@
#define _REALLY_INCLUDE_SYS__SYSTEM_PROPERTIES_H_
#include <sys/_system_properties.h>
extern prop_area *__system_property_area__;
typedef struct pwatch pwatch;
struct pwatch
@ -39,33 +36,35 @@ static void announce(const prop_info *pi)
int watchprops_main(int argc, char *argv[])
{
prop_area *pa = __system_property_area__;
unsigned serial = pa->serial;
unsigned count = pa->count;
unsigned serial = 0;
unsigned count;
unsigned n;
if(count >= 1024) exit(1);
for(n = 0; n < count; n++) {
for(n = 0; n < 1024; n++) {
watchlist[n].pi = __system_property_find_nth(n);
watchlist[n].serial = watchlist[n].pi->serial;
if (watchlist[n].pi == 0)
break;
watchlist[n].serial = __system_property_serial(watchlist[n].pi);
}
for(;;) {
do {
__futex_wait(&pa->serial, serial, 0);
} while(pa->serial == serial);
count = n;
if (count == 1024)
exit(1);
while(count < pa->count){
for(;;) {
serial = __system_property_wait_any(serial);
while(count < 1024){
watchlist[count].pi = __system_property_find_nth(count);
watchlist[count].serial = watchlist[n].pi->serial;
if (watchlist[count].pi == 0)
break;
watchlist[count].serial = __system_property_serial(watchlist[n].pi);
announce(watchlist[count].pi);
count++;
if(count == 1024) exit(1);
}
for(n = 0; n < count; n++){
unsigned tmp = watchlist[n].pi->serial;
unsigned tmp = __system_property_serial(watchlist[n].pi);
if(watchlist[n].serial != tmp) {
announce(watchlist[n].pi);
watchlist[n].serial = tmp;