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

Commit 0699f2a0 authored by Yurii Zubrytskyi's avatar Yurii Zubrytskyi
Browse files

SELinux labels bug logging and workaround

Some apps don't get their dir/file labels correctly updated
after installation, and fail to launch because of it

This CL adds additional logging for the applying, and
introduces some extra verifications during initial app scanning
at boot, and right at the final steps of the installation

Should be reverted after the root cause gets fixed

Bug: 231951809
Test: manual device boot
Change-Id: Ifb68ba1203726db24a7791b284e31fc74df25e96
parent 0aa4fa44
Loading
Loading
Loading
Loading
+16 −3
Original line number Diff line number Diff line
@@ -172,10 +172,23 @@ class FileInstallArgs extends InstallArgs {
            return false;
        }

        if (!onIncremental && !SELinux.restoreconRecursive(afterCodeFile)) {
        if (onIncremental) {
            Slog.i(TAG, PackageManagerServiceUtils.SELINUX_BUG
                    + ": Skipping restorecon for Incremental install of " + beforeCodeFile);
        } else {
            try {
                if (!SELinux.restoreconRecursive(afterCodeFile)) {
                    Slog.w(TAG, "Failed to restorecon");
                    return false;
                }
                PackageManagerServiceUtils.verifySelinuxLabels(afterCodeFile.getAbsolutePath());
            } catch (Exception e) {
                Slog.e(TAG,
                        PackageManagerServiceUtils.SELINUX_BUG + ": Exception from restorecon on "
                                + beforeCodeFile, e);
                throw e;
            }
        }

        // Reflect the rename internally
        mCodeFile = afterCodeFile;
+5 −0
Original line number Diff line number Diff line
@@ -648,6 +648,10 @@ final class InstallPackageHelper {
            Log.v(TAG, "restoreAndPostInstall userId=" + userId + " package=" + res.mPkg);
        }

        if (res.mPkg != null) {
            PackageManagerServiceUtils.verifySelinuxLabels(res.mPkg.getPath());
        }

        // A restore should be requested at this point if (a) the install
        // succeeded, (b) the operation is not an update.
        final boolean update = res.mRemovedInfo != null
@@ -3566,6 +3570,7 @@ final class InstallPackageHelper {
            @ParsingPackageUtils.ParseFlags int parseFlags,
            @PackageManagerService.ScanFlags int scanFlags,
            @Nullable UserHandle user) throws PackageManagerException {
        PackageManagerServiceUtils.verifySelinuxLabels(parsedPackage.getPath());

        final Pair<ScanResult, Boolean> scanResultPair = scanSystemPackageLI(
                parsedPackage, parseFlags, scanFlags, user);
+25 −0
Original line number Diff line number Diff line
@@ -60,6 +60,7 @@ import android.os.Debug;
import android.os.Environment;
import android.os.FileUtils;
import android.os.Process;
import android.os.SELinux;
import android.os.SystemProperties;
import android.os.incremental.IncrementalManager;
import android.os.incremental.IncrementalStorage;
@@ -1388,4 +1389,28 @@ public class PackageManagerServiceUtils {
            }
        }
    }

    // TODO(b/231951809): remove this workaround after figuring out why apk_tmp_file labels stay
    // on the installed apps instead of the correct apk_data_file ones

    public static final String SELINUX_BUG = "b/231951809";

    /**
     * A workaround for b/231951809:
     * Verifies the SELinux labels of the passed path, and tries to correct them if detects them
     * wrong or missing.
     */
    public static void verifySelinuxLabels(String path) {
        final String expectedCon = SELinux.fileSelabelLookup(path);
        final String actualCon = SELinux.getFileContext(path);
        Slog.i(TAG, SELINUX_BUG + ": checking selinux labels for " + path + " expected / actual: "
                + expectedCon + " / " + actualCon);
        if (expectedCon == null || !expectedCon.equals(actualCon)) {
            Slog.w(TAG, SELINUX_BUG + ": labels don't match, reapplying for " + path);
            if (!SELinux.restoreconRecursive(new File(path))) {
                Slog.w(TAG, SELINUX_BUG + ": Failed to reapply restorecon");
            }
            // well, if it didn't work now after not working at first, not much else can be done
        }
    }
}