Loading services/core/java/com/android/server/pm/PackageManagerService.java +1 −64 Original line number Diff line number Diff line Loading @@ -246,7 +246,6 @@ 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; Loading Loading @@ -339,7 +338,6 @@ import com.android.internal.os.SomeArgs; import com.android.internal.os.Zygote; import com.android.internal.telephony.CarrierAppUtils; import com.android.internal.util.ArrayUtils; import com.android.internal.util.CollectionUtils; import com.android.internal.util.ConcurrentUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.FastXmlSerializer; Loading Loading @@ -11592,22 +11590,6 @@ public class PackageManagerService extends IPackageManager.Stub } pkgSetting.signatures.mSigningDetails = reconciledPkg.signingDetails; if (!pkg.getAdoptPermissions().isEmpty()) { // This package wants to adopt ownership of permissions from // another package. for (int i = pkg.getAdoptPermissions().size() - 1; i >= 0; i--) { final String origName = pkg.getAdoptPermissions().get(i); final PackageSetting orig = mSettings.getPackageLPr(origName); if (orig != null) { if (verifyPackageUpdateLPr(orig, pkg)) { Slog.i(TAG, "Adopting permissions from " + origName + " to " + pkg.getPackageName()); mPermissionManager.transferPermissions(origName, pkg.getPackageName()); } } } } if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) { for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) { final String codePathString = changedAbiCodePath.get(i); Loading Loading @@ -12854,27 +12836,6 @@ public class PackageManagerService extends IPackageManager.Stub reconciledPkg.prepareResult != null && reconciledPkg.prepareResult.replace; mAppsFilter.addPackage(pkgSetting, isReplace); // Don't allow ephemeral applications to define new permissions groups. if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { Slog.w(TAG, "Permission groups from package " + pkg.getPackageName() + " ignored: instant apps cannot define new permission groups."); } else { mPermissionManager.addAllPermissionGroups(pkg, chatty); } // If a permission has had its defining app changed, or it has had its protection // upgraded, we need to revoke apps that hold it final List<String> permissionsWithChangedDefinition; // Don't allow ephemeral applications to define new permissions. if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { permissionsWithChangedDefinition = null; Slog.w(TAG, "Permissions from package " + pkg.getPackageName() + " ignored: instant apps cannot define new permissions."); } else { permissionsWithChangedDefinition = mPermissionManager.addAllPermissions(pkg, chatty); } int collectionSize = ArrayUtils.size(pkg.getInstrumentations()); StringBuilder r = null; int i; Loading @@ -12901,31 +12862,7 @@ public class PackageManagerService extends IPackageManager.Stub } } boolean hasOldPkg = oldPkg != null; boolean hasPermissionDefinitionChanges = !CollectionUtils.isEmpty(permissionsWithChangedDefinition); if (hasOldPkg || hasPermissionDefinitionChanges) { // 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(() -> { if (hasOldPkg) { mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg, allPackageNames); } if (hasPermissionDefinitionChanges) { mPermissionManager.revokeRuntimePermissionsIfPermissionDefinitionChanged( permissionsWithChangedDefinition, allPackageNames); } }); } mPermissionManager.onPackageAdded(pkg, (scanFlags & SCAN_AS_INSTANT_APP) != 0, oldPkg); } Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER); services/core/java/com/android/server/pm/permission/Permission.java +3 −4 Original line number Diff line number Diff line Loading @@ -399,8 +399,7 @@ public final class Permission { @NonNull public static Permission createOrUpdate(@Nullable Permission permission, @NonNull PermissionInfo permissionInfo, @NonNull AndroidPackage pkg, @NonNull Collection<Permission> permissionTrees, boolean isOverridingSystemPermission, boolean chatty) { @NonNull Collection<Permission> permissionTrees, boolean isOverridingSystemPermission) { // Allow system apps to redefine non-system permissions boolean ownerChanged = false; if (permission != null && !Objects.equals(permission.mPermissionInfo.packageName, Loading Loading @@ -437,7 +436,7 @@ public final class Permission { permission.mPermissionInfo = permissionInfo; permission.mReconciled = true; permission.mUid = pkg.getUid(); if (chatty) { if (PackageManagerService.DEBUG_PACKAGE_SCANNING) { if (r == null) { r = new StringBuilder(256); } else { Loading @@ -456,7 +455,7 @@ public final class Permission { + permissionInfo.packageName + " ignored: original from " + permission.mPermissionInfo.packageName); } } else if (chatty) { } else if (PackageManagerService.DEBUG_PACKAGE_SCANNING) { if (r == null) { r = new StringBuilder(256); } else { Loading services/core/java/com/android/server/pm/permission/PermissionManagerService.java +106 −73 Original line number Diff line number Diff line Loading @@ -93,6 +93,7 @@ import android.content.pm.parsing.component.ParsedPermission; import android.content.pm.parsing.component.ParsedPermissionGroup; import android.content.pm.permission.SplitPermissionInfoParcelable; import android.metrics.LogMaker; import android.os.AsyncTask; import android.os.Binder; import android.os.Build; import android.os.Debug; Loading Loading @@ -133,6 +134,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.os.RoSystemProperties; import com.android.internal.util.ArrayUtils; import com.android.internal.util.CollectionUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.IntPair; import com.android.internal.util.Preconditions; Loading Loading @@ -2363,14 +2365,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { * * @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 AndroidPackage newPackage, @NonNull AndroidPackage oldPackage, @NonNull ArrayList<String> allPackageNames, @NonNull PermissionCallback permissionCallback) { private void revokeRuntimePermissionsIfGroupChangedInternal(@NonNull AndroidPackage newPackage, @NonNull AndroidPackage oldPackage) { final int numOldPackagePermissions = ArrayUtils.size(oldPackage.getPermissions()); final ArrayMap<String, String> oldPermissionNameToGroupName = new ArrayMap<>(numOldPackagePermissions); Loading Loading @@ -2403,13 +2400,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { 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); mPackageManagerInt.forEachPackage(pkg -> { final String packageName = pkg.getPackageName(); for (final int userId : userIds) { final int permissionState = checkPermission(permissionName, packageName, userId); if (permissionState == PackageManager.PERMISSION_GRANTED) { Loading @@ -2422,14 +2415,15 @@ public class PermissionManagerService extends IPermissionManager.Stub { try { revokeRuntimePermissionInternal(permissionName, packageName, false, callingUid, userId, null, permissionCallback); false, callingUid, userId, null, mDefaultPermissionCallback); } catch (IllegalArgumentException e) { Slog.e(TAG, "Could not revoke " + permissionName + " from " + packageName, e); } } } } }); } } } Loading @@ -2440,18 +2434,11 @@ public class PermissionManagerService extends IPermissionManager.Stub { * granted permissions must be revoked. * * @param permissionsToRevoke A list of permission names to revoke * @param allPackageNames All package names * @param permissionCallback Callback for permission changed */ private void revokeRuntimePermissionsIfPermissionDefinitionChanged( @NonNull List<String> permissionsToRevoke, @NonNull ArrayList<String> allPackageNames, @NonNull PermissionCallback permissionCallback) { private void revokeRuntimePermissionsIfPermissionDefinitionChangedInternal( @NonNull List<String> permissionsToRevoke) { final int[] userIds = mUserManagerInt.getUserIds(); final int numPermissions = permissionsToRevoke.size(); final int numUserIds = userIds.length; final int numPackages = allPackageNames.size(); final int callingUid = Binder.getCallingUid(); for (int permNum = 0; permNum < numPermissions; permNum++) { Loading @@ -2462,15 +2449,14 @@ public class PermissionManagerService extends IPermissionManager.Stub { continue; } } for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) { final int userId = userIds[userIdNum]; for (int packageNum = 0; packageNum < numPackages; packageNum++) { final String packageName = allPackageNames.get(packageNum); final int uid = mPackageManagerInt.getPackageUid(packageName, 0, userId); if (uid < Process.FIRST_APPLICATION_UID) { mPackageManagerInt.forEachPackage(pkg -> { final String packageName = pkg.getPackageName(); final int appId = pkg.getUid(); if (appId < Process.FIRST_APPLICATION_UID) { // do not revoke from system apps continue; return; } for (final int userId : userIds) { final int permissionState = checkPermissionImpl(permName, packageName, userId); final int flags = getPermissionFlags(permName, packageName, userId); Loading @@ -2480,6 +2466,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { | FLAG_PERMISSION_GRANTED_BY_ROLE; if (permissionState == PackageManager.PERMISSION_GRANTED && (flags & flagMask) == 0) { final int uid = UserHandle.getUid(userId, appId); EventLog.writeEvent(0x534e4554, "154505240", uid, "Revoking permission " + permName + " from package " + packageName + " due to definition change"); Loading @@ -2490,18 +2477,18 @@ public class PermissionManagerService extends IPermissionManager.Stub { + packageName + " due to definition change"); try { revokeRuntimePermissionInternal(permName, packageName, false, callingUid, userId, null, permissionCallback); false, callingUid, userId, null, mDefaultPermissionCallback); } catch (Exception e) { Slog.e(TAG, "Could not revoke " + permName + " from " + packageName, e); } } } } }); } } private List<String> addAllPermissions(AndroidPackage pkg, boolean chatty) { private List<String> addAllPermissionsInternal(@NonNull AndroidPackage pkg) { final int N = ArrayUtils.size(pkg.getPermissions()); ArrayList<String> definitionChangedPermissions = new ArrayList<>(); for (int i=0; i<N; i++) { Loading Loading @@ -2539,7 +2526,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { synchronized (mLock) { final Permission permission = Permission.createOrUpdate(oldPermission, permissionInfo, pkg, mRegistry.getPermissionTrees(), isOverridingSystemPermission, chatty); isOverridingSystemPermission); if (p.isTree()) { mRegistry.addPermissionTree(permission); } else { Loading @@ -2557,7 +2544,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { return definitionChangedPermissions; } private void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) { private void addAllPermissionGroupsInternal(@NonNull AndroidPackage pkg) { synchronized (mLock) { final int N = ArrayUtils.size(pkg.getPermissionGroups()); StringBuilder r = null; Loading @@ -2568,7 +2555,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { final boolean isPackageUpdate = pg.getPackageName().equals(curPackageName); if (cur == null || isPackageUpdate) { mRegistry.addPermissionGroup(pg); if (chatty && DEBUG_PACKAGE_SCANNING) { if (DEBUG_PACKAGE_SCANNING) { if (r == null) { r = new StringBuilder(256); } else { Loading @@ -2583,7 +2570,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { Slog.w(TAG, "Permission group " + pg.getName() + " from package " + pg.getPackageName() + " ignored: original from " + cur.getPackageName()); if (chatty && DEBUG_PACKAGE_SCANNING) { if (DEBUG_PACKAGE_SCANNING) { if (r == null) { r = new StringBuilder(256); } else { Loading Loading @@ -4848,13 +4835,83 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } private void transferPermissions(@NonNull String oldPackageName, @NonNull String newPackageName) { private void onPackageAddedInternal(@NonNull AndroidPackage pkg, boolean isInstantApp, @Nullable AndroidPackage oldPkg) { if (!pkg.getAdoptPermissions().isEmpty()) { // This package wants to adopt ownership of permissions from // another package. for (int i = pkg.getAdoptPermissions().size() - 1; i >= 0; i--) { final String origName = pkg.getAdoptPermissions().get(i); if (canAdoptPermissionsInternal(origName, pkg)) { Slog.i(TAG, "Adopting permissions from " + origName + " to " + pkg.getPackageName()); synchronized (mLock) { mRegistry.transferPermissions(oldPackageName, newPackageName); mRegistry.transferPermissions(origName, pkg.getPackageName()); } } } } // Don't allow ephemeral applications to define new permissions groups. if (isInstantApp) { Slog.w(TAG, "Permission groups from package " + pkg.getPackageName() + " ignored: instant apps cannot define new permission groups."); } else { addAllPermissionGroupsInternal(pkg); } // If a permission has had its defining app changed, or it has had its protection // upgraded, we need to revoke apps that hold it final List<String> permissionsWithChangedDefinition; // Don't allow ephemeral applications to define new permissions. if (isInstantApp) { permissionsWithChangedDefinition = null; Slog.w(TAG, "Permissions from package " + pkg.getPackageName() + " ignored: instant apps cannot define new permissions."); } else { permissionsWithChangedDefinition = addAllPermissionsInternal(pkg); } boolean hasOldPkg = oldPkg != null; boolean hasPermissionDefinitionChanges = !CollectionUtils.isEmpty(permissionsWithChangedDefinition); if (hasOldPkg || hasPermissionDefinitionChanges) { // 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. AsyncTask.execute(() -> { if (hasOldPkg) { revokeRuntimePermissionsIfGroupChangedInternal(pkg, oldPkg); } if (hasPermissionDefinitionChanges) { revokeRuntimePermissionsIfPermissionDefinitionChangedInternal( permissionsWithChangedDefinition); } }); } } private boolean canAdoptPermissionsInternal(@NonNull String oldPackageName, @NonNull AndroidPackage newPkg) { final PackageSetting oldPs = mPackageManagerInt.getPackageSetting(oldPackageName); if (oldPs == null) { return false; } if (!oldPs.isSystem()) { Slog.w(TAG, "Unable to update from " + oldPs.name + " to " + newPkg.getPackageName() + ": old package not in system partition"); return false; } if (mPackageManagerInt.getPackage(oldPs.name) != null) { Slog.w(TAG, "Unable to update from " + oldPs.name + " to " + newPkg.getPackageName() + ": old package still exists"); return false; } return true; } private boolean canPropagatePermissionToInstantApp(@NonNull String permissionName) { synchronized (mLock) { final Permission bp = mRegistry.getPermission(permissionName); Loading Loading @@ -4954,31 +5011,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { return isPermissionsReviewRequiredInternal(packageName, userId); } @Override public void revokeRuntimePermissionsIfGroupChanged( @NonNull AndroidPackage newPackage, @NonNull AndroidPackage oldPackage, @NonNull ArrayList<String> allPackageNames) { PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage, oldPackage, allPackageNames, mDefaultPermissionCallback); } @Override public void revokeRuntimePermissionsIfPermissionDefinitionChanged( @NonNull List<String> permissionsToRevoke, @NonNull ArrayList<String> allPackageNames) { PermissionManagerService.this.revokeRuntimePermissionsIfPermissionDefinitionChanged( permissionsToRevoke, allPackageNames, mDefaultPermissionCallback); } @Override public List<String> addAllPermissions(AndroidPackage pkg, boolean chatty) { return PermissionManagerService.this.addAllPermissions(pkg, chatty); } @Override public void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) { PermissionManagerService.this.addAllPermissionGroups(pkg, chatty); } @Override public void removeAllPermissions(AndroidPackage pkg, boolean chatty) { PermissionManagerService.this.removeAllPermissions(pkg, chatty); Loading Loading @@ -5313,9 +5345,10 @@ public class PermissionManagerService extends IPermissionManager.Stub { } @Override public void transferPermissions(@NonNull String oldPackageName, @NonNull String newPackageName) { PermissionManagerService.this.transferPermissions(oldPackageName, newPackageName); public void onPackageAdded(@NonNull AndroidPackage pkg, boolean isInstantApp, @Nullable AndroidPackage oldPkg) { Objects.requireNonNull(pkg); onPackageAddedInternal(pkg, isInstantApp, oldPkg); } @Override Loading services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java +8 −39 Original line number Diff line number Diff line Loading @@ -276,42 +276,6 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER) public abstract void resetAllRuntimePermissions(@UserIdInt int userId); /** * 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 */ public abstract void revokeRuntimePermissionsIfGroupChanged( @NonNull AndroidPackage newPackage, @NonNull AndroidPackage oldPackage, @NonNull ArrayList<String> allPackageNames); /** * Some permissions might have been owned by a non-system package, and the system then defined * said permission. Some other permissions may one have been install permissions, but are now * runtime or higher. These permissions should be revoked. * * @param permissionsToRevoke A list of permission names to revoke * @param allPackageNames All packages */ public abstract void revokeRuntimePermissionsIfPermissionDefinitionChanged( @NonNull List<String> permissionsToRevoke, @NonNull ArrayList<String> allPackageNames); /** * Add all permissions in the given package. * <p> * NOTE: argument {@code groupTEMP} is temporary until mPermissionGroups is moved to * the permission settings. * * @return A list of BasePermissions that were updated, and need to be revoked from packages */ public abstract List<String> addAllPermissions(@NonNull AndroidPackage pkg, boolean chatty); public abstract void addAllPermissionGroups(@NonNull AndroidPackage pkg, boolean chatty); public abstract void removeAllPermissions(@NonNull AndroidPackage pkg, boolean chatty); /** Loading Loading @@ -578,10 +542,15 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager @NonNull LegacyPermissionSettings legacyPermissionSettings); /** * Transfers ownership of permissions from one package to another. * Callback when a package has been added. * * @param pkg the added package * @param isInstantApp whether the added package is an instant app * @param oldPkg the old package, or {@code null} if none */ public abstract void transferPermissions(@NonNull String oldPackageName, @NonNull String newPackageName); //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER) public abstract void onPackageAdded(@NonNull AndroidPackage pkg, boolean isInstantApp, @Nullable AndroidPackage oldPkg); /** * Check whether a permission can be propagated to instant app. Loading Loading
services/core/java/com/android/server/pm/PackageManagerService.java +1 −64 Original line number Diff line number Diff line Loading @@ -246,7 +246,6 @@ 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; Loading Loading @@ -339,7 +338,6 @@ import com.android.internal.os.SomeArgs; import com.android.internal.os.Zygote; import com.android.internal.telephony.CarrierAppUtils; import com.android.internal.util.ArrayUtils; import com.android.internal.util.CollectionUtils; import com.android.internal.util.ConcurrentUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.FastXmlSerializer; Loading Loading @@ -11592,22 +11590,6 @@ public class PackageManagerService extends IPackageManager.Stub } pkgSetting.signatures.mSigningDetails = reconciledPkg.signingDetails; if (!pkg.getAdoptPermissions().isEmpty()) { // This package wants to adopt ownership of permissions from // another package. for (int i = pkg.getAdoptPermissions().size() - 1; i >= 0; i--) { final String origName = pkg.getAdoptPermissions().get(i); final PackageSetting orig = mSettings.getPackageLPr(origName); if (orig != null) { if (verifyPackageUpdateLPr(orig, pkg)) { Slog.i(TAG, "Adopting permissions from " + origName + " to " + pkg.getPackageName()); mPermissionManager.transferPermissions(origName, pkg.getPackageName()); } } } } if (changedAbiCodePath != null && changedAbiCodePath.size() > 0) { for (int i = changedAbiCodePath.size() - 1; i >= 0; --i) { final String codePathString = changedAbiCodePath.get(i); Loading Loading @@ -12854,27 +12836,6 @@ public class PackageManagerService extends IPackageManager.Stub reconciledPkg.prepareResult != null && reconciledPkg.prepareResult.replace; mAppsFilter.addPackage(pkgSetting, isReplace); // Don't allow ephemeral applications to define new permissions groups. if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { Slog.w(TAG, "Permission groups from package " + pkg.getPackageName() + " ignored: instant apps cannot define new permission groups."); } else { mPermissionManager.addAllPermissionGroups(pkg, chatty); } // If a permission has had its defining app changed, or it has had its protection // upgraded, we need to revoke apps that hold it final List<String> permissionsWithChangedDefinition; // Don't allow ephemeral applications to define new permissions. if ((scanFlags & SCAN_AS_INSTANT_APP) != 0) { permissionsWithChangedDefinition = null; Slog.w(TAG, "Permissions from package " + pkg.getPackageName() + " ignored: instant apps cannot define new permissions."); } else { permissionsWithChangedDefinition = mPermissionManager.addAllPermissions(pkg, chatty); } int collectionSize = ArrayUtils.size(pkg.getInstrumentations()); StringBuilder r = null; int i; Loading @@ -12901,31 +12862,7 @@ public class PackageManagerService extends IPackageManager.Stub } } boolean hasOldPkg = oldPkg != null; boolean hasPermissionDefinitionChanges = !CollectionUtils.isEmpty(permissionsWithChangedDefinition); if (hasOldPkg || hasPermissionDefinitionChanges) { // 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(() -> { if (hasOldPkg) { mPermissionManager.revokeRuntimePermissionsIfGroupChanged(pkg, oldPkg, allPackageNames); } if (hasPermissionDefinitionChanges) { mPermissionManager.revokeRuntimePermissionsIfPermissionDefinitionChanged( permissionsWithChangedDefinition, allPackageNames); } }); } mPermissionManager.onPackageAdded(pkg, (scanFlags & SCAN_AS_INSTANT_APP) != 0, oldPkg); } Trace.traceEnd(TRACE_TAG_PACKAGE_MANAGER);
services/core/java/com/android/server/pm/permission/Permission.java +3 −4 Original line number Diff line number Diff line Loading @@ -399,8 +399,7 @@ public final class Permission { @NonNull public static Permission createOrUpdate(@Nullable Permission permission, @NonNull PermissionInfo permissionInfo, @NonNull AndroidPackage pkg, @NonNull Collection<Permission> permissionTrees, boolean isOverridingSystemPermission, boolean chatty) { @NonNull Collection<Permission> permissionTrees, boolean isOverridingSystemPermission) { // Allow system apps to redefine non-system permissions boolean ownerChanged = false; if (permission != null && !Objects.equals(permission.mPermissionInfo.packageName, Loading Loading @@ -437,7 +436,7 @@ public final class Permission { permission.mPermissionInfo = permissionInfo; permission.mReconciled = true; permission.mUid = pkg.getUid(); if (chatty) { if (PackageManagerService.DEBUG_PACKAGE_SCANNING) { if (r == null) { r = new StringBuilder(256); } else { Loading @@ -456,7 +455,7 @@ public final class Permission { + permissionInfo.packageName + " ignored: original from " + permission.mPermissionInfo.packageName); } } else if (chatty) { } else if (PackageManagerService.DEBUG_PACKAGE_SCANNING) { if (r == null) { r = new StringBuilder(256); } else { Loading
services/core/java/com/android/server/pm/permission/PermissionManagerService.java +106 −73 Original line number Diff line number Diff line Loading @@ -93,6 +93,7 @@ import android.content.pm.parsing.component.ParsedPermission; import android.content.pm.parsing.component.ParsedPermissionGroup; import android.content.pm.permission.SplitPermissionInfoParcelable; import android.metrics.LogMaker; import android.os.AsyncTask; import android.os.Binder; import android.os.Build; import android.os.Debug; Loading Loading @@ -133,6 +134,7 @@ import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; import com.android.internal.os.RoSystemProperties; import com.android.internal.util.ArrayUtils; import com.android.internal.util.CollectionUtils; import com.android.internal.util.DumpUtils; import com.android.internal.util.IntPair; import com.android.internal.util.Preconditions; Loading Loading @@ -2363,14 +2365,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { * * @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 AndroidPackage newPackage, @NonNull AndroidPackage oldPackage, @NonNull ArrayList<String> allPackageNames, @NonNull PermissionCallback permissionCallback) { private void revokeRuntimePermissionsIfGroupChangedInternal(@NonNull AndroidPackage newPackage, @NonNull AndroidPackage oldPackage) { final int numOldPackagePermissions = ArrayUtils.size(oldPackage.getPermissions()); final ArrayMap<String, String> oldPermissionNameToGroupName = new ArrayMap<>(numOldPackagePermissions); Loading Loading @@ -2403,13 +2400,9 @@ public class PermissionManagerService extends IPermissionManager.Stub { 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); mPackageManagerInt.forEachPackage(pkg -> { final String packageName = pkg.getPackageName(); for (final int userId : userIds) { final int permissionState = checkPermission(permissionName, packageName, userId); if (permissionState == PackageManager.PERMISSION_GRANTED) { Loading @@ -2422,14 +2415,15 @@ public class PermissionManagerService extends IPermissionManager.Stub { try { revokeRuntimePermissionInternal(permissionName, packageName, false, callingUid, userId, null, permissionCallback); false, callingUid, userId, null, mDefaultPermissionCallback); } catch (IllegalArgumentException e) { Slog.e(TAG, "Could not revoke " + permissionName + " from " + packageName, e); } } } } }); } } } Loading @@ -2440,18 +2434,11 @@ public class PermissionManagerService extends IPermissionManager.Stub { * granted permissions must be revoked. * * @param permissionsToRevoke A list of permission names to revoke * @param allPackageNames All package names * @param permissionCallback Callback for permission changed */ private void revokeRuntimePermissionsIfPermissionDefinitionChanged( @NonNull List<String> permissionsToRevoke, @NonNull ArrayList<String> allPackageNames, @NonNull PermissionCallback permissionCallback) { private void revokeRuntimePermissionsIfPermissionDefinitionChangedInternal( @NonNull List<String> permissionsToRevoke) { final int[] userIds = mUserManagerInt.getUserIds(); final int numPermissions = permissionsToRevoke.size(); final int numUserIds = userIds.length; final int numPackages = allPackageNames.size(); final int callingUid = Binder.getCallingUid(); for (int permNum = 0; permNum < numPermissions; permNum++) { Loading @@ -2462,15 +2449,14 @@ public class PermissionManagerService extends IPermissionManager.Stub { continue; } } for (int userIdNum = 0; userIdNum < numUserIds; userIdNum++) { final int userId = userIds[userIdNum]; for (int packageNum = 0; packageNum < numPackages; packageNum++) { final String packageName = allPackageNames.get(packageNum); final int uid = mPackageManagerInt.getPackageUid(packageName, 0, userId); if (uid < Process.FIRST_APPLICATION_UID) { mPackageManagerInt.forEachPackage(pkg -> { final String packageName = pkg.getPackageName(); final int appId = pkg.getUid(); if (appId < Process.FIRST_APPLICATION_UID) { // do not revoke from system apps continue; return; } for (final int userId : userIds) { final int permissionState = checkPermissionImpl(permName, packageName, userId); final int flags = getPermissionFlags(permName, packageName, userId); Loading @@ -2480,6 +2466,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { | FLAG_PERMISSION_GRANTED_BY_ROLE; if (permissionState == PackageManager.PERMISSION_GRANTED && (flags & flagMask) == 0) { final int uid = UserHandle.getUid(userId, appId); EventLog.writeEvent(0x534e4554, "154505240", uid, "Revoking permission " + permName + " from package " + packageName + " due to definition change"); Loading @@ -2490,18 +2477,18 @@ public class PermissionManagerService extends IPermissionManager.Stub { + packageName + " due to definition change"); try { revokeRuntimePermissionInternal(permName, packageName, false, callingUid, userId, null, permissionCallback); false, callingUid, userId, null, mDefaultPermissionCallback); } catch (Exception e) { Slog.e(TAG, "Could not revoke " + permName + " from " + packageName, e); } } } } }); } } private List<String> addAllPermissions(AndroidPackage pkg, boolean chatty) { private List<String> addAllPermissionsInternal(@NonNull AndroidPackage pkg) { final int N = ArrayUtils.size(pkg.getPermissions()); ArrayList<String> definitionChangedPermissions = new ArrayList<>(); for (int i=0; i<N; i++) { Loading Loading @@ -2539,7 +2526,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { synchronized (mLock) { final Permission permission = Permission.createOrUpdate(oldPermission, permissionInfo, pkg, mRegistry.getPermissionTrees(), isOverridingSystemPermission, chatty); isOverridingSystemPermission); if (p.isTree()) { mRegistry.addPermissionTree(permission); } else { Loading @@ -2557,7 +2544,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { return definitionChangedPermissions; } private void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) { private void addAllPermissionGroupsInternal(@NonNull AndroidPackage pkg) { synchronized (mLock) { final int N = ArrayUtils.size(pkg.getPermissionGroups()); StringBuilder r = null; Loading @@ -2568,7 +2555,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { final boolean isPackageUpdate = pg.getPackageName().equals(curPackageName); if (cur == null || isPackageUpdate) { mRegistry.addPermissionGroup(pg); if (chatty && DEBUG_PACKAGE_SCANNING) { if (DEBUG_PACKAGE_SCANNING) { if (r == null) { r = new StringBuilder(256); } else { Loading @@ -2583,7 +2570,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { Slog.w(TAG, "Permission group " + pg.getName() + " from package " + pg.getPackageName() + " ignored: original from " + cur.getPackageName()); if (chatty && DEBUG_PACKAGE_SCANNING) { if (DEBUG_PACKAGE_SCANNING) { if (r == null) { r = new StringBuilder(256); } else { Loading Loading @@ -4848,13 +4835,83 @@ public class PermissionManagerService extends IPermissionManager.Stub { } } private void transferPermissions(@NonNull String oldPackageName, @NonNull String newPackageName) { private void onPackageAddedInternal(@NonNull AndroidPackage pkg, boolean isInstantApp, @Nullable AndroidPackage oldPkg) { if (!pkg.getAdoptPermissions().isEmpty()) { // This package wants to adopt ownership of permissions from // another package. for (int i = pkg.getAdoptPermissions().size() - 1; i >= 0; i--) { final String origName = pkg.getAdoptPermissions().get(i); if (canAdoptPermissionsInternal(origName, pkg)) { Slog.i(TAG, "Adopting permissions from " + origName + " to " + pkg.getPackageName()); synchronized (mLock) { mRegistry.transferPermissions(oldPackageName, newPackageName); mRegistry.transferPermissions(origName, pkg.getPackageName()); } } } } // Don't allow ephemeral applications to define new permissions groups. if (isInstantApp) { Slog.w(TAG, "Permission groups from package " + pkg.getPackageName() + " ignored: instant apps cannot define new permission groups."); } else { addAllPermissionGroupsInternal(pkg); } // If a permission has had its defining app changed, or it has had its protection // upgraded, we need to revoke apps that hold it final List<String> permissionsWithChangedDefinition; // Don't allow ephemeral applications to define new permissions. if (isInstantApp) { permissionsWithChangedDefinition = null; Slog.w(TAG, "Permissions from package " + pkg.getPackageName() + " ignored: instant apps cannot define new permissions."); } else { permissionsWithChangedDefinition = addAllPermissionsInternal(pkg); } boolean hasOldPkg = oldPkg != null; boolean hasPermissionDefinitionChanges = !CollectionUtils.isEmpty(permissionsWithChangedDefinition); if (hasOldPkg || hasPermissionDefinitionChanges) { // 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. AsyncTask.execute(() -> { if (hasOldPkg) { revokeRuntimePermissionsIfGroupChangedInternal(pkg, oldPkg); } if (hasPermissionDefinitionChanges) { revokeRuntimePermissionsIfPermissionDefinitionChangedInternal( permissionsWithChangedDefinition); } }); } } private boolean canAdoptPermissionsInternal(@NonNull String oldPackageName, @NonNull AndroidPackage newPkg) { final PackageSetting oldPs = mPackageManagerInt.getPackageSetting(oldPackageName); if (oldPs == null) { return false; } if (!oldPs.isSystem()) { Slog.w(TAG, "Unable to update from " + oldPs.name + " to " + newPkg.getPackageName() + ": old package not in system partition"); return false; } if (mPackageManagerInt.getPackage(oldPs.name) != null) { Slog.w(TAG, "Unable to update from " + oldPs.name + " to " + newPkg.getPackageName() + ": old package still exists"); return false; } return true; } private boolean canPropagatePermissionToInstantApp(@NonNull String permissionName) { synchronized (mLock) { final Permission bp = mRegistry.getPermission(permissionName); Loading Loading @@ -4954,31 +5011,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { return isPermissionsReviewRequiredInternal(packageName, userId); } @Override public void revokeRuntimePermissionsIfGroupChanged( @NonNull AndroidPackage newPackage, @NonNull AndroidPackage oldPackage, @NonNull ArrayList<String> allPackageNames) { PermissionManagerService.this.revokeRuntimePermissionsIfGroupChanged(newPackage, oldPackage, allPackageNames, mDefaultPermissionCallback); } @Override public void revokeRuntimePermissionsIfPermissionDefinitionChanged( @NonNull List<String> permissionsToRevoke, @NonNull ArrayList<String> allPackageNames) { PermissionManagerService.this.revokeRuntimePermissionsIfPermissionDefinitionChanged( permissionsToRevoke, allPackageNames, mDefaultPermissionCallback); } @Override public List<String> addAllPermissions(AndroidPackage pkg, boolean chatty) { return PermissionManagerService.this.addAllPermissions(pkg, chatty); } @Override public void addAllPermissionGroups(AndroidPackage pkg, boolean chatty) { PermissionManagerService.this.addAllPermissionGroups(pkg, chatty); } @Override public void removeAllPermissions(AndroidPackage pkg, boolean chatty) { PermissionManagerService.this.removeAllPermissions(pkg, chatty); Loading Loading @@ -5313,9 +5345,10 @@ public class PermissionManagerService extends IPermissionManager.Stub { } @Override public void transferPermissions(@NonNull String oldPackageName, @NonNull String newPackageName) { PermissionManagerService.this.transferPermissions(oldPackageName, newPackageName); public void onPackageAdded(@NonNull AndroidPackage pkg, boolean isInstantApp, @Nullable AndroidPackage oldPkg) { Objects.requireNonNull(pkg); onPackageAddedInternal(pkg, isInstantApp, oldPkg); } @Override Loading
services/core/java/com/android/server/pm/permission/PermissionManagerServiceInternal.java +8 −39 Original line number Diff line number Diff line Loading @@ -276,42 +276,6 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER) public abstract void resetAllRuntimePermissions(@UserIdInt int userId); /** * 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 */ public abstract void revokeRuntimePermissionsIfGroupChanged( @NonNull AndroidPackage newPackage, @NonNull AndroidPackage oldPackage, @NonNull ArrayList<String> allPackageNames); /** * Some permissions might have been owned by a non-system package, and the system then defined * said permission. Some other permissions may one have been install permissions, but are now * runtime or higher. These permissions should be revoked. * * @param permissionsToRevoke A list of permission names to revoke * @param allPackageNames All packages */ public abstract void revokeRuntimePermissionsIfPermissionDefinitionChanged( @NonNull List<String> permissionsToRevoke, @NonNull ArrayList<String> allPackageNames); /** * Add all permissions in the given package. * <p> * NOTE: argument {@code groupTEMP} is temporary until mPermissionGroups is moved to * the permission settings. * * @return A list of BasePermissions that were updated, and need to be revoked from packages */ public abstract List<String> addAllPermissions(@NonNull AndroidPackage pkg, boolean chatty); public abstract void addAllPermissionGroups(@NonNull AndroidPackage pkg, boolean chatty); public abstract void removeAllPermissions(@NonNull AndroidPackage pkg, boolean chatty); /** Loading Loading @@ -578,10 +542,15 @@ public abstract class PermissionManagerServiceInternal extends PermissionManager @NonNull LegacyPermissionSettings legacyPermissionSettings); /** * Transfers ownership of permissions from one package to another. * Callback when a package has been added. * * @param pkg the added package * @param isInstantApp whether the added package is an instant app * @param oldPkg the old package, or {@code null} if none */ public abstract void transferPermissions(@NonNull String oldPackageName, @NonNull String newPackageName); //@SystemApi(client = SystemApi.Client.SYSTEM_SERVER) public abstract void onPackageAdded(@NonNull AndroidPackage pkg, boolean isInstantApp, @Nullable AndroidPackage oldPkg); /** * Check whether a permission can be propagated to instant app. Loading