Always use PermMgrSrv APIs to change permission

So that the appropriate callbacks are called when a permission is
changed.

Test: cleared package state and saw PermissionPolicyService being run
Bug: 132704705
Change-Id: Iea53b463fcc7d73dde89efbe91a7c5fa8b65bd7b
This commit is contained in:
Philip P. Moltmann
2019-06-13 15:49:08 -07:00
parent 61a878126c
commit cf5e437b6c

View File

@@ -111,9 +111,6 @@ import static com.android.server.pm.PackageManagerServiceUtils.getCompressedFile
import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime; import static com.android.server.pm.PackageManagerServiceUtils.getLastModifiedTime;
import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo; import static com.android.server.pm.PackageManagerServiceUtils.logCriticalInfo;
import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures; import static com.android.server.pm.PackageManagerServiceUtils.verifySignatures;
import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_FAILURE;
import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS;
import static com.android.server.pm.permission.PermissionsState.PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED;
import android.Manifest; import android.Manifest;
import android.annotation.IntDef; import android.annotation.IntDef;
@@ -294,6 +291,7 @@ import com.android.internal.util.ConcurrentUtils;
import com.android.internal.util.DumpUtils; import com.android.internal.util.DumpUtils;
import com.android.internal.util.FastXmlSerializer; import com.android.internal.util.FastXmlSerializer;
import com.android.internal.util.IndentingPrintWriter; import com.android.internal.util.IndentingPrintWriter;
import com.android.internal.util.IntPair;
import com.android.internal.util.Preconditions; import com.android.internal.util.Preconditions;
import com.android.server.AttributeCache; import com.android.server.AttributeCache;
import com.android.server.DeviceIdleController; import com.android.server.DeviceIdleController;
@@ -19801,6 +19799,8 @@ public class PackageManagerService extends IPackageManager.Stub
return; return;
} }
final String packageName = ps.pkg.packageName;
// These are flags that can change base on user actions. // These are flags that can change base on user actions.
final int userSettableMask = FLAG_PERMISSION_USER_SET final int userSettableMask = FLAG_PERMISSION_USER_SET
| FLAG_PERMISSION_USER_FIXED | FLAG_PERMISSION_USER_FIXED
@@ -19810,8 +19810,59 @@ public class PackageManagerService extends IPackageManager.Stub
final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED final int policyOrSystemFlags = FLAG_PERMISSION_SYSTEM_FIXED
| FLAG_PERMISSION_POLICY_FIXED; | FLAG_PERMISSION_POLICY_FIXED;
boolean writeInstallPermissions = false; // Delay and combine non-async permission callbacks
boolean writeRuntimePermissions = false; final boolean[] permissionRemoved = new boolean[1];
final ArraySet<Long> revokedPermissions = new ArraySet<>();
final SparseBooleanArray updatedUsers = new SparseBooleanArray();
PermissionCallback delayingPermCallback = new PermissionCallback() {
public void onGidsChanged(int appId, int userId) {
mPermissionCallback.onGidsChanged(appId, userId);
}
public void onPermissionChanged() {
mPermissionCallback.onPermissionChanged();
}
public void onPermissionGranted(int uid, int userId) {
mPermissionCallback.onPermissionGranted(uid, userId);
}
public void onInstallPermissionGranted() {
mPermissionCallback.onInstallPermissionGranted();
}
public void onPermissionRevoked(int uid, int userId) {
revokedPermissions.add(IntPair.of(uid, userId));
updatedUsers.put(userId, true);
}
public void onInstallPermissionRevoked() {
mPermissionCallback.onInstallPermissionRevoked();
}
public void onPermissionUpdated(int[] updatedUserIds, boolean sync) {
for (int userId : updatedUserIds) {
if (sync) {
updatedUsers.put(userId, true);
} else {
// Don't override sync=true by sync=false
if (!updatedUsers.get(userId)) {
updatedUsers.put(userId, false);
}
}
}
}
public void onPermissionRemoved() {
permissionRemoved[0] = true;
}
public void onInstallPermissionUpdated() {
mPermissionCallback.onInstallPermissionUpdated();
}
};
final int permissionCount = ps.pkg.requestedPermissions.size(); final int permissionCount = ps.pkg.requestedPermissions.size();
for (int i = 0; i < permissionCount; i++) { for (int i = 0; i < permissionCount; i++) {
@@ -19843,26 +19894,20 @@ public class PackageManagerService extends IPackageManager.Stub
} }
} }
final PermissionsState permissionsState = ps.getPermissionsState(); final int oldFlags = mPermissionManager.getPermissionFlags(permName, packageName,
Process.SYSTEM_UID, userId);
final int oldFlags = permissionsState.getPermissionFlags(permName, userId);
// Always clear the user settable flags. // Always clear the user settable flags.
final boolean hasInstallState =
permissionsState.getInstallPermissionState(permName) != null;
// If permission review is enabled and this is a legacy app, mark the // If permission review is enabled and this is a legacy app, mark the
// permission as requiring a review as this is the initial state. // permission as requiring a review as this is the initial state.
int flags = 0; int flags = 0;
if (ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M && bp.isRuntime()) { if (ps.pkg.applicationInfo.targetSdkVersion < Build.VERSION_CODES.M && bp.isRuntime()) {
flags |= FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKE_ON_UPGRADE; flags |= FLAG_PERMISSION_REVIEW_REQUIRED | FLAG_PERMISSION_REVOKE_ON_UPGRADE;
} }
if (permissionsState.updatePermissionFlags(bp, userId, userSettableMask, flags)) {
if (hasInstallState) { mPermissionManager.updatePermissionFlags(permName, packageName,
writeInstallPermissions = true; userSettableMask, flags, Process.SYSTEM_UID, userId, false,
} else { delayingPermCallback);
writeRuntimePermissions = true;
}
}
// Below is only runtime permission handling. // Below is only runtime permission handling.
if (!bp.isRuntime()) { if (!bp.isRuntime()) {
@@ -19876,35 +19921,42 @@ public class PackageManagerService extends IPackageManager.Stub
// If this permission was granted by default, make sure it is. // If this permission was granted by default, make sure it is.
if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) { if ((oldFlags & FLAG_PERMISSION_GRANTED_BY_DEFAULT) != 0) {
if (permissionsState.grantRuntimePermission(bp, userId) mPermissionManager.grantRuntimePermission(permName, packageName, false,
!= PERMISSION_OPERATION_FAILURE) { Process.SYSTEM_UID, userId, delayingPermCallback);
writeRuntimePermissions = true;
}
// If permission review is enabled the permissions for a legacy apps // If permission review is enabled the permissions for a legacy apps
// are represented as constantly granted runtime ones, so don't revoke. // are represented as constantly granted runtime ones, so don't revoke.
} else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) { } else if ((flags & FLAG_PERMISSION_REVIEW_REQUIRED) == 0) {
// Otherwise, reset the permission. // Otherwise, reset the permission.
final int revokeResult = permissionsState.revokeRuntimePermission(bp, userId); mPermissionManager.revokeRuntimePermission(permName, packageName, false, userId,
switch (revokeResult) { delayingPermCallback);
case PERMISSION_OPERATION_SUCCESS:
case PERMISSION_OPERATION_SUCCESS_GIDS_CHANGED: {
writeRuntimePermissions = true;
final int appId = ps.appId;
mHandler.post(
() -> killUid(appId, userId, KILL_APP_REASON_PERMISSIONS_REVOKED));
} break;
}
} }
} }
// Synchronously write as we are taking permissions away. // Execute delayed callbacks
if (writeRuntimePermissions) { if (permissionRemoved[0]) {
mSettings.writeRuntimePermissionsForUserLPr(userId, true); mPermissionCallback.onPermissionRemoved();
} }
// Synchronously write as we are taking permissions away. // Slight variation on the code in mPermissionCallback.onPermissionRevoked() as we cannot
if (writeInstallPermissions) { // kill uid while holding mPackages-lock
mSettings.writeLPr(); if (!revokedPermissions.isEmpty()) {
int numRevokedPermissions = revokedPermissions.size();
for (int i = 0; i < numRevokedPermissions; i++) {
int revocationUID = IntPair.first(revokedPermissions.valueAt(i));
int revocationUserId = IntPair.second(revokedPermissions.valueAt(i));
mOnPermissionChangeListeners.onPermissionsChanged(revocationUID);
// Kill app later as we are holding mPackages
mHandler.post(() -> killUid(UserHandle.getAppId(revocationUID), revocationUserId,
KILL_APP_REASON_PERMISSIONS_REVOKED));
}
}
int numUpdatedUsers = updatedUsers.size();
for (int i = 0; i < numUpdatedUsers; i++) {
mSettings.writeRuntimePermissionsForUserLPr(updatedUsers.keyAt(i),
updatedUsers.valueAt(i));
} }
} }