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

Commit 3b35e3d2 authored by Philip P. Moltmann's avatar Philip P. Moltmann Committed by android-build-merger
Browse files

Merge "(P) Revoke permision when group changed" into pi-dev

am: 7081085d

Change-Id: I97fd9bb2f15f7adfead96efd8475a9af0b127cf6
parents 0f1bf00a 7081085d
Loading
Loading
Loading
Loading
+30 −6
Original line number Diff line number Diff line
@@ -202,6 +202,7 @@ import android.database.ContentObserver;
import android.graphics.Bitmap;
import android.hardware.display.DisplayManager;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Build;
import android.os.Bundle;
@@ -8696,7 +8697,7 @@ public class PackageManagerService extends IPackageManager.Stub
                        }
                    }
                    // we're updating the disabled package, so, scan it as the package setting
                    final ScanRequest request = new ScanRequest(pkg, sharedUserSetting,
                    final ScanRequest request = new ScanRequest(pkg, sharedUserSetting, null,
                            disabledPkgSetting /* pkgSetting */, null /* disabledPkgSetting */,
                            null /* originalPkgSetting */, null, parseFlags, scanFlags,
                            (pkg == mPlatformPackage), user);
@@ -9885,6 +9886,8 @@ public class PackageManagerService extends IPackageManager.Stub
    private static class ScanRequest {
        /** The parsed package */
        @NonNull public final PackageParser.Package pkg;
        /** The package this package replaces */
        @Nullable public final PackageParser.Package oldPkg;
        /** Shared user settings, if the package has a shared user */
        @Nullable public final SharedUserSetting sharedUserSetting;
        /**
@@ -9910,6 +9913,7 @@ public class PackageManagerService extends IPackageManager.Stub
        public ScanRequest(
                @NonNull PackageParser.Package pkg,
                @Nullable SharedUserSetting sharedUserSetting,
                @Nullable PackageParser.Package oldPkg,
                @Nullable PackageSetting pkgSetting,
                @Nullable PackageSetting disabledPkgSetting,
                @Nullable PackageSetting originalPkgSetting,
@@ -9919,6 +9923,7 @@ public class PackageManagerService extends IPackageManager.Stub
                boolean isPlatformPackage,
                @Nullable UserHandle user) {
            this.pkg = pkg;
            this.oldPkg = oldPkg;
            this.pkgSetting = pkgSetting;
            this.sharedUserSetting = sharedUserSetting;
            this.oldPkgSetting = pkgSetting == null ? null : new PackageSetting(pkgSetting);
@@ -10048,8 +10053,9 @@ public class PackageManagerService extends IPackageManager.Stub
            boolean scanSucceeded = false;
            try {
                final ScanRequest request = new ScanRequest(pkg, sharedUserSetting, pkgSetting,
                        disabledPkgSetting, originalPkgSetting, realPkgName, parseFlags, scanFlags,
                final ScanRequest request = new ScanRequest(pkg, sharedUserSetting,
                        pkgSetting == null ? null : pkgSetting.pkg, pkgSetting, disabledPkgSetting,
                        originalPkgSetting, realPkgName, parseFlags, scanFlags,
                        (pkg == mPlatformPackage), user);
                final ScanResult result = scanPackageOnlyLI(request, mFactoryTest, currentTime);
                if (result.success) {
@@ -10079,6 +10085,7 @@ public class PackageManagerService extends IPackageManager.Stub
    private void commitScanResultsLocked(@NonNull ScanRequest request, @NonNull ScanResult result)
            throws PackageManagerException {
        final PackageParser.Package pkg = request.pkg;
        final PackageParser.Package oldPkg = request.oldPkg;
        final @ParseFlags int parseFlags = request.parseFlags;
        final @ScanFlags int scanFlags = request.scanFlags;
        final PackageSetting oldPkgSetting = request.oldPkgSetting;
@@ -10248,7 +10255,7 @@ public class PackageManagerService extends IPackageManager.Stub
        } else {
            final int userId = user == null ? 0 : user.getIdentifier();
            // Modify state for the given package setting
            commitPackageSettings(pkg, pkgSetting, user, scanFlags,
            commitPackageSettings(pkg, oldPkg, pkgSetting, user, scanFlags,
                    (parseFlags & PackageParser.PARSE_CHATTY) != 0 /*chatty*/);
            if (pkgSetting.getInstantApp(userId)) {
                mInstantAppRegistry.addInstantAppLPw(userId, pkgSetting.appId);
@@ -11174,8 +11181,9 @@ public class PackageManagerService extends IPackageManager.Stub
     * Adds a scanned package to the system. When this method is finished, the package will
     * be available for query, resolution, etc...
     */
    private void commitPackageSettings(PackageParser.Package pkg, PackageSetting pkgSetting,
            UserHandle user, final @ScanFlags int scanFlags, boolean chatty) {
    private void commitPackageSettings(PackageParser.Package pkg,
            @Nullable PackageParser.Package oldPkg, PackageSetting pkgSetting, UserHandle user,
            final @ScanFlags int scanFlags, boolean chatty) {
        final String pkgName = pkg.packageName;
        if (mCustomResolverComponentName != null &&
                mCustomResolverComponentName.getPackageName().equals(pkg.packageName)) {
@@ -11515,6 +11523,22 @@ public class PackageManagerService extends IPackageManager.Stub
                    }
                }
            }
            if (oldPkg != null) {
                // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
                // revoke callbacks from this method might need to kill apps which need the
                // mPackages lock on a different thread. This would dead lock.
                //
                // Hence create a copy of all package names and pass it into
                // revokeRuntimePermissionsIfGroupChanged. Only for those permissions might get
                // revoked. If a new package is added before the async code runs the permission
                // won't be granted yet, hence new packages are no problem.
                final ArrayList<String> allPackageNames = new ArrayList<>(mPackages.keySet());
                AsyncTask.execute(() ->
                        mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg,
                                allPackageNames, mPermissionCallback));
            }
        }
        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
+17 −0
Original line number Diff line number Diff line
@@ -28,6 +28,7 @@ import android.content.pm.PackageParser.Permission;
import com.android.server.pm.SharedUserSetting;
import com.android.server.pm.permission.PermissionManagerInternal.PermissionCallback;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
@@ -90,6 +91,22 @@ public abstract class PermissionManagerInternal {
    public abstract void updateAllPermissions(@Nullable String volumeUuid, boolean sdkUpdated,
            @NonNull Collection<PackageParser.Package> allPacakges, PermissionCallback callback);

    /**
     * We might auto-grant permissions if any permission of the group is already granted. Hence if
     * the group of a granted permission changes we need to revoke it to avoid having permissions of
     * the new group auto-granted.
     *
     * @param newPackage The new package that was installed
     * @param oldPackage The old package that was updated
     * @param allPackageNames All packages
     * @param permissionCallback Callback for permission changed
     */
    public abstract void revokeRuntimePermissionsIfGroupChanged(
            @NonNull PackageParser.Package newPackage,
            @NonNull PackageParser.Package oldPackage,
            @NonNull ArrayList<String> allPackageNames,
            @NonNull PermissionCallback permissionCallback);

    /**
     * Add all permissions in the given package.
     * <p>
+86 −0
Original line number Diff line number Diff line
@@ -51,6 +51,7 @@ import android.os.storage.StorageManagerInternal;
import android.text.TextUtils;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.EventLog;
import android.util.Log;
import android.util.Slog;
import android.util.SparseArray;
@@ -391,6 +392,82 @@ public class PermissionManagerService {
        return protectionLevel;
    }

    /**
     * We might auto-grant permissions if any permission of the group is already granted. Hence if
     * the group of a granted permission changes we need to revoke it to avoid having permissions of
     * the new group auto-granted.
     *
     * @param newPackage The new package that was installed
     * @param oldPackage The old package that was updated
     * @param allPackageNames All package names
     * @param permissionCallback Callback for permission changed
     */
    private void revokeRuntimePermissionsIfGroupChanged(
            @NonNull PackageParser.Package newPackage,
            @NonNull PackageParser.Package oldPackage,
            @NonNull ArrayList<String> allPackageNames,
            @NonNull PermissionCallback permissionCallback) {
        final int numOldPackagePermissions = oldPackage.permissions.size();
        final ArrayMap<String, String> oldPermissionNameToGroupName
                = new ArrayMap<>(numOldPackagePermissions);

        for (int i = 0; i < numOldPackagePermissions; i++) {
            final PackageParser.Permission permission = oldPackage.permissions.get(i);

            if (permission.group != null) {
                oldPermissionNameToGroupName.put(permission.info.name,
                        permission.group.info.name);
            }
        }

        final int numNewPackagePermissions = newPackage.permissions.size();
        for (int newPermissionNum = 0; newPermissionNum < numNewPackagePermissions;
                newPermissionNum++) {
            final PackageParser.Permission newPermission =
                    newPackage.permissions.get(newPermissionNum);
            final int newProtection = newPermission.info.getProtection();

            if ((newProtection & PermissionInfo.PROTECTION_DANGEROUS) != 0) {
                final String permissionName = newPermission.info.name;
                final String newPermissionGroupName =
                        newPermission.group == null ? null : newPermission.group.info.name;
                final String oldPermissionGroupName = oldPermissionNameToGroupName.get(
                        permissionName);

                if (newPermissionGroupName != null
                        && !newPermissionGroupName.equals(oldPermissionGroupName)) {
                    final int[] userIds = mUserManagerInt.getUserIds();
                    final int numUserIds = userIds.length;
                    for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) {
                        final int userId = userIds[userIdNum];

                        final int numPackages = allPackageNames.size();
                        for (int packageNum = 0; packageNum < numPackages; packageNum++) {
                            final String packageName = allPackageNames.get(packageNum);

                            if (checkPermission(permissionName, packageName, UserHandle.USER_SYSTEM,
                                    userId) == PackageManager.PERMISSION_GRANTED) {
                                EventLog.writeEvent(0x534e4554, "72710897",
                                        newPackage.applicationInfo.uid,
                                        "Revoking permission", permissionName, "from package",
                                        packageName, "as the group changed from",
                                        oldPermissionGroupName, "to", newPermissionGroupName);

                                try {
                                    revokeRuntimePermission(permissionName, packageName, false,
                                            Process.SYSTEM_UID, userId, permissionCallback);
                                } catch (IllegalArgumentException e) {
                                    Slog.e(TAG, "Could not revoke " + permissionName + " from "
                                            + packageName, e);
                                }
                            }
                        }
                    }
                }
            }
        }
    }

    private void addAllPermissions(PackageParser.Package pkg, boolean chatty) {
        final int N = pkg.permissions.size();
        for (int i=0; i<N; i++) {
@@ -1968,6 +2045,15 @@ public class PermissionManagerService {
            return PermissionManagerService.this.isPermissionsReviewRequired(pkg, userId);
        }
        @Override
        public void revokeRuntimePermissionsIfGroupChanged(
                @NonNull PackageParser.Package newPackage,
                @NonNull PackageParser.Package oldPackage,
                @NonNull ArrayList<String> allPackageNames,
                @NonNull PermissionCallback permissionCallback) {
            PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage,
                    oldPackage, allPackageNames, permissionCallback);
        }
        @Override
        public void addAllPermissions(Package pkg, boolean chatty) {
            PermissionManagerService.this.addAllPermissions(pkg, chatty);
        }