Merge "Modify installd's restorecon function."

This commit is contained in:
Nick Kralevich 2014-03-31 20:09:18 +00:00 committed by Gerrit Code Review
commit 3ebb877e52
2 changed files with 70 additions and 19 deletions

View File

@ -1235,31 +1235,82 @@ fail:
return -1; return -1;
} }
int restorecon_data() int restorecon_data(const char* pkgName, const char* seinfo, uid_t uid)
{ {
char *data_dir = build_string2(android_data_dir.path, PRIMARY_USER_PREFIX); struct dirent *entry;
char *user_dir = build_string2(android_data_dir.path, SECONDARY_USER_PREFIX); DIR *d;
struct stat s;
unsigned int flags = SELINUX_ANDROID_RESTORECON_RECURSE | char *userdir;
SELINUX_ANDROID_RESTORECON_DATADATA; char *primarydir;
char *pkgdir;
int ret = 0; int ret = 0;
if (!data_dir || !user_dir) { // SELINUX_ANDROID_RESTORECON_DATADATA flag is set by libselinux. Not needed here.
unsigned int flags = SELINUX_ANDROID_RESTORECON_RECURSE;
if (!pkgName || !seinfo) {
ALOGE("Package name or seinfo tag is null when trying to restorecon.");
return -1; return -1;
} }
if (selinux_android_restorecon(data_dir, flags) < 0) { if (asprintf(&primarydir, "%s%s%s", android_data_dir.path, PRIMARY_USER_PREFIX, pkgName) < 0) {
ALOGE("restorecon failed for %s: %s\n", data_dir, strerror(errno)); return -1;
}
// Relabel for primary user.
if (selinux_android_restorecon_pkgdir(primarydir, seinfo, uid, flags) < 0) {
ALOGE("restorecon failed for %s: %s\n", primarydir, strerror(errno));
ret |= -1; ret |= -1;
} }
if (selinux_android_restorecon(user_dir, flags) < 0) { if (asprintf(&userdir, "%s%s", android_data_dir.path, SECONDARY_USER_PREFIX) < 0) {
ALOGE("restorecon failed for %s: %s\n", user_dir, strerror(errno)); free(primarydir);
ret |= -1; return -1;
} }
free(data_dir); // Relabel package directory for all secondary users.
free(user_dir); d = opendir(userdir);
if (d == NULL) {
free(primarydir);
free(userdir);
return -1;
}
while ((entry = readdir(d))) {
if (entry->d_type != DT_DIR) {
continue;
}
const char *user = entry->d_name;
// Ignore "." and ".."
if (!strcmp(user, ".") || !strcmp(user, "..")) {
continue;
}
// user directories start with a number
if (user[0] < '0' || user[0] > '9') {
ALOGE("Expecting numbered directory during restorecon. Instead got '%s'.", user);
continue;
}
if (asprintf(&pkgdir, "%s%s/%s", userdir, user, pkgName) < 0) {
continue;
}
if (stat(pkgdir, &s) < 0) {
free(pkgdir);
continue;
}
if (selinux_android_restorecon_pkgdir(pkgdir, seinfo, uid, flags) < 0) {
ALOGE("restorecon failed for %s: %s\n", pkgdir, strerror(errno));
ret |= -1;
}
free(pkgdir);
}
closedir(d);
free(primarydir);
free(userdir);
return ret; return ret;
} }

View File

@ -129,10 +129,10 @@ static int do_idmap(char **arg, char reply[REPLY_MAX])
return idmap(arg[0], arg[1], atoi(arg[2])); return idmap(arg[0], arg[1], atoi(arg[2]));
} }
static int do_restorecon_data(char **arg __attribute__((unused)), static int do_restorecon_data(char **arg, char reply[REPLY_MAX] __attribute__((unused)))
char reply[REPLY_MAX] __attribute__((unused)))
{ {
return restorecon_data(); return restorecon_data(arg[0], arg[1], atoi(arg[2]));
/* pkgName, seinfo, uid*/
} }
struct cmdinfo { struct cmdinfo {
@ -159,7 +159,7 @@ struct cmdinfo cmds[] = {
{ "mkuserdata", 4, do_mk_user_data }, { "mkuserdata", 4, do_mk_user_data },
{ "rmuser", 1, do_rm_user }, { "rmuser", 1, do_rm_user },
{ "idmap", 3, do_idmap }, { "idmap", 3, do_idmap },
{ "restorecondata", 0, do_restorecon_data }, { "restorecondata", 3, do_restorecon_data },
}; };
static int readx(int s, void *_buf, int count) static int readx(int s, void *_buf, int count)