diff --git a/core/java/android/os/UserManager.java b/core/java/android/os/UserManager.java index 1f16c4a4cdedf..c5adafe9d16db 100644 --- a/core/java/android/os/UserManager.java +++ b/core/java/android/os/UserManager.java @@ -1631,12 +1631,23 @@ public class UserManager { } /** - * Returns a Bundle containing any saved application restrictions for this user, for the + * Returns a {@code Bundle} containing any saved application restrictions for this user, for the * given package name. Only an application with this package name can call this method. + * + *

The returned {@link Bundle} consists of key-value pairs, as defined by the application, + * where the types of values may be: + *

+ * * @param packageName the package name of the calling application - * @return a Bundle with the restrictions as key/value pairs, or null if there are no - * saved restrictions. The values can be of type Boolean, String or String[], depending - * on the restriction type, as defined by the application. + * @return a {@code Bundle} with the restrictions for that package, or {@code null} if there + * are no saved restrictions. + * + * @see #KEY_RESTRICTIONS_PENDING */ public Bundle getApplicationRestrictions(String packageName) { try { diff --git a/services/core/java/com/android/server/pm/UserManagerService.java b/services/core/java/com/android/server/pm/UserManagerService.java index 0b59c16b5839f..f5da1032c718d 100644 --- a/services/core/java/com/android/server/pm/UserManagerService.java +++ b/services/core/java/com/android/server/pm/UserManagerService.java @@ -1123,7 +1123,7 @@ public class UserManagerService extends IUserManager.Stub { */ private static final void checkManageUsersPermission(String message) { final int uid = Binder.getCallingUid(); - if (uid != Process.SYSTEM_UID && uid != 0 + if (!UserHandle.isSameApp(uid, Process.SYSTEM_UID) && uid != Process.ROOT_UID && ActivityManager.checkComponentPermission( android.Manifest.permission.MANAGE_USERS, uid, -1, true) != PackageManager.PERMISSION_GRANTED) { @@ -1131,6 +1131,20 @@ public class UserManagerService extends IUserManager.Stub { } } + /** + * Enforces that only the system UID or root's UID (on any user) can make certain calls to the + * UserManager. + * + * @param message used as message if SecurityException is thrown + * @throws SecurityException if the caller is not system or root + */ + private static void checkSystemOrRoot(String message) { + final int uid = Binder.getCallingUid(); + if (!UserHandle.isSameApp(uid, Process.SYSTEM_UID) && uid != Process.ROOT_UID) { + throw new SecurityException("Only system may: " + message); + } + } + private void writeBitmapLP(UserInfo info, Bitmap bitmap) { try { File dir = new File(mUsersDir, Integer.toString(info.id)); @@ -2071,7 +2085,7 @@ public class UserManagerService extends IUserManager.Stub { public Bundle getApplicationRestrictionsForUser(String packageName, int userId) { if (UserHandle.getCallingUserId() != userId || !UserHandle.isSameApp(Binder.getCallingUid(), getUidForPackage(packageName))) { - checkManageUsersPermission("get application restrictions for other users/apps"); + checkSystemOrRoot("get application restrictions for other users/apps"); } synchronized (mPackagesLock) { // Read the restrictions from XML @@ -2082,7 +2096,7 @@ public class UserManagerService extends IUserManager.Stub { @Override public void setApplicationRestrictions(String packageName, Bundle restrictions, int userId) { - checkManageUsersPermission("set application restrictions"); + checkSystemOrRoot("set application restrictions"); synchronized (mPackagesLock) { if (restrictions == null || restrictions.isEmpty()) { cleanAppRestrictionsForPackage(packageName, userId); diff --git a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java index c540e052d4998..bdaf0aba5981b 100644 --- a/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java +++ b/services/devicepolicy/java/com/android/server/devicepolicy/DevicePolicyManagerService.java @@ -3681,7 +3681,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { public void choosePrivateKeyAlias(final int uid, final Uri uri, final String alias, final IBinder response) { // Caller UID needs to be trusted, so we restrict this method to SYSTEM_UID callers. - if (UserHandle.getAppId(mInjector.binderGetCallingUid()) != Process.SYSTEM_UID) { + if (!UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID)) { return; } @@ -4991,7 +4991,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.MANAGE_PROFILE_AND_DEVICE_OWNERS, null); if (hasUserSetupCompleted(userHandle) - && UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) { + && !UserHandle.isSameApp(callingUid, Process.SYSTEM_UID)) { throw new IllegalStateException("Cannot set the profile owner on a user which is " + "already set-up"); } @@ -5051,7 +5051,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { private void enforceManageUsers() { final int callingUid = mInjector.binderGetCallingUid(); - if (!(UserHandle.isSameApp(callingUid, Process.SYSTEM_UID) || callingUid == 0)) { + if (!(UserHandle.isSameApp(callingUid, Process.SYSTEM_UID) + || callingUid == Process.ROOT_UID)) { mContext.enforceCallingOrSelfPermission(android.Manifest.permission.MANAGE_USERS, null); } } @@ -5062,7 +5063,8 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { } final int callingUid = mInjector.binderGetCallingUid(); if (userHandle == UserHandle.getUserId(callingUid)) return; - if (!(UserHandle.isSameApp(callingUid, Process.SYSTEM_UID) || callingUid == 0)) { + if (!(UserHandle.isSameApp(callingUid, Process.SYSTEM_UID) + || callingUid == Process.ROOT_UID)) { mContext.enforceCallingOrSelfPermission( android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, "Must be system or have" + " INTERACT_ACROSS_USERS_FULL permission"); @@ -5292,7 +5294,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public ComponentName getRestrictionsProvider(int userHandle) { synchronized (this) { - if (mInjector.binderGetCallingUid() != Process.SYSTEM_UID) { + if (!UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID)) { throw new SecurityException("Only the system can query the permission provider"); } DevicePolicyData userData = getUserData(userHandle); @@ -6303,7 +6305,7 @@ public class DevicePolicyManagerService extends IDevicePolicyManager.Stub { @Override public void notifyLockTaskModeChanged(boolean isEnabled, String pkg, int userHandle) { - if (mInjector.binderGetCallingUid() != Process.SYSTEM_UID) { + if (!UserHandle.isSameApp(mInjector.binderGetCallingUid(), Process.SYSTEM_UID)) { throw new SecurityException("notifyLockTaskModeChanged can only be called by system"); } synchronized (this) {