From a0116afeaf9363c5a662624dda77b550aa9172a8 Mon Sep 17 00:00:00 2001 From: Amith Yamasani Date: Thu, 4 Dec 2014 14:49:24 -0800 Subject: [PATCH] Potential fix for accidental deactivation of profile owner This is a safeguard to only check for changing packages when re-validating active admins. 1. If package is being removed, only check if it's not being replaced. 2. If package is changing, only check the changing package that matches one of the active admins. 3. If package is being added and is a replacement (update), then check if it affects any matching active admins and verify the validity of the receivers. If by any chance some package broadcast was occuring at a time when an admin was being updated, or the package removed broadcast was coming in much before the update was registered with package manager then this will help in avoiding accidental deactivation. Bug: 18590558 Change-Id: I7f4897e8836f81aa037b8be87d399942ce78b1a2 --- .../DevicePolicyManagerService.java | 30 ++++++++++++------- 1 file changed, 20 insertions(+), 10 deletions(-) diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index 2201d2b7c306a..cd3c65c0ec229 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -303,8 +303,6 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { if (Intent.ACTION_USER_REMOVED.equals(action)) { removeUserData(userHandle); } else if (Intent.ACTION_USER_STARTED.equals(action) - || Intent.ACTION_PACKAGE_CHANGED.equals(action) - || Intent.ACTION_PACKAGE_REMOVED.equals(action) || Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE.equals(action)) { if (Intent.ACTION_USER_STARTED.equals(action)) { @@ -313,8 +311,14 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mUserData.remove(userHandle); } } - - handlePackagesChanged(userHandle); + handlePackagesChanged(null /* check all admins */, userHandle); + } else if (Intent.ACTION_PACKAGE_CHANGED.equals(action) + || (Intent.ACTION_PACKAGE_ADDED.equals(action) + && intent.getBooleanExtra(Intent.EXTRA_REPLACING, false))) { + handlePackagesChanged(intent.getData().getSchemeSpecificPart(), userHandle); + } else if (Intent.ACTION_PACKAGE_REMOVED.equals(action) + && !intent.getBooleanExtra(Intent.EXTRA_REPLACING, false)) { + handlePackagesChanged(intent.getData().getSchemeSpecificPart(), userHandle); } } }; @@ -899,7 +903,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } - private void handlePackagesChanged(int userHandle) { + private void handlePackagesChanged(String packageName, int userHandle) { boolean removed = false; if (DBG) Slog.d(LOG_TAG, "Handling package changes for user " + userHandle); DevicePolicyData policy = getUserData(userHandle); @@ -908,11 +912,17 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { for (int i = policy.mAdminList.size() - 1; i >= 0; i--) { ActiveAdmin aa = policy.mAdminList.get(i); try { - if (pm.getPackageInfo(aa.info.getPackageName(), 0, userHandle) == null - || pm.getReceiverInfo(aa.info.getComponent(), 0, userHandle) == null) { - removed = true; - policy.mAdminList.remove(i); - policy.mAdminMap.remove(aa.info.getComponent()); + // If we're checking all packages or if the specific one we're checking matches, + // then check if the package and receiver still exist. + final String adminPackage = aa.info.getPackageName(); + if (packageName == null || packageName.equals(adminPackage)) { + if (pm.getPackageInfo(adminPackage, 0, userHandle) == null + || pm.getReceiverInfo(aa.info.getComponent(), 0, userHandle) + == null) { + removed = true; + policy.mAdminList.remove(i); + policy.mAdminMap.remove(aa.info.getComponent()); + } } } catch (RemoteException re) { // Shouldn't happen