diff options
| author | 2020-08-17 10:35:18 +0100 | |
|---|---|---|
| committer | 2020-08-19 12:57:50 +0100 | |
| commit | 65eacc95e387cb8d3fd3620aa69ffb07f93c0047 (patch) | |
| tree | 84410fae90296e9d4ed8ed596c006b537ef5b59d | |
| parent | 509f1c79df9186f9757fbffafa891585575c9304 (diff) | |
Replace enforce permission checks in DPMS
Replaced
* enforceFullCrossUsersPermission -> hasFullCrossUsersPermission
* enforceCrossUsersPermission -> hasCrossUsersPermission
Removed
* enforceSystemUserOrPermissionIfCrossUser
* enforceSystemUserOrPermission
* enforceAcrossUsersPermissions
* hasMarkProfileOwnerOnOrganizationOwnedDevicePermission
Updated methods
* getCurrentFailedPasswordAttempts
* getAllCrossProfilePackages
* setActiveAdmin
* isAdminActive
* isRemovingAdmin
* hasGrantedPolicy
* getActiveAdmins
* packageHasActiveAdmins
* removeActiveAdmin
* getPasswordQuality
* getPasswordExpirationTimeout
* getPasswordExpiration
* getStrictestPasswordRequirement
* getPasswordMinimumMetrics
* isActivePasswordSufficient
* isProfileActivePasswordSufficientForParent
* isPasswordSufficientAfterProfileUnification
* getCurrentFailedPasswordAttempts
* getMaximumFailedPasswordsForWipe
* getProfileWithMinimumFailedPasswordsForWipe
* getMaximumTimeToLock
* getRequiredStrongAuthTimeout
* wipeDataWithReason
* getRemoveWarning
* reportFailedPasswordAttempt
* reportSuccessfulPasswordAttempt
* reportFailedBiometricAttempt
* reportSuccessfulBiometricAttempt
* reportKeyguardDismissed
* reportKeyguardSecured
* getGlobalProxyAdmin
* getStorageEncryption
* getStorageEncryptionStatus
* getKeyguardDisabledFeatures
* getTrustAgentConfiguration
* getAccountTypesWithManagementDisabledAsUser
* setOrganizationColorForUser
* getOrganizationColorForUser
* getOrganizationNameForUser
* getProfileOwnerAsUser
* getCrossProfileCallerIdDisabledForUser
* getCrossProfileContactsSearchDisabledForUser
* isPackageAllowedToAccessCalendarForUser
* getCrossProfileCalendarPackagesForUser
* getActiveAdminOrCheckPermissionForCallerLocked
* resetPassword
* lockNow
* enforceNetworkStackOrProfileOrDeviceOwner
* getFactoryResetProtectionPolicy
Bug: 165302873
Test: atest com.android.server.devicepolicy.DevicePolicyManagerTest
atest com.google.android.cts.deviceowner.DeviceOwnerTest
atest com.android.cts.devicepolicy.MixedDeviceOwnerTest
atest com.android.cts.devicepolicy.MixedProfileOwnerTest
atest com.android.cts.devicepolicy.OrgOwnedProfileOwnerTest
Change-Id: Ic3fea2f0483c02623a21bc3a67ff6bd29fbcc792
3 files changed, 295 insertions, 144 deletions
diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 6154bef2bda3..f4e8d05e8da6 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -1566,7 +1566,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { /** * Creates a new {@link CallerIdentity} object to represent the caller's identity. */ - private CallerIdentity getCallerIdentity(String callerPackage) { + private CallerIdentity getCallerIdentity() { + final int callerUid = mInjector.binderGetCallingUid(); + return new CallerIdentity(callerUid, null, null); + } + + /** + * Creates a new {@link CallerIdentity} object to represent the caller's identity. + */ + private CallerIdentity getCallerIdentity(@NonNull String callerPackage) { final int callerUid = mInjector.binderGetCallingUid(); if (!isCallingFromPackage(callerPackage, callerUid)) { @@ -2145,9 +2153,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { ActiveAdmin result = getActiveAdminWithPolicyForUidLocked(who, reqPolicy, callingUid); if (result != null) { return result; - } else if (permission != null - && (mContext.checkCallingPermission(permission) - == PackageManager.PERMISSION_GRANTED)) { + } else if (permission != null && hasCallingPermission(permission)) { return null; } @@ -2844,9 +2850,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { private void setActiveAdmin(ComponentName adminReceiver, boolean refreshing, int userHandle, Bundle onEnableData) { - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.MANAGE_DEVICE_ADMINS, null); - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization( + hasCallingOrSelfPermission(permission.MANAGE_DEVICE_ADMINS)); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); DevicePolicyData policy = getUserData(userHandle); DeviceAdminInfo info = findAdmin(adminReceiver, userHandle, @@ -2986,7 +2995,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return false; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + synchronized (getLockObject()) { return getActiveAdminUncheckedLocked(adminReceiver, userHandle) != null; } @@ -2997,7 +3010,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return false; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + synchronized (getLockObject()) { DevicePolicyData policyData = getUserData(userHandle); return policyData.mRemovingAdmins.contains(adminReceiver); @@ -3009,7 +3026,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return false; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(adminReceiver); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + synchronized (getLockObject()) { ActiveAdmin administrator = getActiveAdminUncheckedLocked(adminReceiver, userHandle); if (administrator == null) { @@ -3025,8 +3046,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return Collections.EMPTY_LIST; } + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); - enforceFullCrossUsersPermission(userHandle); synchronized (getLockObject()) { DevicePolicyData policy = getUserData(userHandle); final int N = policy.mAdminList.size(); @@ -3046,7 +3070,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return false; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + synchronized (getLockObject()) { DevicePolicyData policy = getUserData(userHandle); final int N = policy.mAdminList.size(); @@ -3156,8 +3184,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); enforceUserUnlocked(userHandle); + synchronized (getLockObject()) { ActiveAdmin admin = getActiveAdminUncheckedLocked(adminReceiver, userHandle); if (admin == null) { @@ -3309,7 +3341,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return PASSWORD_QUALITY_UNSPECIFIED; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + synchronized (getLockObject()) { int mode = PASSWORD_QUALITY_UNSPECIFIED; @@ -3521,7 +3557,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) { return 0L; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + synchronized (getLockObject()) { long timeout = 0L; @@ -3656,7 +3696,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) { return 0L; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + synchronized (getLockObject()) { return getPasswordExpirationLocked(who, userHandle, parent); } @@ -3862,7 +3906,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return 0; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + synchronized (getLockObject()) { if (who != null) { final ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent); @@ -3902,7 +3950,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { new PasswordMetrics(CREDENTIAL_TYPE_NONE); } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + ArrayList<PasswordMetrics> adminMetrics = new ArrayList<>(); synchronized (getLockObject()) { List<ActiveAdmin> admins = @@ -3919,7 +3971,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return true; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); enforceUserUnlocked(userHandle, parent); synchronized (getLockObject()) { @@ -3951,7 +4006,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return true; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); enforceManagedProfile(userHandle, "call APIs refering to the parent profile"); synchronized (getLockObject()) { @@ -3970,7 +4028,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return true; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); enforceNotManagedProfile(userHandle, "check password sufficiency"); enforceUserUnlocked(userHandle); @@ -4058,12 +4119,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mLockPatternUtils.hasSecureLockScreen()) { return 0; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + synchronized (getLockObject()) { - if (!isCallerWithSystemUid()) { + if (!isSystemUid(identity)) { // This API can be called by an active device admin or by keyguard code. - if (mContext.checkCallingPermission(permission.ACCESS_KEYGUARD_SECURE_STORAGE) - != PackageManager.PERMISSION_GRANTED) { + if (!hasCallingPermission(permission.ACCESS_KEYGUARD_SECURE_STORAGE)) { getActiveAdminForCallerLocked( null, DeviceAdminInfo.USES_POLICY_WATCH_LOGIN, parent); } @@ -4106,7 +4170,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) { return 0; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + synchronized (getLockObject()) { ActiveAdmin admin = (who != null) ? getActiveAdminUncheckedLocked(who, userHandle, parent) @@ -4120,7 +4188,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature || !mLockPatternUtils.hasSecureLockScreen()) { return UserHandle.USER_NULL; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + synchronized (getLockObject()) { ActiveAdmin admin = getAdminWithMinimumFailedPasswordsForWipeLocked( userHandle, parent); @@ -4191,8 +4263,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // As of R, only privlleged caller holding RESET_PASSWORD can call resetPassword() to // set password to an unsecured user. - if (mContext.checkCallingPermission(permission.RESET_PASSWORD) - == PackageManager.PERMISSION_GRANTED) { + if (hasCallingPermission(permission.RESET_PASSWORD)) { return setPasswordPrivileged(password, flags, callingUid); } @@ -4392,7 +4463,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return 0; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + synchronized (getLockObject()) { if (who != null) { final ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userHandle, parent); @@ -4465,12 +4540,16 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return DevicePolicyManager.DEFAULT_STRONG_AUTH_TIMEOUT_MS; } + Preconditions.checkArgumentNonnegative(userId, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userId)); + if (!mLockPatternUtils.hasSecureLockScreen()) { // No strong auth timeout on devices not supporting the // {@link PackageManager#FEATURE_SECURE_LOCK_SCREEN} feature return 0; } - enforceFullCrossUsersPermission(userId); synchronized (getLockObject()) { if (who != null) { ActiveAdmin admin = getActiveAdminUncheckedLocked(who, userId, parent); @@ -4504,8 +4583,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void lockNow(int flags, boolean parent) { - if (!mHasFeature && mContext.checkCallingPermission(android.Manifest.permission.LOCK_DEVICE) - != PackageManager.PERMISSION_GRANTED) { + if (!mHasFeature && !hasCallingPermission(permission.LOCK_DEVICE)) { return; } @@ -4597,8 +4675,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } private void enforceNetworkStackOrProfileOrDeviceOwner(ComponentName who) { - if (mContext.checkCallingPermission(PERMISSION_MAINLINE_NETWORK_STACK) - == PackageManager.PERMISSION_GRANTED) { + if (hasCallingPermission(PERMISSION_MAINLINE_NETWORK_STACK)) { return; } enforceProfileOrDeviceOwner(who); @@ -5677,8 +5754,9 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return; } - - enforceFullCrossUsersPermission(mInjector.userHandleGetCallingUserId()); + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(isSystemUid(identity) || isRootUid(identity) + || hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS_FULL)); final ActiveAdmin admin; synchronized (getLockObject()) { @@ -5854,8 +5932,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { synchronized (getLockObject()) { if (who == null) { if ((frpManagementAgentUid != mInjector.binderGetCallingUid()) - && (mContext.checkCallingPermission(permission.MASTER_CLEAR) - != PackageManager.PERMISSION_GRANTED)) { + && !hasCallingPermission(permission.MASTER_CLEAR)) { throw new SecurityException( "Must be called by the FRP management agent on device"); } @@ -5893,9 +5970,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return; } - enforceFullCrossUsersPermission(userHandle); - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.BIND_DEVICE_ADMIN, null); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = comp != null + ? getCallerIdentity(comp) + : getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(BIND_DEVICE_ADMIN)); synchronized (getLockObject()) { ActiveAdmin admin = getActiveAdminUncheckedLocked(comp, userHandle); @@ -5972,13 +6053,15 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void reportFailedPasswordAttempt(int userHandle) { - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(BIND_DEVICE_ADMIN)); if (!isSeparateProfileChallengeEnabled(userHandle)) { enforceNotManagedProfile(userHandle, "report failed password attempt if separate profile challenge is not in place"); } - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.BIND_DEVICE_ADMIN, null); boolean wipeData = false; ActiveAdmin strictestAdmin = null; @@ -6051,9 +6134,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void reportSuccessfulPasswordAttempt(int userHandle) { - enforceFullCrossUsersPermission(userHandle); - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.BIND_DEVICE_ADMIN, null); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(BIND_DEVICE_ADMIN)); synchronized (getLockObject()) { DevicePolicyData policy = getUserData(userHandle); @@ -6079,9 +6164,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void reportFailedBiometricAttempt(int userHandle) { - enforceFullCrossUsersPermission(userHandle); - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.BIND_DEVICE_ADMIN, null); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(BIND_DEVICE_ADMIN)); + if (mInjector.securityLogIsLoggingEnabled()) { SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT, /*result*/ 0, /*method strength*/ 0); @@ -6090,9 +6178,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void reportSuccessfulBiometricAttempt(int userHandle) { - enforceFullCrossUsersPermission(userHandle); - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.BIND_DEVICE_ADMIN, null); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(BIND_DEVICE_ADMIN)); + if (mInjector.securityLogIsLoggingEnabled()) { SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_DISMISS_AUTH_ATTEMPT, /*result*/ 1, /*method strength*/ 0); @@ -6101,9 +6192,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void reportKeyguardDismissed(int userHandle) { - enforceFullCrossUsersPermission(userHandle); - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.BIND_DEVICE_ADMIN, null); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(BIND_DEVICE_ADMIN)); if (mInjector.securityLogIsLoggingEnabled()) { SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_DISMISSED); @@ -6112,9 +6205,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public void reportKeyguardSecured(int userHandle) { - enforceFullCrossUsersPermission(userHandle); - mContext.enforceCallingOrSelfPermission( - android.Manifest.permission.BIND_DEVICE_ADMIN, null); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + Preconditions.checkCallAuthorization(hasCallingOrSelfPermission(BIND_DEVICE_ADMIN)); if (mInjector.securityLogIsLoggingEnabled()) { SecurityLog.writeEvent(SecurityLog.TAG_KEYGUARD_SECURED); @@ -6176,7 +6271,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return null; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + synchronized (getLockObject()) { DevicePolicyData policy = getUserData(UserHandle.USER_SYSTEM); // Scan through active admins and find if anyone has already @@ -6310,7 +6409,13 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return false; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = who != null + ? getCallerIdentity(who) + : getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + synchronized (getLockObject()) { // Check for permissions if a particular caller is specified if (who != null) { @@ -6340,7 +6445,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { // Ok to return current status. } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = callerPackage != null + ? getCallerIdentity(callerPackage) + : getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); // It's not critical here, but let's make sure the package name is correct, in case // we start using it for different purposes. @@ -7033,7 +7143,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return 0; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + final long ident = mInjector.binderClearCallingIdentity(); try { synchronized (getLockObject()) { @@ -7783,7 +7897,10 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public ComponentName getProfileOwnerAsUser(int userHandle) { - enforceCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasCrossUsersPermission(identity, userHandle)); return getProfileOwner(userHandle); } @@ -8140,56 +8257,31 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { } } - private void enforceAcrossUsersPermissions() { - final int callingUid = mInjector.binderGetCallingUid(); - final int callingPid = mInjector.binderGetCallingPid(); - final String packageName = mContext.getPackageName(); - - if (isCallerWithSystemUid() || callingUid == Process.ROOT_UID) { - return; - } - if (PermissionChecker.checkPermissionForPreflight( - mContext, permission.INTERACT_ACROSS_PROFILES, callingPid, callingUid, - packageName) == PermissionChecker.PERMISSION_GRANTED) { - return; - } - if (mContext.checkCallingPermission(permission.INTERACT_ACROSS_USERS) - == PackageManager.PERMISSION_GRANTED) { - return; - } - if (mContext.checkCallingPermission(permission.INTERACT_ACROSS_USERS_FULL) - == PackageManager.PERMISSION_GRANTED) { - return; - } - throw new SecurityException("Calling user does not have INTERACT_ACROSS_PROFILES or" - + "INTERACT_ACROSS_USERS or INTERACT_ACROSS_USERS_FULL permissions"); + private boolean hasCallingPermission(String permission) { + return mContext.checkCallingPermission(permission) == PackageManager.PERMISSION_GRANTED; } - private void enforceFullCrossUsersPermission(int userHandle) { - enforceSystemUserOrPermissionIfCrossUser(userHandle, - android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); + private boolean hasCallingOrSelfPermission(String permission) { + return mContext.checkCallingOrSelfPermission(permission) + == PackageManager.PERMISSION_GRANTED; } - private void enforceCrossUsersPermission(int userHandle) { - enforceSystemUserOrPermissionIfCrossUser(userHandle, - android.Manifest.permission.INTERACT_ACROSS_USERS); + private boolean hasPermissionForPreflight(CallerIdentity identity, String permission) { + final int callingPid = mInjector.binderGetCallingPid(); + final String packageName = mContext.getPackageName(); + + return PermissionChecker.checkPermissionForPreflight(mContext, permission, callingPid, + identity.getUid(), packageName) == PermissionChecker.PERMISSION_GRANTED; } - private void enforceSystemUserOrPermission(String permission) { - if (!(isCallerWithSystemUid() || mInjector.binderGetCallingUid() == Process.ROOT_UID)) { - mContext.enforceCallingOrSelfPermission(permission, - "Must be system or have " + permission + " permission"); - } + private boolean hasFullCrossUsersPermission(CallerIdentity identity, int userHandle) { + return (userHandle == identity.getUserId()) || isSystemUid(identity) || isRootUid(identity) + || hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS_FULL); } - private void enforceSystemUserOrPermissionIfCrossUser(int userHandle, String permission) { - if (userHandle < 0) { - throw new IllegalArgumentException("Invalid userId " + userHandle); - } - if (userHandle == mInjector.userHandleGetCallingUserId()) { - return; - } - enforceSystemUserOrPermission(permission); + private boolean hasCrossUsersPermission(CallerIdentity identity, int userHandle) { + return (userHandle == identity.getUserId()) || isSystemUid(identity) || isRootUid(identity) + || hasCallingOrSelfPermission(permission.INTERACT_ACROSS_USERS); } private void enforceManagedProfile(int userId, String message) { @@ -8249,19 +8341,18 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { throw new SecurityException("No active admin found"); } - private void enforceProfileOwnerOrFullCrossUsersPermission(int userId) { - if (userId == mInjector.userHandleGetCallingUserId()) { + private void enforceProfileOwnerOrFullCrossUsersPermission(CallerIdentity identity, + int userId) { + if (userId == identity.getUserId()) { synchronized (getLockObject()) { if (getActiveAdminWithPolicyForUidLocked(null, - DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, mInjector.binderGetCallingUid()) - != null) { + DeviceAdminInfo.USES_POLICY_PROFILE_OWNER, identity.getUid()) != null) { // Device Owner/Profile Owner may access the user it runs on. return; } } } - // Otherwise, INTERACT_ACROSS_USERS_FULL permission, system UID or root UID is required. - enforceSystemUserOrPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userId)); } private boolean canUserUseLockTaskLocked(int userId) { @@ -8315,6 +8406,18 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID); } + private boolean isSystemUid(CallerIdentity identity) { + return UserHandle.isSameApp(identity.getUid(), Process.SYSTEM_UID); + } + + private boolean isRootUid(CallerIdentity identity) { + return UserHandle.isSameApp(identity.getUid(), Process.ROOT_UID); + } + + private boolean isShellUid(CallerIdentity identity) { + return UserHandle.isSameApp(identity.getUid(), Process.SHELL_UID); + } + protected int getProfileParentId(int userHandle) { return mInjector.binderWithCleanCallingIdentity(() -> { UserInfo parentUser = mUserManager.getProfileParent(userHandle); @@ -8569,7 +8672,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return null; } Objects.requireNonNull(agent, "agent null"); - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = admin != null + ? getCallerIdentity(admin) + : getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); synchronized (getLockObject()) { final String componentName = agent.flattenToString(); @@ -9922,10 +10030,14 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public String[] getAccountTypesWithManagementDisabledAsUser(int userId, boolean parent) { - enforceFullCrossUsersPermission(userId); if (!mHasFeature) { return null; } + Preconditions.checkArgumentNonnegative(userId, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userId)); + synchronized (getLockObject()) { final ArraySet<String> resultSet = new ArraySet<>(); @@ -10045,7 +10157,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean getCrossProfileCallerIdDisabledForUser(int userId) { - enforceCrossUsersPermission(userId); + Preconditions.checkArgumentNonnegative(userId, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasCrossUsersPermission(identity, userId)); + synchronized (getLockObject()) { ActiveAdmin admin = getProfileOwnerAdminLocked(userId); return (admin != null) ? admin.disableCallerId : false; @@ -10088,7 +10204,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public boolean getCrossProfileContactsSearchDisabledForUser(int userId) { - enforceCrossUsersPermission(userId); + Preconditions.checkArgumentNonnegative(userId, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasCrossUsersPermission(identity, userId)); + synchronized (getLockObject()) { ActiveAdmin admin = getProfileOwnerAdminLocked(userId); return (admin != null) ? admin.disableContactsSearch : false; @@ -12157,7 +12277,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return; } - enforceFullCrossUsersPermission(userId); + Preconditions.checkArgumentNonnegative(userId, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userId)); + enforceManageUsers(); enforceManagedProfile(userId, "set organization color"); synchronized (getLockObject()) { @@ -12186,7 +12310,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return ActiveAdmin.DEF_ORGANIZATION_COLOR; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + enforceManagedProfile(userHandle, "get organization color"); synchronized (getLockObject()) { ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userHandle); @@ -12246,7 +12374,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return null; } - enforceFullCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasFullCrossUsersPermission(identity, userHandle)); + enforceManagedProfile(userHandle, "get organization name"); synchronized (getLockObject()) { ActiveAdmin profileOwner = getProfileOwnerAdminLocked(userHandle); @@ -12337,12 +12469,6 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return false; } - private boolean hasMarkProfileOwnerOnOrganizationOwnedDevicePermission() { - return mContext.checkCallingPermission( - permission.MARK_DEVICE_ORGANIZATION_OWNED) - == PackageManager.PERMISSION_GRANTED; - } - @Override public void markProfileOwnerOnOrganizationOwnedDevice(ComponentName who, int userId) { // As the caller is the system, it must specify the component name of the profile owner @@ -12355,7 +12481,7 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { // Only adb or system apps with the right permission can mark a profile owner on // organization-owned device. - if (!(isAdb() || hasMarkProfileOwnerOnOrganizationOwnedDevicePermission())) { + if (!(isAdb() || hasCallingPermission(permission.MARK_DEVICE_ORGANIZATION_OWNED))) { throw new SecurityException( "Only the system can mark a profile owner of organization-owned device."); } @@ -13483,7 +13609,8 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { @Override public StringParceledListSlice getOwnerInstalledCaCerts(@NonNull UserHandle user) { final int userId = user.getIdentifier(); - enforceProfileOwnerOrFullCrossUsersPermission(userId); + final CallerIdentity identity = getCallerIdentity(); + enforceProfileOwnerOrFullCrossUsersPermission(identity, userId); synchronized (getLockObject()) { return new StringParceledListSlice( new ArrayList<>(getUserData(userId).mOwnerInstalledCaCerts)); @@ -14136,8 +14263,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { return false; } Preconditions.checkStringNotEmpty(packageName, "Package name is null or empty"); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasCrossUsersPermission(identity, userHandle)); - enforceCrossUsersPermission(userHandle); synchronized (getLockObject()) { if (mInjector.settingsSecureGetIntForUser( Settings.Secure.CROSS_PROFILE_CALENDAR_ENABLED, 0, userHandle) == 0) { @@ -14159,7 +14289,11 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return Collections.emptyList(); } - enforceCrossUsersPermission(userHandle); + Preconditions.checkArgumentNonnegative(userHandle, "Invalid userId"); + + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization(hasCrossUsersPermission(identity, userHandle)); + synchronized (getLockObject()) { final ActiveAdmin admin = getProfileOwnerAdminLocked(userHandle); if (admin != null) { @@ -14221,7 +14355,12 @@ public class DevicePolicyManagerService extends BaseIDevicePolicyManager { if (!mHasFeature) { return Collections.emptyList(); } - enforceAcrossUsersPermissions(); + final CallerIdentity identity = getCallerIdentity(); + Preconditions.checkCallAuthorization( + isSystemUid(identity) || isRootUid(identity) || hasCallingPermission( + permission.INTERACT_ACROSS_USERS) || hasCallingPermission( + permission.INTERACT_ACROSS_USERS_FULL) || hasPermissionForPreflight( + identity, permission.INTERACT_ACROSS_PROFILES)); synchronized (getLockObject()) { final List<ActiveAdmin> admins = getProfileOwnerAdminsForCurrentProfileGroup(); diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java index 32afe8244eb6..e6fc792c6a9d 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DevicePolicyManagerTest.java @@ -4465,6 +4465,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { final int MANAGED_PROFILE_ADMIN_UID = UserHandle.getUid(MANAGED_PROFILE_USER_ID, 19436); addManagedProfile(admin1, MANAGED_PROFILE_ADMIN_UID, admin1); mContext.binder.callingUid = MANAGED_PROFILE_ADMIN_UID; + mServiceContext.permissions.add(permission.INTERACT_ACROSS_USERS_FULL); // Even if the caller is the managed profile, the current user is the user 0 when(getServices().iactivityManager.getCurrentUser()) @@ -5694,6 +5695,7 @@ public class DevicePolicyManagerTest extends DpmTestBase { final long ident = mServiceContext.binder.clearCallingIdentity(); configureContextForAccess(mServiceContext, true); + mServiceContext.permissions.add(permission.MARK_DEVICE_ORGANIZATION_OWNED); mServiceContext.binder.callingUid = UserHandle.getUid(CALLER_USER_HANDLE, diff --git a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java index ce7ac9e796d2..09b6d7b0cd7e 100644 --- a/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java +++ b/services/tests/servicestests/src/com/android/server/devicepolicy/DpmMockContext.java @@ -259,18 +259,7 @@ public class DpmMockContext extends MockContext { @Override public int checkPermission(String permission, int pid, int uid) { - if (UserHandle.isSameApp(binder.getCallingUid(), SYSTEM_UID)) { - return PackageManager.PERMISSION_GRANTED; // Assume system has all permissions. - } - List<String> permissions = binder.callingPermissions.get(binder.getCallingUid()); - if (permissions == null) { - permissions = callerPermissions; - } - if (permissions.contains(permission)) { - return PackageManager.PERMISSION_GRANTED; - } else { - return PackageManager.PERMISSION_DENIED; - } + return checkPermission(permission); } @Override @@ -480,11 +469,32 @@ public class DpmMockContext extends MockContext { @Override public int checkCallingPermission(String permission) { - return spiedContext.checkCallingPermission(permission); + return checkPermission(permission); + } + + @Override + public int checkCallingOrSelfPermission(String permission) { + return checkPermission(permission); } @Override public void startActivityAsUser(Intent intent, UserHandle userHandle) { spiedContext.startActivityAsUser(intent, userHandle); } + + private int checkPermission(String permission) { + if (UserHandle.isSameApp(binder.getCallingUid(), SYSTEM_UID)) { + return PackageManager.PERMISSION_GRANTED; // Assume system has all permissions. + } + List<String> permissions = binder.callingPermissions.get(binder.getCallingUid()); + if (permissions == null) { + permissions = callerPermissions; + } + if (permissions.contains(permission)) { + return PackageManager.PERMISSION_GRANTED; + } else { + return PackageManager.PERMISSION_DENIED; + } + } + } |