diff options
| author | 2023-04-21 15:20:36 +0000 | |
|---|---|---|
| committer | 2023-04-25 16:57:05 +0000 | |
| commit | 41af70da37f9973ed065fe75b0f4009f360dc609 (patch) | |
| tree | 57d37b2bbb4c3b1bb00e7d74cc2f226b8d7ba003 | |
| parent | 9c6a31ea6583b3c89761c5ac19f28391a8498bac (diff) | |
Fix permission access to wipeData/Device
Bug: 278857275
Fixes: 254031494
Test: btest a.d.c.WipeDataTest
Test: manual
Change-Id: Icf9a6cbb7f1eab355012c91998744a895af3861a
| -rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java | 86 |
1 files changed, 66 insertions, 20 deletions
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index f6bc93ab2491..473e61036731 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -80,6 +80,7 @@ import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WIFI; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WINDOWS; import static android.Manifest.permission.MANAGE_DEVICE_POLICY_WIPE_DATA; import static android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS; +import static android.Manifest.permission.MASTER_CLEAR; import static android.Manifest.permission.QUERY_ADMIN_POLICY; import static android.Manifest.permission.REQUEST_PASSWORD_COMPLEXITY; import static android.Manifest.permission.SET_TIME; @@ -7548,9 +7549,9 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { boolean calledByProfileOwnerOnOrgOwnedDevice = isProfileOwnerOfOrganizationOwnedDevice(caller.getUserId()); if (isPolicyEngineForFinanceFlagEnabled()) { - EnforcingAdmin enforcingAdmin = enforcePermissionAndGetEnforcingAdmin( + EnforcingAdmin enforcingAdmin = enforcePermissionsAndGetEnforcingAdmin( /*admin=*/ null, - /*permission= */ MANAGE_DEVICE_POLICY_WIPE_DATA, + /*permission=*/ new String[]{MANAGE_DEVICE_POLICY_WIPE_DATA, MASTER_CLEAR}, USES_POLICY_WIPE_DATA, caller.getPackageName(), factoryReset ? UserHandle.USER_ALL : getAffectedUser(calledOnParentInstance)); @@ -7572,12 +7573,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { admin = getActiveAdminWithPolicyForUidLocked(/* who= */ null, DeviceAdminInfo.USES_POLICY_WIPE_DATA, caller.getUid()); } + Preconditions.checkCallAuthorization( + (admin != null) || hasCallingOrSelfPermission(permission.MASTER_CLEAR), + "No active admin for user %d and caller %d does not hold MASTER_CLEAR " + + "permission", + caller.getUserId(), caller.getUid()); } - Preconditions.checkCallAuthorization( - (admin != null) || hasCallingOrSelfPermission(permission.MASTER_CLEAR), - "No active admin for user %d and caller %d does not hold MASTER_CLEAR permission", - caller.getUserId(), caller.getUid()); checkCanExecuteOrThrowUnsafe(DevicePolicyManager.OPERATION_WIPE_DATA); if (TextUtils.isEmpty(wipeReasonForUser)) { @@ -7832,15 +7834,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } else { // Explicit behaviour if (factoryReset) { - // TODO(b/254031494) Replace with new factory reset permission checks - if (!isPermissionCheckFlagEnabled()) { - boolean hasPermission = isDeviceOwnerUserId(userId) - || (isOrganizationOwnedDeviceWithManagedProfile() - && calledOnParentInstance); - Preconditions.checkCallAuthorization(hasPermission, - "Admin %s does not have permission to factory reset the device.", - userId); - } + EnforcingAdmin enforcingAdmin = enforcePermissionsAndGetEnforcingAdmin( + /*admin=*/ null, + /*permission=*/ new String[]{MANAGE_DEVICE_POLICY_WIPE_DATA, + MASTER_CLEAR}, + USES_POLICY_WIPE_DATA, + adminPackage, + factoryReset ? UserHandle.USER_ALL : + getAffectedUser(calledOnParentInstance)); wipeDevice = true; } else { Preconditions.checkCallAuthorization(!isSystemUser, @@ -23121,6 +23122,28 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } /** + * Checks if the calling process has been granted permission to apply a device policy on a + * specific user. Only one permission provided in the list needs to be granted to pass this + * check. + * The given permissions will be checked along with their associated cross-user permissions if + * they exist and the target user is different to the calling user. + * Returns an {@link EnforcingAdmin} for the caller. + * + * @param admin the component name of the admin. + * @param callerPackageName The package name of the calling application. + * @param permissions The names of the permissions being checked. + * @param deviceAdminPolicy The userId of the user which the caller needs permission to act on. + * @throws SecurityException if the caller has not been granted the given permission, + * the associated cross-user permission if the caller's user is different to the target user. + */ + private EnforcingAdmin enforcePermissionsAndGetEnforcingAdmin(@Nullable ComponentName admin, + String[] permissions, int deviceAdminPolicy, String callerPackageName, + int targetUserId) { + enforcePermissions(permissions, deviceAdminPolicy, callerPackageName, targetUserId); + return getEnforcingAdminForCaller(admin, callerPackageName); + } + + /** * Checks whether the calling process has been granted permission to query a device policy on * a specific user. * The given permission will be checked along with its associated cross-user permission if it @@ -23166,12 +23189,13 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { /** * Checks if the calling process has been granted permission to apply a device policy on a - * specific user. - * The given permission will be checked along with its associated cross-user permission if it - * exists and the target user is different to the calling user. + * specific user. Only one permission provided in the list needs to be granted to pass this + * check. + * The given permissions will be checked along with their associated cross-user permissions if + * they exists and the target user is different to the calling user. * * @param callerPackageName The package name of the calling application. - * @param permission The name of the permission being checked. + * @param permissions The names of the permissions being checked. * @param targetUserId The userId of the user which the caller needs permission to act on. * @throws SecurityException if the caller has not been granted the given permission, * the associated cross-user permission if the caller's user is different to the target user. @@ -23236,6 +23260,27 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } /** + * Checks if the calling process has been granted permission to apply a device policy on a + * specific user. + * The given permission will be checked along with its associated cross-user permission if it + * exists and the target user is different to the calling user. + * + * @param callerPackageName The package name of the calling application. + * @param adminPolicy The admin policy that should grant holders permission. + * @param permission The name of the permission being checked. + * @param targetUserId The userId of the user which the caller needs permission to act on. + * @throws SecurityException if the caller has not been granted the given permission, + * the associated cross-user permission if the caller's user is different to the target user. + */ + private void enforcePermissions(String[] permissions, int adminPolicy, + String callerPackageName, int targetUserId) throws SecurityException { + if (hasAdminPolicy(adminPolicy, callerPackageName)) { + return; + } + enforcePermissions(permissions, callerPackageName, targetUserId); + } + + /** * Checks whether the calling process has been granted permission to query a device policy on * a specific user. * The given permission will be checked along with its associated cross-user permission if it @@ -23362,7 +23407,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { // Check for non-DPC active admins. admin = getActiveAdminForCaller(who, caller); if (admin != null) { - return EnforcingAdmin.createDeviceAdminEnforcingAdmin(who, userId, admin); + return EnforcingAdmin.createDeviceAdminEnforcingAdmin(admin.info.getComponent(), userId, + admin); } admin = getUserData(userId).createOrGetPermissionBasedAdmin(userId); return EnforcingAdmin.createEnforcingAdmin(caller.getPackageName(), userId, admin); |