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:
commit
95a41f6b20
6 changed files with 76 additions and 107 deletions
24
init/init.c
24
init/init.c
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in a new issue