summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cmds/installd/commands.c79
-rw-r--r--cmds/installd/installd.c8
2 files changed, 69 insertions, 18 deletions
diff --git a/cmds/installd/commands.c b/cmds/installd/commands.c
index 12e8cd1..669f403 100644
--- a/cmds/installd/commands.c
+++ b/cmds/installd/commands.c
@@ -1235,31 +1235,82 @@ fail:
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);
- char *user_dir = build_string2(android_data_dir.path, SECONDARY_USER_PREFIX);
+ struct dirent *entry;
+ DIR *d;
+ struct stat s;
+ char *userdir;
+ char *primarydir;
+ char *pkgdir;
+ int ret = 0;
- unsigned int flags = SELINUX_ANDROID_RESTORECON_RECURSE |
- SELINUX_ANDROID_RESTORECON_DATADATA;
+ // SELINUX_ANDROID_RESTORECON_DATADATA flag is set by libselinux. Not needed here.
+ unsigned int flags = SELINUX_ANDROID_RESTORECON_RECURSE;
- int ret = 0;
+ if (!pkgName || !seinfo) {
+ ALOGE("Package name or seinfo tag is null when trying to restorecon.");
+ return -1;
+ }
- if (!data_dir || !user_dir) {
+ if (asprintf(&primarydir, "%s%s%s", android_data_dir.path, PRIMARY_USER_PREFIX, pkgName) < 0) {
return -1;
}
- if (selinux_android_restorecon(data_dir, flags) < 0) {
- ALOGE("restorecon failed for %s: %s\n", data_dir, strerror(errno));
+ // 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;
}
- if (selinux_android_restorecon(user_dir, flags) < 0) {
- ALOGE("restorecon failed for %s: %s\n", user_dir, strerror(errno));
- ret |= -1;
+ if (asprintf(&userdir, "%s%s", android_data_dir.path, SECONDARY_USER_PREFIX) < 0) {
+ free(primarydir);
+ return -1;
}
- free(data_dir);
- free(user_dir);
+ // Relabel package directory for all secondary users.
+ 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;
}
diff --git a/cmds/installd/installd.c b/cmds/installd/installd.c
index a080ee6..a078e1c 100644
--- a/cmds/installd/installd.c
+++ b/cmds/installd/installd.c
@@ -129,10 +129,10 @@ static int do_idmap(char **arg, char reply[REPLY_MAX])
return idmap(arg[0], arg[1], atoi(arg[2]));
}
-static int do_restorecon_data(char **arg __attribute__((unused)),
- char reply[REPLY_MAX] __attribute__((unused)))
+static int do_restorecon_data(char **arg, char reply[REPLY_MAX] __attribute__((unused)))
{
- return restorecon_data();
+ return restorecon_data(arg[0], arg[1], atoi(arg[2]));
+ /* pkgName, seinfo, uid*/
}
struct cmdinfo {
@@ -159,7 +159,7 @@ struct cmdinfo cmds[] = {
{ "mkuserdata", 4, do_mk_user_data },
{ "rmuser", 1, do_rm_user },
{ "idmap", 3, do_idmap },
- { "restorecondata", 0, do_restorecon_data },
+ { "restorecondata", 3, do_restorecon_data },
};
static int readx(int s, void *_buf, int count)