Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit da30dc73 authored by Robert Craig's avatar Robert Craig
Browse files

Modify installd's restorecon function.



Changes above with PMS and below with libselinux
have resulted in a few changes to the restorecon data
api. This change is needed in order to support the new
way to issue a recursive restorecon of certain
/data/data directories.

The restorecondata function has also been modified to
find all users on the device for a given package name
(argument to the function) and to issue a separate
recursive restorecon call for each.

Change-Id: Ie440cba2c96f0907458086348197e1506d31c1b6
Signed-off-by: default avatarrpcraig <rpcraig@tycho.ncsc.mil>
parent 50ef8562
Loading
Loading
Loading
Loading
+65 −14
Original line number Diff line number Diff line
@@ -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));
    if (asprintf(&userdir, "%s%s", android_data_dir.path, SECONDARY_USER_PREFIX) < 0) {
        free(primarydir);
        return -1;
    }

    // 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);
    }

    free(data_dir);
    free(user_dir);
    closedir(d);
    free(primarydir);
    free(userdir);
    return ret;
}
+4 −4
Original line number Diff line number Diff line
@@ -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)