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

Commit c842393b authored by Todd Kennedy's avatar Todd Kennedy
Browse files

Move mPermissionTrees to permission settings

Move more state / logic into the permission sub-package. We're
close to being able to wholesale move large amounts of code from
package manager into the permission manager.

Bug: 63539144

Test: Manual. Builds and runs
Test: cts-tradefed run commandAndExit cts-dev -m CtsAppSecurityHostTestCases -t android.appsecurity.cts.PermissionsHostTest
Test: cts-tradefed run commandAndExit cts-dev -m CtsPermissionTestCases
Test: cts-tradefed run commandAndExit cts-dev -m CtsPermission2TestCases
Test: bit FrameworksServicesTests:com.android.server.pm.PackageManagerSettingsTests
Change-Id: Id292441ff22b14665fd77f700ad934bf2c5a3357
parent 30e7ca0f
Loading
Loading
Loading
Loading
+3 −2
Original line number Diff line number Diff line
@@ -467,6 +467,7 @@ public abstract class PackageManagerInternal {
    /** Updates the flags for the given permission. */
    public abstract void updatePermissionFlagsTEMP(@NonNull String permName,
            @NonNull String packageName, int flagMask, int flagValues, int userId);
    /** temporary until mPermissionTrees is moved to PermissionManager */
    public abstract Object enforcePermissionTreeTEMP(@NonNull String permName, int callingUid);
    /** Returns a PermissionGroup. */
    public abstract @Nullable PackageParser.PermissionGroup getPermissionGroupTEMP(
            @NonNull String groupName);
}
+5 −0
Original line number Diff line number Diff line
@@ -6849,6 +6849,11 @@ public class PackageParser {
            dest.writeParcelable(group, flags);
        }

        /** @hide */
        public boolean isAppOp() {
            return info.isAppOp();
        }

        private Permission(Parcel in) {
            super(in);
            final ClassLoader boot = Object.class.getClassLoader();
+5 −0
Original line number Diff line number Diff line
@@ -353,6 +353,11 @@ public class PermissionInfo extends PackageItemInfo implements Parcelable {
        return size;
    }

    /** @hide */
    public boolean isAppOp() {
        return (protectionLevel & PermissionInfo.PROTECTION_FLAG_APPOP) != 0;
    }

    public static final Creator<PermissionInfo> CREATOR =
        new Creator<PermissionInfo>() {
        @Override
+41 −214
Original line number Diff line number Diff line
@@ -397,7 +397,7 @@ public class PackageManagerService extends IPackageManager.Stub
    static final boolean DEBUG_DOMAIN_VERIFICATION = false;
    private static final boolean DEBUG_BACKUP = false;
    private static final boolean DEBUG_INSTALL = false;
    private static final boolean DEBUG_REMOVE = false;
    public static final boolean DEBUG_REMOVE = false;
    private static final boolean DEBUG_BROADCASTS = false;
    private static final boolean DEBUG_SHOW_INFO = false;
    private static final boolean DEBUG_PACKAGE_INFO = false;
@@ -405,7 +405,7 @@ public class PackageManagerService extends IPackageManager.Stub
    public static final boolean DEBUG_PACKAGE_SCANNING = false;
    private static final boolean DEBUG_VERIFY = false;
    private static final boolean DEBUG_FILTERS = false;
    private static final boolean DEBUG_PERMISSIONS = false;
    public static final boolean DEBUG_PERMISSIONS = false;
    private static final boolean DEBUG_SHARED_LIBRARIES = false;
    private static final boolean DEBUG_COMPRESSION = Build.IS_DEBUGGABLE;
@@ -953,9 +953,6 @@ public class PackageManagerService extends IPackageManager.Stub
    final SparseArray<PackageVerificationState> mPendingVerification
            = new SparseArray<PackageVerificationState>();
    /** Set of packages associated with each app op permission. */
    final ArrayMap<String, ArraySet<String>> mAppOpPermissionPackages = new ArrayMap<>();
    final PackageInstallerService mInstallerService;
    private final PackageDexOptimizer mPackageDexOptimizer;
@@ -2880,7 +2877,7 @@ public class PackageManagerService extends IPackageManager.Stub
                        + mSdkVersion + "; regranting permissions for internal storage");
                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
            }
            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
            updatePermissionsLocked(null, null, StorageManager.UUID_PRIVATE_INTERNAL, updateFlags);
            ver.sdkVersion = mSdkVersion;
            // If this is the first boot or an update from pre-M, and it is a normal
@@ -5181,7 +5178,7 @@ public class PackageManagerService extends IPackageManager.Stub
                final PermissionsState permissionsState = settingBase.getPermissionsState();
                if (permissionsState.hasPermission(permName, userId)) {
                    if (isUidInstantApp) {
                        if (mPermissionManager.isPermissionInstant(permName)) {
                        if (mSettings.mPermissions.isPermissionInstant(permName)) {
                            return PackageManager.PERMISSION_GRANTED;
                        }
                    } else {
@@ -5250,8 +5247,8 @@ public class PackageManagerService extends IPackageManager.Stub
        }
    }
    boolean addPermission(PermissionInfo info, final boolean async) {
        return mPermissionManager.addPermission(
    private boolean addDynamicPermission(PermissionInfo info, final boolean async) {
        return mPermissionManager.addDynamicPermission(
                info, async, getCallingUid(), new PermissionCallback() {
                    @Override
                    public void onPermissionChanged() {
@@ -5267,20 +5264,20 @@ public class PackageManagerService extends IPackageManager.Stub
    @Override
    public boolean addPermission(PermissionInfo info) {
        synchronized (mPackages) {
            return addPermission(info, false);
            return addDynamicPermission(info, false);
        }
    }
    @Override
    public boolean addPermissionAsync(PermissionInfo info) {
        synchronized (mPackages) {
            return addPermission(info, true);
            return addDynamicPermission(info, true);
        }
    }
    @Override
    public void removePermission(String permName) {
        mPermissionManager.removePermission(permName, getCallingUid(), mPermissionCallback);
        mPermissionManager.removeDynamicPermission(permName, getCallingUid(), mPermissionCallback);
    }
    @Override
@@ -5941,17 +5938,8 @@ public class PackageManagerService extends IPackageManager.Stub
    }
    @Override
    public String[] getAppOpPermissionPackages(String permissionName) {
        if (getInstantAppPackageName(Binder.getCallingUid()) != null) {
            return null;
        }
        synchronized (mPackages) {
            ArraySet<String> pkgs = mAppOpPermissionPackages.get(permissionName);
            if (pkgs == null) {
                return null;
            }
            return pkgs.toArray(new String[pkgs.size()]);
        }
    public String[] getAppOpPermissionPackages(String permName) {
        return mPermissionManager.getAppOpPermissionPackages(permName);
    }
    @Override
@@ -10339,7 +10327,7 @@ public class PackageManagerService extends IPackageManager.Stub
                            Slog.i(TAG, "Adopting permissions from " + origName + " to "
                                    + pkg.packageName);
                            // SIDE EFFECTS; updates permissions system state; move elsewhere
                            mSettings.transferPermissionsLPw(origName, pkg.packageName);
                            mSettings.mPermissions.transferPermissions(origName, pkg.packageName);
                        }
                    }
                }
@@ -11187,54 +11175,13 @@ public class PackageManagerService extends IPackageManager.Stub
                if (DEBUG_PACKAGE_SCANNING) Log.d(TAG, "  Permission Groups: " + r);
            }
            N = pkg.permissions.size();
            r = null;
            for (i=0; i<N; i++) {
                PackageParser.Permission p = pkg.permissions.get(i);
            // Dont allow ephemeral apps to define new permissions.
            if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) {
                    Slog.w(TAG, "Permission " + p.info.name + " from package "
                            + p.info.packageName
                Slog.w(TAG, "Permissions from package " + pkg.packageName
                        + " ignored: instant apps cannot define new permissions.");
                    continue;
                }
                // Assume by default that we did not install this permission into the system.
                p.info.flags &= ~PermissionInfo.FLAG_INSTALLED;
                // Now that permission groups have a special meaning, we ignore permission
                // groups for legacy apps to prevent unexpected behavior. In particular,
                // permissions for one app being granted to someone just because they happen
                // to be in a group defined by another app (before this had no implications).
                if (pkg.applicationInfo.targetSdkVersion > Build.VERSION_CODES.LOLLIPOP_MR1) {
                    p.group = mPermissionGroups.get(p.info.group);
                    // Warn for a permission in an unknown group.
                    if (DEBUG_PERMISSIONS && p.info.group != null && p.group == null) {
                        Slog.i(TAG, "Permission " + p.info.name + " from package "
                                + p.info.packageName + " in an unknown group " + p.info.group);
                    }
                }
                // TODO Move to PermissionManager once mPermissionTrees moves there.
//                        p.tree ? mSettings.mPermissionTrees
//                                : mSettings.mPermissions;
//                final BasePermission bp = BasePermission.createOrUpdate(
//                        permissionMap.get(p.info.name), p, pkg, mSettings.mPermissionTrees, chatty);
//                permissionMap.put(p.info.name, bp);
                if (p.tree) {
                    final ArrayMap<String, BasePermission> permissionMap =
                            mSettings.mPermissionTrees;
                    final BasePermission bp = BasePermission.createOrUpdate(
                            permissionMap.get(p.info.name), p, pkg, mSettings.mPermissionTrees,
                            chatty);
                    permissionMap.put(p.info.name, bp);
            } else {
                    final BasePermission bp = BasePermission.createOrUpdate(
                            (BasePermission) mPermissionManager.getPermissionTEMP(p.info.name),
                            p, pkg, mSettings.mPermissionTrees, chatty);
                    mPermissionManager.putPermissionTEMP(p.info.name, bp);
                }
                mPermissionManager.addAllPermissions(pkg, chatty);
            }
            N = pkg.instrumentation.size();
@@ -11960,53 +11907,7 @@ public class PackageManagerService extends IPackageManager.Stub
            if (DEBUG_REMOVE) Log.d(TAG, "  Activities: " + r);
        }
        N = pkg.permissions.size();
        r = null;
        for (i=0; i<N; i++) {
            PackageParser.Permission p = pkg.permissions.get(i);
            BasePermission bp = (BasePermission) mPermissionManager.getPermissionTEMP(p.info.name);
            if (bp == null) {
                bp = mSettings.mPermissionTrees.get(p.info.name);
            }
            if (bp != null && bp.isPermission(p)) {
                bp.setPermission(null);
                if (DEBUG_REMOVE && chatty) {
                    if (r == null) {
                        r = new StringBuilder(256);
                    } else {
                        r.append(' ');
                    }
                    r.append(p.info.name);
                }
            }
            if ((p.info.protectionLevel&PermissionInfo.PROTECTION_FLAG_APPOP) != 0) {
                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(p.info.name);
                if (appOpPkgs != null) {
                    appOpPkgs.remove(pkg.packageName);
                }
            }
        }
        if (r != null) {
            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
        }
        N = pkg.requestedPermissions.size();
        r = null;
        for (i=0; i<N; i++) {
            String perm = pkg.requestedPermissions.get(i);
            if (mPermissionManager.isPermissionAppOp(perm)) {
                ArraySet<String> appOpPkgs = mAppOpPermissionPackages.get(perm);
                if (appOpPkgs != null) {
                    appOpPkgs.remove(pkg.packageName);
                    if (appOpPkgs.isEmpty()) {
                        mAppOpPermissionPackages.remove(perm);
                    }
                }
            }
        }
        if (r != null) {
            if (DEBUG_REMOVE) Log.d(TAG, "  Permissions: " + r);
        }
        mPermissionManager.removeAllPermissions(pkg, chatty);
        N = pkg.instrumentation.size();
        r = null;
@@ -12067,18 +11968,9 @@ public class PackageManagerService extends IPackageManager.Stub
        }
    }
    private static boolean hasPermission(PackageParser.Package pkgInfo, String perm) {
        for (int i=pkgInfo.permissions.size()-1; i>=0; i--) {
            if (pkgInfo.permissions.get(i).info.name.equals(perm)) {
                return true;
            }
        }
        return false;
    }
    static final int UPDATE_PERMISSIONS_ALL = 1<<0;
    static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
    static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
    public static final int UPDATE_PERMISSIONS_ALL = 1<<0;
    public static final int UPDATE_PERMISSIONS_REPLACE_PKG = 1<<1;
    public static final int UPDATE_PERMISSIONS_REPLACE_ALL = 1<<2;
    private void updatePermissionsLPw(PackageParser.Package pkg, int flags) {
        // Update the parent permissions
@@ -12094,10 +11986,10 @@ public class PackageManagerService extends IPackageManager.Stub
    private void updatePermissionsLPw(String changingPkg, PackageParser.Package pkgInfo,
            int flags) {
        final String volumeUuid = (pkgInfo != null) ? getVolumeUuidForPackage(pkgInfo) : null;
        updatePermissionsLPw(changingPkg, pkgInfo, volumeUuid, flags);
        updatePermissionsLocked(changingPkg, pkgInfo, volumeUuid, flags);
    }
    private void updatePermissionsLPw(String changingPkg,
    private void updatePermissionsLocked(String changingPkg,
            PackageParser.Package pkgInfo, String replaceVolumeUuid, int flags) {
        // TODO: Most of the methods exposing BasePermission internals [source package name,
        // etc..] shouldn't be needed. Instead, when we've parsed a permission that doesn't
@@ -12109,55 +12001,11 @@ public class PackageManagerService extends IPackageManager.Stub
        // normal permissions. Today, we need two separate loops because these BasePermission
        // objects are stored separately.
        // Make sure there are no dangling permission trees.
        Iterator<BasePermission> it = mSettings.mPermissionTrees.values().iterator();
        while (it.hasNext()) {
            final BasePermission bp = it.next();
            if (bp.getSourcePackageSetting() == null) {
                // We may not yet have parsed the package, so just see if
                // we still know about its settings.
                bp.setSourcePackageSetting(mSettings.mPackages.get(bp.getSourcePackageName()));
            }
            if (bp.getSourcePackageSetting() == null) {
                Slog.w(TAG, "Removing dangling permission tree: " + bp.getName()
                        + " from package " + bp.getSourcePackageName());
                it.remove();
            } else if (changingPkg != null && changingPkg.equals(bp.getSourcePackageName())) {
                if (pkgInfo == null || !hasPermission(pkgInfo, bp.getName())) {
                    Slog.i(TAG, "Removing old permission tree: " + bp.getName()
                            + " from package " + bp.getSourcePackageName());
                    flags |= UPDATE_PERMISSIONS_ALL;
                    it.remove();
                }
            }
        }
        flags = mPermissionManager.updatePermissionTrees(changingPkg, pkgInfo, flags);
        // Make sure all dynamic permissions have been assigned to a package,
        // and make sure there are no dangling permissions.
        final Iterator<BasePermission> permissionIter =
                mPermissionManager.getPermissionIteratorTEMP();
        while (permissionIter.hasNext()) {
            final BasePermission bp = permissionIter.next();
            if (bp.isDynamic()) {
                bp.updateDynamicPermission(mSettings.mPermissionTrees);
            }
            if (bp.getSourcePackageSetting() == null) {
                // We may not yet have parsed the package, so just see if
                // we still know about its settings.
                bp.setSourcePackageSetting(mSettings.mPackages.get(bp.getSourcePackageName()));
            }
            if (bp.getSourcePackageSetting() == null) {
                Slog.w(TAG, "Removing dangling permission: " + bp.getName()
                        + " from package " + bp.getSourcePackageName());
                permissionIter.remove();
            } else if (changingPkg != null && changingPkg.equals(bp.getSourcePackageName())) {
                if (pkgInfo == null || !hasPermission(pkgInfo, bp.getName())) {
                    Slog.i(TAG, "Removing old permission: " + bp.getName()
                            + " from package " + bp.getSourcePackageName());
                    flags |= UPDATE_PERMISSIONS_ALL;
                    permissionIter.remove();
                }
            }
        }
        flags = mPermissionManager.updatePermissions(changingPkg, pkgInfo, flags);
        Trace.traceBegin(TRACE_TAG_PACKAGE_MANAGER, "grantPermissions");
        // Now update the permissions for all packages, in particular
@@ -12279,12 +12127,7 @@ public class PackageManagerService extends IPackageManager.Stub
            // Keep track of app op permissions.
            if (bp.isAppOp()) {
                ArraySet<String> pkgs = mAppOpPermissionPackages.get(perm);
                if (pkgs == null) {
                    pkgs = new ArraySet<>();
                    mAppOpPermissionPackages.put(perm, pkgs);
                }
                pkgs.add(pkg.packageName);
                mSettings.addAppOpPackage(perm, pkg.packageName);
            }
            if (bp.isNormal()) {
@@ -21227,7 +21070,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
        // permissions, ensure permissions are updated. Beware of dragons if you
        // try optimizing this.
        synchronized (mPackages) {
            updatePermissionsLPw(null, null, StorageManager.UUID_PRIVATE_INTERNAL,
            updatePermissionsLocked(null, null, StorageManager.UUID_PRIVATE_INTERNAL,
                    UPDATE_PERMISSIONS_ALL);
        }
@@ -21773,22 +21616,6 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
            if (!checkin && dumpState.isDumping(DumpState.DUMP_PERMISSIONS)) {
                mSettings.dumpPermissionsLPr(pw, packageName, permissionNames, dumpState);
                if (packageName == null && permissionNames == null) {
                    for (int iperm=0; iperm<mAppOpPermissionPackages.size(); iperm++) {
                        if (iperm == 0) {
                            if (dumpState.onTitlePrinted())
                                pw.println();
                            pw.println("AppOp Permissions:");
                        }
                        pw.print("  AppOp Permission ");
                        pw.print(mAppOpPermissionPackages.keyAt(iperm));
                        pw.println(":");
                        ArraySet<String> pkgs = mAppOpPermissionPackages.valueAt(iperm);
                        for (int ipkg=0; ipkg<pkgs.size(); ipkg++) {
                            pw.print("    "); pw.println(pkgs.valueAt(ipkg));
                        }
                    }
                }
            }
            if (!checkin && dumpState.isDumping(DumpState.DUMP_PROVIDERS)) {
@@ -22292,7 +22119,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
                        + mSdkVersion + "; regranting permissions for " + volumeUuid);
                updateFlags |= UPDATE_PERMISSIONS_REPLACE_PKG | UPDATE_PERMISSIONS_REPLACE_ALL;
            }
            updatePermissionsLPw(null, null, volumeUuid, updateFlags);
            updatePermissionsLocked(null, null, volumeUuid, updateFlags);
            // Yay, everything is now upgraded
            ver.forceCurrent();
@@ -23300,7 +23127,6 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
    void onNewUserCreated(final int userId) {
        synchronized(mPackages) {
            mDefaultPermissionPolicy.grantDefaultPermissions(mPackages.values(), userId);
        }
            // If permission review for legacy apps is required, we represent
            // dagerous permissions for such apps as always granted runtime
            // permissions to keep per user flag state whether review is needed.
@@ -23311,6 +23137,7 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
                        | UPDATE_PERMISSIONS_REPLACE_ALL);
            }
        }
    }
    @Override
    public VerifierDeviceIdentity getVerifierDeviceIdentity() throws RemoteException {
@@ -23752,12 +23579,12 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName());
        }
        @Override
        public Object enforcePermissionTreeTEMP(String permName, int callingUid) {
        public PackageParser.PermissionGroup getPermissionGroupTEMP(String groupName) {
            synchronized (mPackages) {
                return BasePermission.enforcePermissionTreeLP(
                        mSettings.mPermissionTrees, permName, callingUid);
                return mPermissionGroups.get(groupName);
            }
        }
        @Override
        public boolean isInstantApp(String packageName, int userId) {
            return PackageManagerService.this.isInstantApp(packageName, userId);
+7 −16
Original line number Diff line number Diff line
@@ -378,10 +378,6 @@ public final class Settings {
    private final ArrayMap<Long, Integer> mKeySetRefs =
            new ArrayMap<Long, Integer>();

    // Mapping from permission tree names to info about them.
    final ArrayMap<String, BasePermission> mPermissionTrees =
            new ArrayMap<String, BasePermission>();

    // Packages that have been uninstalled and still need their external
    // storage data deleted.
    final ArrayList<PackageCleanItem> mPackagesToBeCleaned = new ArrayList<PackageCleanItem>();
@@ -416,7 +412,7 @@ public final class Settings {

    public final KeySetManagerService mKeySetManagerService = new KeySetManagerService(mPackages);
    /** Settings and other information about permissions */
    private final PermissionSettings mPermissions;
    final PermissionSettings mPermissions;

    Settings(PermissionSettings permissions, Object lock) {
        this(Environment.getDataDirectory(), permissions, lock);
@@ -622,6 +618,10 @@ public final class Settings {
        return null;
    }

    void addAppOpPackage(String permName, String packageName) {
        mPermissions.addAppOpPackage(permName, packageName);
    }

    SharedUserSetting addSharedUserLPw(String name, int uid, int pkgFlags, int pkgPrivateFlags) {
        SharedUserSetting s = mSharedUsers.get(name);
        if (s != null) {
@@ -665,13 +665,6 @@ public final class Settings {
        }
    }

    /**
     * Transfers ownership of permissions from one package to another.
     */
    void transferPermissionsLPw(String origPackageName, String newPackageName) {
        mPermissions.transferPermissions(origPackageName, newPackageName, mPermissionTrees);
    }

    /**
     * Creates a new {@code PackageSetting} object.
     * Use this method instead of the constructor to ensure a settings object is created
@@ -2496,9 +2489,7 @@ public final class Settings {
            }

            serializer.startTag(null, "permission-trees");
            for (BasePermission bp : mPermissionTrees.values()) {
                writePermissionLPr(serializer, bp);
            }
            mPermissions.writePermissionTrees(serializer);
            serializer.endTag(null, "permission-trees");

            serializer.startTag(null, "permissions");
@@ -3042,7 +3033,7 @@ public final class Settings {
                } else if (tagName.equals("permissions")) {
                    mPermissions.readPermissions(parser);
                } else if (tagName.equals("permission-trees")) {
                    PermissionSettings.readPermissions(mPermissionTrees, parser);
                    mPermissions.readPermissionTrees(parser);
                } else if (tagName.equals("shared-user")) {
                    readSharedUserLPw(parser);
                } else if (tagName.equals("preferred-packages")) {
Loading