diff options
author | Robin Lee <rgl@google.com> | 2014-03-28 17:37:31 +0000 |
---|---|---|
committer | Android Git Automerger <android-git-automerger@android.com> | 2014-03-28 17:37:31 +0000 |
commit | 9869f2fcf54397fc48ac4e41d8e3f707cba4299b (patch) | |
tree | 080d9845a49417bca571e85f97c0ded6b3415d06 | |
parent | ad295d14c52b4949d749415ac8cb36ee6eda77b9 (diff) | |
parent | 0756e4e42e36e649c858eca1f6c6c05d3422a8c8 (diff) | |
download | frameworks_base-9869f2fcf54397fc48ac4e41d8e3f707cba4299b.zip frameworks_base-9869f2fcf54397fc48ac4e41d8e3f707cba4299b.tar.gz frameworks_base-9869f2fcf54397fc48ac4e41d8e3f707cba4299b.tar.bz2 |
am 0756e4e4: Merge "Fix privilege escalation for preferred activities"
* commit '0756e4e42e36e649c858eca1f6c6c05d3422a8c8':
Fix privilege escalation for preferred activities
-rw-r--r-- | core/java/android/app/admin/DeviceAdminInfo.java | 16 | ||||
-rw-r--r-- | services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java | 128 |
2 files changed, 81 insertions, 63 deletions
diff --git a/core/java/android/app/admin/DeviceAdminInfo.java b/core/java/android/app/admin/DeviceAdminInfo.java index 66fc816..3074b49 100644 --- a/core/java/android/app/admin/DeviceAdminInfo.java +++ b/core/java/android/app/admin/DeviceAdminInfo.java @@ -52,6 +52,22 @@ public final class DeviceAdminInfo implements Parcelable { static final String TAG = "DeviceAdminInfo"; /** + * A type of policy that this device admin can use: device owner meta-policy + * for an admin that is designated as owner of the device. + * + * @hide + */ + public static final int USES_POLICY_DEVICE_OWNER = -2; + + /** + * A type of policy that this device admin can use: profile owner meta-policy + * for admins that have been installed as owner of some user profile. + * + * @hide + */ + public static final int USES_POLICY_PROFILE_OWNER = -1; + + /** * A type of policy that this device admin can use: limit the passwords * that the user can select, via {@link DevicePolicyManager#setPasswordQuality} * and {@link DevicePolicyManager#setPasswordMinimumLength}. diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index f186b2c..983ca2d 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -170,7 +170,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { int mActivePasswordNonLetter = 0; int mFailedPasswordAttempts = 0; - int mUserHandle;; + int mUserHandle; int mPasswordOwner = -1; long mLastMaximumTimeToLock = -1; @@ -722,6 +722,10 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { final int callingUid = Binder.getCallingUid(); final int userHandle = UserHandle.getUserId(callingUid); final DevicePolicyData policy = getUserData(userHandle); + + List<ActiveAdmin> candidates = new ArrayList<ActiveAdmin>(); + + // Build a list of admins for this uid matching the given ComponentName if (who != null) { ActiveAdmin admin = policy.mAdminMap.get(who); if (admin == null) { @@ -731,22 +735,43 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { throw new SecurityException("Admin " + who + " is not owned by uid " + Binder.getCallingUid()); } - if (!admin.info.usesPolicy(reqPolicy)) { - throw new SecurityException("Admin " + admin.info.getComponent() - + " did not specify uses-policy for: " - + admin.info.getTagForPolicy(reqPolicy)); - } - return admin; + candidates.add(admin); } else { - final int N = policy.mAdminList.size(); - for (int i=0; i<N; i++) { - ActiveAdmin admin = policy.mAdminList.get(i); - if (admin.getUid() == callingUid && admin.info.usesPolicy(reqPolicy)) { + for (ActiveAdmin admin : policy.mAdminList) { + if (admin.getUid() == callingUid) { + candidates.add(admin); + } + } + } + + // Try to find an admin which can use reqPolicy + for (ActiveAdmin admin : candidates) { + boolean ownsDevice = isDeviceOwner(admin.info.getPackageName()); + boolean ownsProfile = (getProfileOwner(userHandle) != null + && getProfileOwner(userHandle).equals(admin.info.getPackageName())); + + if (reqPolicy == DeviceAdminInfo.USES_POLICY_DEVICE_OWNER) { + if (ownsDevice) { + return admin; + } + } else if (reqPolicy == DeviceAdminInfo.USES_POLICY_PROFILE_OWNER) { + if (ownsDevice || ownsProfile) { + return admin; + } + } else { + if (admin.info.usesPolicy(reqPolicy)) { return admin; } } + } + + if (who != null) { + throw new SecurityException("Admin " + candidates.get(0).info.getComponent() + + " did not specify uses-policy for: " + + candidates.get(0).info.getTagForPolicy(reqPolicy)); + } else { throw new SecurityException("No active admin owned by uid " - + Binder.getCallingUid() + " for policy #" + reqPolicy); + + Binder.getCallingUid() + " for policy:" + reqPolicy); } } @@ -2966,64 +2991,41 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } } - private boolean isProfileOwner(String packageName, int userId) { - String profileOwnerPackage = getProfileOwner(userId); - // TODO: make public and connect with isProfileOwnerApp in DPM - return profileOwnerPackage != null && profileOwnerPackage.equals(packageName); - } - - public void addPersistentPreferredActivity(ComponentName admin, IntentFilter filter, + public void addPersistentPreferredActivity(ComponentName who, IntentFilter filter, ComponentName activity) { - int callingUserId = UserHandle.getCallingUserId(); - Slog.d(LOG_TAG,"called by user " + callingUserId); synchronized (this) { - ActiveAdmin aa = getActiveAdminUncheckedLocked(admin, callingUserId); - if (aa == null) { - throw new SecurityException("No active admin " + admin); - } else { - if (isProfileOwner(admin.getPackageName(), callingUserId) - || isDeviceOwner(admin.getPackageName())) { - IPackageManager pm = AppGlobals.getPackageManager(); - long id = Binder.clearCallingIdentity(); - try { - pm.addPersistentPreferredActivity(filter, activity, callingUserId); - } catch (RemoteException re) { - // Shouldn't happen - } finally { - restoreCallingIdentity(id); - } - } else { - throw new SecurityException("Admin " + admin + - "is not device owner or profile owner" ); - } + if (who == null) { + throw new NullPointerException("ComponentName is null"); + } + getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + + IPackageManager pm = AppGlobals.getPackageManager(); + long id = Binder.clearCallingIdentity(); + try { + pm.addPersistentPreferredActivity(filter, activity, UserHandle.getCallingUserId()); + } catch (RemoteException re) { + // Shouldn't happen + } finally { + restoreCallingIdentity(id); } } } - public void clearPackagePersistentPreferredActivities(ComponentName admin, - String packageName) { - int callingUserId = UserHandle.getCallingUserId(); - Slog.d(LOG_TAG,"called by user " + callingUserId); + public void clearPackagePersistentPreferredActivities(ComponentName who, String packageName) { synchronized (this) { - ActiveAdmin aa = getActiveAdminUncheckedLocked(admin, callingUserId); - if (aa == null) { - throw new SecurityException("No active admin " + admin); - } else { - if (isProfileOwner(admin.getPackageName(), callingUserId) - || isDeviceOwner(admin.getPackageName())) { - IPackageManager pm = AppGlobals.getPackageManager(); - long id = Binder.clearCallingIdentity(); - try{ - pm.clearPackagePersistentPreferredActivities(packageName, callingUserId); - } catch (RemoteException re) { - // Shouldn't happen - } finally { - restoreCallingIdentity(id); - } - } else { - throw new SecurityException("Admin " + admin + - "is not device owner or profile owner" ); - } + if (who == null) { + throw new NullPointerException("ComponentName is null"); + } + getActiveAdminForCallerLocked(who, DeviceAdminInfo.USES_POLICY_PROFILE_OWNER); + + IPackageManager pm = AppGlobals.getPackageManager(); + long id = Binder.clearCallingIdentity(); + try { + pm.clearPackagePersistentPreferredActivities(packageName, UserHandle.getCallingUserId()); + } catch (RemoteException re) { + // Shouldn't happen + } finally { + restoreCallingIdentity(id); } } } |