Skip to content

Commit

Permalink
Support for per-SELinux-type split property spaces
Browse files Browse the repository at this point in the history
  • Loading branch information
Chainfire committed Oct 22, 2016
1 parent 686acfd commit 049b41a
Showing 1 changed file with 63 additions and 52 deletions.
115 changes: 63 additions & 52 deletions jni/setpropex.c
Original file line number Diff line number Diff line change
Expand Up @@ -94,34 +94,36 @@ static int read_mapinfo(FILE *fp, mapinfo* mi)
return 0;
}

static mapinfo *search_maps(int pid, const char* perm, const char* name)
static mapinfo *load_maps(int pid)
{
char tmp[128];
FILE *fp;
mapinfo *mi;
mapinfo *mi, *last, *ret;

sprintf(tmp, "/proc/%d/maps", pid);
fp = fopen(tmp, "r");
if(fp == 0) {
LOGE("search_maps: unable to open maps file: %s", strerror(errno));
return 0;
LOGE("load_maps: unable to open maps file: %s", strerror(errno));
return NULL;
}

mi = calloc(1, sizeof(mapinfo) + 16);

ret = NULL;
last = NULL;
mi = malloc(sizeof(mapinfo));
memset(mi, 0, sizeof(mapinfo));
while(!read_mapinfo(fp, mi)) {
LOGD("search_maps: %"PRIxPTR" %s %s", mi->start, mi->perm, mi->name);
if(!strcmp(mi->perm, perm) && !strcmp(mi->name, name)){
fclose(fp);
mi->pid = pid;
return mi;
}
LOGD("load_maps: %"PRIxPTR" %s %s", mi->start, mi->perm, mi->name);
mi->pid = pid;
if (ret == NULL) ret = mi;
if (last != NULL) last->next = mi;
last = mi;
mi = malloc(sizeof(mapinfo));
memset(mi, 0, sizeof(mapinfo));
}

LOGD("search_maps: map \"%s\" not found!", name);
fclose(fp);
free(mi);
return 0;
return ret;
}

static void dump_region(int fd, uintptr_t start, uintptr_t end, char* mem)
Expand Down Expand Up @@ -220,8 +222,7 @@ static int property_set_ex(const char *name, const char *value, int mem, mapinfo

return 0;
}
else
LOGE("didn't find the property!");

return -1;
}

Expand All @@ -236,20 +237,6 @@ static int setpropex(int init_pid, int argc, char *argv[])
return 1;
}

/* try several different strategies to find the property area in init */
mi = search_maps(init_pid, "rw-s", "/dev/__properties__");
if(!mi)
mi = search_maps(init_pid, "rw-s", "/dev/__properties__ (deleted)");
if(!mi)
mi = search_maps(init_pid, "rwxs", "/dev/__properties__ (deleted)");
if(!mi)
mi = search_maps(init_pid, "rwxs", "/dev/ashmem/system_properties (deleted)");
if(!mi) {
LOGE("didn't find mapinfo!");
return 1;
}
LOGD("map found @ %"PRIxPTR" %"PRIxPTR" %s %s", mi->start, mi->end, mi->perm, mi->name);

/* open it up, so we can read a copy */
sprintf(tmp, "/proc/%d/mem", init_pid);
int mem = open(tmp, O_RDONLY);
Expand All @@ -258,35 +245,59 @@ static int setpropex(int init_pid, int argc, char *argv[])
goto error2;
}

pa_size = mi->end - mi->start;
pa_data_size = pa_size - sizeof(prop_area);
mi = load_maps(init_pid);
while(mi != NULL) {
if (
/* try several different strategies to find the property area in init */
(!strcmp(mi->perm, "rw-s") && !strcmp(mi->name, "/dev/__properties__")) ||
(!strcmp(mi->perm, "rw-s") && !strcmp(mi->name, "/dev/__properties__ (deleted)")) ||
(!strcmp(mi->perm, "rwxs") && !strcmp(mi->name, "/dev/__properties__ (deleted)")) ||
(!strcmp(mi->perm, "rwxs") && !strcmp(mi->name, "/dev/ashmem/system_properties (deleted)")) ||

/* property spaces split per SELinux type */
(!strcmp(mi->perm, "rw-s") && !strncmp(mi->name, "/dev/__properties__/u", strlen("/dev/__properties__/u")))
) {
LOGD("map found @ %"PRIxPTR" %"PRIxPTR" %s %s", mi->start, mi->end, mi->perm, mi->name);

pa_size = mi->end - mi->start;
pa_data_size = pa_size - sizeof(prop_area);

/* allocate memory for our copy */
void *p = malloc(pa_size);
if(p == 0) {
LOGE("unable to allocate memory for our copy of the property area");
goto error1;
}

/* got it, read the data and set it for the system_property code */
dump_region(mem, mi->start, mi->end, p);
__system_property_area__ = p;

/* detect old versions of android and use the correct implementation
* accordingly */
if (__system_property_area__->version == PROP_AREA_VERSION_COMPAT)
compat_mode = true;

/* set the property */
ret = property_set_ex(argv[1], argv[2], mem, mi);

/* clean up */
free(p);

if (ret == 0)
break;
}

/* allocate memory for our copy */
void *p = malloc(pa_size);
if(p == 0) {
LOGE("unable to allocate memory for our copy of the property area");
goto error1;
mi = mi->next;
}

/* got it, read the data and set it for the system_property code */
dump_region(mem, mi->start, mi->end, p);
__system_property_area__ = p;

/* detect old versions of android and use the correct implementation
* accordingly */
if (__system_property_area__->version == PROP_AREA_VERSION_COMPAT)
compat_mode = true;

/* set the property */
ret = property_set_ex(argv[1], argv[2], mem, mi);

/* clean up */
free(p);
if(ret == -1){
LOGE("didn't find the property!");
}

error1:
close(mem);
error2:
free(mi);
if(ret == 0){
return 0;
}
Expand Down

0 comments on commit 049b41a

Please sign in to comment.