Merge changes from topics "presubmit-am-4fce8d22f6ba4533875ba6f9fcf0183b", "presubmit-am-748689f93ea9431ca216195bbc7d9588" into tm-dev

* changes:
  Fix potential deadlock in restorePermissionState().
  Properly fix revokePermissionsNoLongerImplicitLocked() for shared UIDs.
This commit is contained in:
Hai Zhang
2022-03-03 00:57:15 +00:00
committed by Android (Google) Code Review

View File

@@ -2536,33 +2536,38 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
} }
} }
Collection<String> uidRequestedPermissions;
Collection<String> uidImplicitPermissions;
int uidTargetSdkVersion;
if (!ps.hasSharedUser()) {
uidRequestedPermissions = pkg.getRequestedPermissions();
uidImplicitPermissions = pkg.getImplicitPermissions();
uidTargetSdkVersion = pkg.getTargetSdkVersion();
} else {
uidRequestedPermissions = new ArraySet<>();
uidImplicitPermissions = new ArraySet<>();
uidTargetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
final ArraySet<PackageStateInternal> packages =
mPackageManagerInt.getSharedUserPackages(ps.getSharedUserAppId());
int packagesSize = packages.size();
for (int i = 0; i < packagesSize; i++) {
AndroidPackageApi sharedUserPackage =
packages.valueAt(i).getAndroidPackage();
uidRequestedPermissions.addAll(
sharedUserPackage.getRequestedPermissions());
uidImplicitPermissions.addAll(
sharedUserPackage.getImplicitPermissions());
uidTargetSdkVersion = Math.min(uidTargetSdkVersion,
sharedUserPackage.getTargetSdkVersion());
}
}
synchronized (mLock) { synchronized (mLock) {
for (final int userId : userIds) { for (final int userId : userIds) {
final UserPermissionState userState = mState.getOrCreateUserState(userId); final UserPermissionState userState = mState.getOrCreateUserState(userId);
final UidPermissionState uidState = userState.getOrCreateUidState(ps.getAppId()); final UidPermissionState uidState = userState.getOrCreateUidState(ps.getAppId());
if (uidState.isMissing()) { if (uidState.isMissing()) {
Collection<String> uidRequestedPermissions;
int targetSdkVersion;
if (!ps.hasSharedUser()) {
uidRequestedPermissions = pkg.getRequestedPermissions();
targetSdkVersion = pkg.getTargetSdkVersion();
} else {
uidRequestedPermissions = new ArraySet<>();
targetSdkVersion = Build.VERSION_CODES.CUR_DEVELOPMENT;
final ArraySet<PackageStateInternal> packages =
mPackageManagerInt.getSharedUserPackages(ps.getSharedUserAppId());
int packagesSize = packages.size();
for (int i = 0; i < packagesSize; i++) {
AndroidPackageApi sharedUserPackage =
packages.valueAt(i).getAndroidPackage();
uidRequestedPermissions.addAll(
sharedUserPackage.getRequestedPermissions());
targetSdkVersion = Math.min(targetSdkVersion,
sharedUserPackage.getTargetSdkVersion());
}
}
for (String permissionName : uidRequestedPermissions) { for (String permissionName : uidRequestedPermissions) {
Permission permission = mRegistry.getPermission(permissionName); Permission permission = mRegistry.getPermission(permissionName);
if (permission == null) { if (permission == null) {
@@ -2576,7 +2581,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT, FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT,
FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT); FLAG_PERMISSION_RESTRICTION_UPGRADE_EXEMPT);
} }
if (targetSdkVersion < Build.VERSION_CODES.M) { if (uidTargetSdkVersion < Build.VERSION_CODES.M) {
uidState.updatePermissionFlags(permission, uidState.updatePermissionFlags(permission,
PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED PackageManager.FLAG_PERMISSION_REVIEW_REQUIRED
| PackageManager.FLAG_PERMISSION_REVOKED_COMPAT, | PackageManager.FLAG_PERMISSION_REVOKED_COMPAT,
@@ -2606,8 +2611,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
// the runtime ones are written only if changed. The only cases of // the runtime ones are written only if changed. The only cases of
// changed runtime permissions here are promotion of an install to // changed runtime permissions here are promotion of an install to
// runtime and revocation of a runtime from a shared user. // runtime and revocation of a runtime from a shared user.
if (revokeUnusedSharedUserPermissionsLocked( if (revokeUnusedSharedUserPermissionsLocked(uidRequestedPermissions,
mPackageManagerInt.getSharedUserPackages(ps.getSharedUserAppId()),
uidState)) { uidState)) {
updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId); updatedUserIds = ArrayUtils.appendInt(updatedUserIds, userId);
runtimePermissionsRevoked = true; runtimePermissionsRevoked = true;
@@ -2909,8 +2913,9 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
userState.setInstallPermissionsFixed(ps.getPackageName(), true); userState.setInstallPermissionsFixed(ps.getPackageName(), true);
} }
updatedUserIds = revokePermissionsNoLongerImplicitLocked(uidState, pkg, updatedUserIds = revokePermissionsNoLongerImplicitLocked(uidState,
userId, updatedUserIds); pkg.getPackageName(), uidImplicitPermissions, uidTargetSdkVersion, userId,
updatedUserIds);
updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origState, updatedUserIds = setInitialGrantForNewImplicitPermissionsLocked(origState,
uidState, pkg, newImplicitPermissions, userId, updatedUserIds); uidState, pkg, newImplicitPermissions, userId, updatedUserIds);
} }
@@ -2947,7 +2952,9 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
* {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set. * {@link PackageManager#FLAG_PERMISSION_REVOKE_WHEN_REQUESTED} set.
* *
* @param ps The state of the permissions of the package * @param ps The state of the permissions of the package
* @param pkg The package that is currently looked at * @param packageName The name of the package
* @param uidImplicitPermissions The implicit permissions of all packages in the UID
* @param uidTargetSdkVersion The lowest target SDK version of all packages in the UID
* @param userIds All user IDs in the system, must be passed in because this method is locked * @param userIds All user IDs in the system, must be passed in because this method is locked
* @param updatedUserIds a list of user ids that needs to be amended if the permission state * @param updatedUserIds a list of user ids that needs to be amended if the permission state
* for a user is changed. * for a user is changed.
@@ -2957,14 +2964,12 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
@NonNull @NonNull
@GuardedBy("mLock") @GuardedBy("mLock")
private int[] revokePermissionsNoLongerImplicitLocked(@NonNull UidPermissionState ps, private int[] revokePermissionsNoLongerImplicitLocked(@NonNull UidPermissionState ps,
@NonNull AndroidPackage pkg, int userId, @NonNull int[] updatedUserIds) { @NonNull String packageName, @NonNull Collection<String> uidImplicitPermissions,
String pkgName = pkg.getPackageName(); int uidTargetSdkVersion, int userId, @NonNull int[] updatedUserIds) {
boolean supportsRuntimePermissions = pkg.getTargetSdkVersion() boolean supportsRuntimePermissions = uidTargetSdkVersion >= Build.VERSION_CODES.M;
>= Build.VERSION_CODES.M;
for (String permission : ps.getGrantedPermissions()) { for (String permission : ps.getGrantedPermissions()) {
if (pkg.getRequestedPermissions().contains(permission) if (!uidImplicitPermissions.contains(permission)) {
&& !pkg.getImplicitPermissions().contains(permission)) {
Permission bp = mRegistry.getPermission(permission); Permission bp = mRegistry.getPermission(permission);
if (bp != null && bp.isRuntime()) { if (bp != null && bp.isRuntime()) {
int flags = ps.getPermissionFlags(permission); int flags = ps.getPermissionFlags(permission);
@@ -2991,7 +2996,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
if (ps.revokePermission(bp)) { if (ps.revokePermission(bp)) {
if (DEBUG_PERMISSIONS) { if (DEBUG_PERMISSIONS) {
Slog.i(TAG, "Revoking runtime permission " Slog.i(TAG, "Revoking runtime permission "
+ permission + " for " + pkgName + permission + " for " + packageName
+ " as it is now requested"); + " as it is now requested");
} }
} }
@@ -3822,27 +3827,8 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
@GuardedBy("mLock") @GuardedBy("mLock")
private boolean revokeUnusedSharedUserPermissionsLocked( private boolean revokeUnusedSharedUserPermissionsLocked(
ArraySet<PackageStateInternal> pkgList, UidPermissionState uidState) { @NonNull Collection<String> uidRequestedPermissions,
// Collect all used permissions in the UID @NonNull UidPermissionState uidState) {
final ArraySet<String> usedPermissions = new ArraySet<>();
if (pkgList == null || pkgList.size() == 0) {
return false;
}
for (PackageStateInternal pkgState : pkgList) {
final AndroidPackageApi pkg = pkgState.getAndroidPackage();
if (pkg.getRequestedPermissions().isEmpty()) {
continue;
}
final int requestedPermCount = pkg.getRequestedPermissions().size();
for (int j = 0; j < requestedPermCount; j++) {
String permission = pkg.getRequestedPermissions().get(j);
Permission bp = mRegistry.getPermission(permission);
if (bp != null) {
usedPermissions.add(permission);
}
}
}
boolean runtimePermissionChanged = false; boolean runtimePermissionChanged = false;
// Prune permissions // Prune permissions
@@ -3850,7 +3836,7 @@ public class PermissionManagerServiceImpl implements PermissionManagerServiceInt
final int permissionStatesSize = permissionStates.size(); final int permissionStatesSize = permissionStates.size();
for (int i = permissionStatesSize - 1; i >= 0; i--) { for (int i = permissionStatesSize - 1; i >= 0; i--) {
PermissionState permissionState = permissionStates.get(i); PermissionState permissionState = permissionStates.get(i);
if (!usedPermissions.contains(permissionState.getName())) { if (!uidRequestedPermissions.contains(permissionState.getName())) {
Permission bp = mRegistry.getPermission(permissionState.getName()); Permission bp = mRegistry.getPermission(permissionState.getName());
if (bp != null) { if (bp != null) {
if (uidState.removePermissionState(bp.getName()) && bp.isRuntime()) { if (uidState.removePermissionState(bp.getName()) && bp.isRuntime()) {