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

Commit 42f4ac8e authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

Merge "DO NOT MERGE (N) Revoke permision when group changed" into nyc-dev

parents 1bbc69d8 5aee5696
Loading
Loading
Loading
Loading
+103 −0
Original line number Diff line number Diff line
@@ -166,6 +166,7 @@ import android.content.res.Resources;
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;
@@ -4290,6 +4291,81 @@ public class PackageManagerService extends IPackageManager.Stub {
        killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED);
    }
    /**
     * 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
     */
    private void revokeRuntimePermissionsIfGroupChanged(
            PackageParser.Package newPackage,
            PackageParser.Package oldPackage,
            ArrayList<String> allPackageNames) {
        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.protectionLevel;
            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 List<UserInfo> users = mContext.getSystemService(UserManager.class)
                            .getUsers();
                    final int numUsers = users.size();
                    for (int userNum = 0; userNum < numUsers; userNum++) {
                        final int userId = users.get(userNum).id;
                        final int numPackages = allPackageNames.size();
                        for (int packageNum = 0; packageNum < numPackages; packageNum++) {
                            final String packageName = allPackageNames.get(packageNum);
                            if (checkPermission(permissionName, packageName, 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(packageName, permissionName, userId);
                                } catch (IllegalArgumentException e) {
                                    Slog.e(TAG, "Could not revoke " + permissionName + " from "
                                            + packageName, e);
                                }
                            }
                        }
                    }
                }
            }
        }
    }
    @Override
    public void resetRuntimePermissions() {
        mContext.enforceCallingOrSelfPermission(
@@ -8099,6 +8175,8 @@ public class PackageManagerService extends IPackageManager.Stub {
                Log.d(TAG, "Scanning package " + pkg.packageName);
        }
        final PackageParser.Package oldPkg;
        synchronized (mPackages) {
            if (mPackages.containsKey(pkg.packageName)
                    || mSharedLibraries.containsKey(pkg.packageName)) {
@@ -8107,6 +8185,13 @@ public class PackageManagerService extends IPackageManager.Stub {
                                + " already installed.  Skipping duplicate.");
            }
            final PackageSetting oldPkgSetting = mSettings.peekPackageLPr(pkg.packageName);
            if (oldPkgSetting == null) {
               oldPkg = null;
            } else {
               oldPkg = oldPkgSetting.pkg;
            }
            // If we're only installing presumed-existing packages, require that the
            // scanned APK is both already known and at the path previously established
            // for it.  Previously unknown packages we pick up normally, but if we have an
@@ -8970,6 +9055,24 @@ public class PackageManagerService extends IPackageManager.Stub {
                // This is a regular package, with one or more known overlay packages.
                createIdmapsForPackageLI(pkg);
            }
            if (oldPkg != null) {
                // We need to call revokeRuntimePermissionsIfGroupChanged async as permission
                // revokation 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(new Runnable() {
                    public void run() {
                        revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg, allPackageNames);
                    }
                });
            }
        }
        Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);