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

Commit 95d9ac64 authored by Jeff Sharkey's avatar Jeff Sharkey
Browse files

DO NOT MERGE. Check and restorecon cache/code_cache directories.

To speed up boot times, we recently relaxed SELinux restorecon logic
to only consider relabeling app storage when the top level SELinux
label changed.

However, if an app manually deletes either their cache or code_cache
directories, installd will helpfully recreate those directories at
the next boot, but they'll be stuck with incorrect SELinux labels
which an app can't fix.  (Our historically aggressive restorecons had
relabeled them, which is why we didn't observe until now.)

This change checks the labels of the cache/code_cache directories,
and runs a restorecon if needed, fixing the issue above.

Test: delete cache and verify recreated with correct label
Bug: 32504081
Change-Id: I0114ae4129223e5909b1075d56a9b1145ebc5ef4
parent 7db6041d
Loading
Loading
Loading
Loading
+14 −7
Original line number Original line Diff line number Diff line
@@ -106,7 +106,7 @@ static std::string create_primary_profile(const std::string& profile_dir) {
 * if the label of that top-level file actually changed.  This can save us
 * if the label of that top-level file actually changed.  This can save us
 * significant time by avoiding no-op traversals of large filesystem trees.
 * significant time by avoiding no-op traversals of large filesystem trees.
 */
 */
static int restorecon_app_data_lazy(const char* path, const char* seinfo, uid_t uid) {
static int restorecon_app_data_lazy(const std::string& path, const char* seinfo, uid_t uid) {
    int res = 0;
    int res = 0;
    char* before = nullptr;
    char* before = nullptr;
    char* after = nullptr;
    char* after = nullptr;
@@ -114,15 +114,15 @@ static int restorecon_app_data_lazy(const char* path, const char* seinfo, uid_t
    // Note that SELINUX_ANDROID_RESTORECON_DATADATA flag is set by
    // Note that SELINUX_ANDROID_RESTORECON_DATADATA flag is set by
    // libselinux. Not needed here.
    // libselinux. Not needed here.


    if (lgetfilecon(path, &before) < 0) {
    if (lgetfilecon(path.c_str(), &before) < 0) {
        PLOG(ERROR) << "Failed before getfilecon for " << path;
        PLOG(ERROR) << "Failed before getfilecon for " << path;
        goto fail;
        goto fail;
    }
    }
    if (selinux_android_restorecon_pkgdir(path, seinfo, uid, 0) < 0) {
    if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid, 0) < 0) {
        PLOG(ERROR) << "Failed top-level restorecon for " << path;
        PLOG(ERROR) << "Failed top-level restorecon for " << path;
        goto fail;
        goto fail;
    }
    }
    if (lgetfilecon(path, &after) < 0) {
    if (lgetfilecon(path.c_str(), &after) < 0) {
        PLOG(ERROR) << "Failed after getfilecon for " << path;
        PLOG(ERROR) << "Failed after getfilecon for " << path;
        goto fail;
        goto fail;
    }
    }
@@ -132,7 +132,7 @@ static int restorecon_app_data_lazy(const char* path, const char* seinfo, uid_t
    if (strcmp(before, after)) {
    if (strcmp(before, after)) {
        LOG(DEBUG) << "Detected label change from " << before << " to " << after << " at " << path
        LOG(DEBUG) << "Detected label change from " << before << " to " << after << " at " << path
                << "; running recursive restorecon";
                << "; running recursive restorecon";
        if (selinux_android_restorecon_pkgdir(path, seinfo, uid,
        if (selinux_android_restorecon_pkgdir(path.c_str(), seinfo, uid,
                SELINUX_ANDROID_RESTORECON_RECURSE) < 0) {
                SELINUX_ANDROID_RESTORECON_RECURSE) < 0) {
            PLOG(ERROR) << "Failed recursive restorecon for " << path;
            PLOG(ERROR) << "Failed recursive restorecon for " << path;
            goto fail;
            goto fail;
@@ -148,6 +148,11 @@ done:
    return res;
    return res;
}
}


static int restorecon_app_data_lazy(const std::string& parent, const char* name, const char* seinfo,
        uid_t uid) {
    return restorecon_app_data_lazy(StringPrintf("%s/%s", parent.c_str(), name), seinfo, uid);
}

static int prepare_app_dir(const std::string& path, mode_t target_mode, uid_t uid) {
static int prepare_app_dir(const std::string& path, mode_t target_mode, uid_t uid) {
    if (fs_prepare_dir_strict(path.c_str(), target_mode, uid, uid) != 0) {
    if (fs_prepare_dir_strict(path.c_str(), target_mode, uid, uid) != 0) {
        PLOG(ERROR) << "Failed to prepare " << path;
        PLOG(ERROR) << "Failed to prepare " << path;
@@ -174,7 +179,9 @@ int create_app_data(const char *uuid, const char *pkgname, userid_t userid, int
        }
        }


        // Consider restorecon over contents if label changed
        // Consider restorecon over contents if label changed
        if (restorecon_app_data_lazy(path.c_str(), seinfo, uid)) {
        if (restorecon_app_data_lazy(path, seinfo, uid) ||
                restorecon_app_data_lazy(path, "cache", seinfo, uid) ||
                restorecon_app_data_lazy(path, "code_cache", seinfo, uid)) {
            return -1;
            return -1;
        }
        }


@@ -193,7 +200,7 @@ int create_app_data(const char *uuid, const char *pkgname, userid_t userid, int
        }
        }


        // Consider restorecon over contents if label changed
        // Consider restorecon over contents if label changed
        if (restorecon_app_data_lazy(path.c_str(), seinfo, uid)) {
        if (restorecon_app_data_lazy(path, seinfo, uid)) {
            return -1;
            return -1;
        }
        }