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

Commit 628946a6 authored by Christopher Tate's avatar Christopher Tate
Browse files

Fix priv-app edge case across OTAs

In this case:

   1. Privileged system app FOO is overlain by an installed update,
   2. FOO was replaced during an OTA,
   3. The new in-system FOO introduced new privileged permission requests
      that had not been requested by the original FOO,
   4. the update version of FOO still had a higher version code than
      the new FOO on the system disk, and
   5. the update version of FOO had been requesting these same (newly-
      added-to-system-apk) permissions all along;

then the newly-added privileged permission requests were incorrectly being
refused.  FOO should be able to use any privileged permission used by the
APK sited on the system disk; but instead, it was only being granted the
permissions used by the *original* version of FOO, even though the system
FOO now attempted to use them.

Still with me?

The fix is to (a) properly track privileged-install state when processing
known-to-be-hidden system packages, and (b) to tie the semantics of the
permission grant more explicitly to that evaluated state, rather than
using the prior (rather fragile) fixed-up privilege calculation applied
to the overlain apk's parse records.

Bug 11271490

Change-Id: Id8a45d667e52f3b5d18109e3620d5865f85bb9c9
parent da35dded
Loading
Loading
Loading
Loading
+4 −4
Original line number Diff line number Diff line
@@ -5566,9 +5566,9 @@ public class PackageManagerService extends IPackageManager.Stub {
                        // version of the one on the data partition, but which
                        // granted a new system permission that it didn't have
                        // before.  In this case we do want to allow the app to
                        // now get the new permission if the new system-partition
                        // apk is privileged to get it.
                        if (sysPs.pkg != null && isPrivilegedApp(pkg)) {
                        // now get the new permission if the ancestral apk is
                        // privileged to get it.
                        if (sysPs.pkg != null && sysPs.isPrivileged()) {
                            for (int j=0;
                                    j<sysPs.pkg.requestedPermissions.size(); j++) {
                                if (perm.equals(
@@ -9370,7 +9370,7 @@ public class PackageManagerService extends IPackageManager.Stub {
        }
    }

    boolean locationIsPrivileged(File path) {
    static boolean locationIsPrivileged(File path) {
        try {
            final String privilegedAppDir = new File(Environment.getRootDirectory(), "priv-app")
                    .getCanonicalPath();
+5 −0
Original line number Diff line number Diff line
@@ -16,6 +16,7 @@

package com.android.server.pm;

import android.content.pm.ApplicationInfo;
import android.content.pm.PackageParser;

import java.io.File;
@@ -56,4 +57,8 @@ final class PackageSetting extends PackageSettingBase {
    public int[] getGids() {
        return sharedUser != null ? sharedUser.gids : gids;
    }

    public boolean isPrivileged() {
        return (pkgFlags & ApplicationInfo.FLAG_PRIVILEGED) != 0;
    }
}
+6 −1
Original line number Diff line number Diff line
@@ -2210,7 +2210,11 @@ final class Settings {

        int pkgFlags = 0;
        pkgFlags |= ApplicationInfo.FLAG_SYSTEM;
        PackageSetting ps = new PackageSetting(name, realName, new File(codePathStr),
        final File codePathFile = new File(codePathStr);
        if (PackageManagerService.locationIsPrivileged(codePathFile)) {
            pkgFlags |= ApplicationInfo.FLAG_PRIVILEGED;
        }
        PackageSetting ps = new PackageSetting(name, realName, codePathFile,
                new File(resourcePathStr), nativeLibraryPathStr, versionCode, pkgFlags);
        String timeStampStr = parser.getAttributeValue(null, "ft");
        if (timeStampStr != null) {
@@ -2266,6 +2270,7 @@ final class Settings {
                XmlUtils.skipCurrentTag(parser);
            }
        }

        mDisabledSysPackages.put(name, ps);
    }