diff options
7 files changed, 59 insertions, 161 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index 7fe567b5ce27..9cf0d2a3a36a 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -52,23 +52,14 @@ public abstract class ActivityManagerInternal { * if in the same profile group. * Otherwise, {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} is required. */ - public static final int ALLOW_NON_FULL_IN_PROFILE_OR_FULL = 1; + public static final int ALLOW_NON_FULL_IN_PROFILE = 1; public static final int ALLOW_FULL_ONLY = 2; /** * Allows access to a caller with {@link android.Manifest.permission#INTERACT_ACROSS_PROFILES} * or {@link android.Manifest.permission#INTERACT_ACROSS_USERS} if in the same profile group. * Otherwise, {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} is required. */ - public static final int ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_FULL = 3; - /** - * Requires {@link android.Manifest.permission#INTERACT_ACROSS_PROFILES}, - * {@link android.Manifest.permission#INTERACT_ACROSS_USERS}, or - * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} if in same profile group, - * otherwise {@link android.Manifest.permission#INTERACT_ACROSS_USERS} or - * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL}. (so this is an extension - * to {@link #ALLOW_NON_FULL}) - */ - public static final int ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_NON_FULL = 4; + public static final int ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE = 3; /** * Verify that calling app has access to the given provider. diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 1680963e26d1..33a92e6ad0ac 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -2559,12 +2559,12 @@ public final class ActiveServices { private int getAllowMode(Intent service, @Nullable String callingPackage) { if (callingPackage == null || service.getComponent() == null) { - return ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE_OR_FULL; + return ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE; } if (callingPackage.equals(service.getComponent().getPackageName())) { - return ActivityManagerInternal.ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_FULL; + return ActivityManagerInternal.ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE; } else { - return ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE_OR_FULL; + return ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE; } } diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 19b671e46b71..0658e8139cc2 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -23,11 +23,10 @@ import static android.app.ActivityManager.USER_OP_ERROR_IS_SYSTEM; import static android.app.ActivityManager.USER_OP_ERROR_RELATED_USERS_CANNOT_STOP; import static android.app.ActivityManager.USER_OP_IS_CURRENT; import static android.app.ActivityManager.USER_OP_SUCCESS; -import static android.app.ActivityManagerInternal.ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_NON_FULL; -import static android.app.ActivityManagerInternal.ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_FULL; +import static android.app.ActivityManagerInternal.ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE; import static android.app.ActivityManagerInternal.ALLOW_FULL_ONLY; import static android.app.ActivityManagerInternal.ALLOW_NON_FULL; -import static android.app.ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE_OR_FULL; +import static android.app.ActivityManagerInternal.ALLOW_NON_FULL_IN_PROFILE; import static android.os.Process.SHELL_UID; import static android.os.Process.SYSTEM_UID; @@ -1910,12 +1909,11 @@ class UserController implements Handler.Callback { callingUid, -1, true) != PackageManager.PERMISSION_GRANTED) { // If the caller does not have either permission, they are always doomed. allow = false; - } else if (allowMode == ALLOW_NON_FULL - || allowMode == ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_NON_FULL) { + } else if (allowMode == ALLOW_NON_FULL) { // We are blanket allowing non-full access, you lucky caller! allow = true; - } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE_OR_FULL - || allowMode == ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_FULL) { + } else if (allowMode == ALLOW_NON_FULL_IN_PROFILE + || allowMode == ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE) { // We may or may not allow this depending on whether the two users are // in the same profile. allow = isSameProfileGroup; @@ -1942,15 +1940,12 @@ class UserController implements Handler.Callback { builder.append("; this requires "); builder.append(INTERACT_ACROSS_USERS_FULL); if (allowMode != ALLOW_FULL_ONLY) { - if (allowMode == ALLOW_NON_FULL - || allowMode == ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_NON_FULL - || isSameProfileGroup) { + if (allowMode == ALLOW_NON_FULL || isSameProfileGroup) { builder.append(" or "); builder.append(INTERACT_ACROSS_USERS); } if (isSameProfileGroup - && (allowMode == ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_FULL - || allowMode == ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_NON_FULL)) { + && allowMode == ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE) { builder.append(" or "); builder.append(INTERACT_ACROSS_PROFILES); } @@ -1977,8 +1972,7 @@ class UserController implements Handler.Callback { private boolean canInteractWithAcrossProfilesPermission( int allowMode, boolean isSameProfileGroup, int callingPid, int callingUid, String callingPackage) { - if (allowMode != ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_FULL - && allowMode != ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_NON_FULL) { + if (allowMode != ALLOW_ALL_PROFILE_PERMISSIONS_IN_PROFILE) { return false; } if (!isSameProfileGroup) { diff --git a/services/core/java/com/android/server/appop/AppOpsService.java b/services/core/java/com/android/server/appop/AppOpsService.java index 74f3daf50079..e6480fc6cde8 100644 --- a/services/core/java/com/android/server/appop/AppOpsService.java +++ b/services/core/java/com/android/server/appop/AppOpsService.java @@ -19,7 +19,6 @@ package com.android.server.appop; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_CAMERA; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_LOCATION; import static android.app.ActivityManager.PROCESS_CAPABILITY_FOREGROUND_MICROPHONE; -import static android.app.ActivityManagerInternal.ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_NON_FULL; import static android.app.AppOpsManager.CALL_BACK_ON_SWITCHED_OP; import static android.app.AppOpsManager.FILTER_BY_ATTRIBUTION_TAG; import static android.app.AppOpsManager.FILTER_BY_OP_NAMES; @@ -129,7 +128,6 @@ import android.provider.Settings; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; -import android.util.EventLog; import android.util.KeyValueListParser; import android.util.LongSparseArray; import android.util.Pair; @@ -163,7 +161,6 @@ import com.android.server.LocalServices; import com.android.server.LockGuard; import com.android.server.SystemServerInitThreadPool; import com.android.server.SystemServiceManager; -import com.android.server.am.ActivityManagerService; import com.android.server.pm.PackageList; import com.android.server.pm.parsing.pkg.AndroidPackage; @@ -2200,11 +2197,8 @@ public class AppOpsService extends IAppOpsService.Stub { + " by uid " + Binder.getCallingUid()); } - int userId = UserHandle.getUserId(uid); - enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid); verifyIncomingOp(code); - verifyIncomingUser(userId); code = AppOpsManager.opToSwitch(code); if (permissionPolicyCallback == null) { @@ -2449,12 +2443,8 @@ public class AppOpsService extends IAppOpsService.Stub { private void setMode(int code, int uid, @NonNull String packageName, int mode, @Nullable IAppOpsCallback permissionPolicyCallback) { enforceManageAppOpsModes(Binder.getCallingPid(), Binder.getCallingUid(), uid); - - int userId = UserHandle.getUserId(uid); - verifyIncomingOp(code); - verifyIncomingUser(userId); - verifyIncomingPackage(packageName, userId); + verifyIncomingPackage(packageName, UserHandle.getUserId(uid)); ArraySet<ModeCallback> repCbs = null; code = AppOpsManager.opToSwitch(code); @@ -2867,11 +2857,8 @@ public class AppOpsService extends IAppOpsService.Stub { private int checkOperationImpl(int code, int uid, String packageName, boolean raw) { - int userId = UserHandle.getUserId(uid); - verifyIncomingOp(code); - verifyIncomingUser(userId); - verifyIncomingPackage(packageName, userId); + verifyIncomingPackage(packageName, UserHandle.getUserId(uid)); String resolvedPackageName = resolvePackageName(uid, packageName); if (resolvedPackageName == null) { @@ -2990,15 +2977,10 @@ public class AppOpsService extends IAppOpsService.Stub { String proxiedAttributionTag, int proxyUid, String proxyPackageName, String proxyAttributionTag, boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage) { - int proxiedUserId = UserHandle.getUserId(proxiedUid); - int proxyUserId = UserHandle.getUserId(proxyUid); - verifyIncomingUid(proxyUid); verifyIncomingOp(code); - verifyIncomingUser(proxiedUserId); - verifyIncomingUser(proxyUserId); - verifyIncomingPackage(proxiedPackageName, proxiedUserId); - verifyIncomingPackage(proxyPackageName, proxyUserId); + verifyIncomingPackage(proxiedPackageName, UserHandle.getUserId(proxiedUid)); + verifyIncomingPackage(proxyPackageName, UserHandle.getUserId(proxyUid)); String resolveProxyPackageName = resolvePackageName(proxyUid, proxyPackageName); if (resolveProxyPackageName == null) { @@ -3048,12 +3030,9 @@ public class AppOpsService extends IAppOpsService.Stub { private int noteOperationImpl(int code, int uid, @Nullable String packageName, @Nullable String attributionTag, boolean shouldCollectAsyncNotedOp, @Nullable String message, boolean shouldCollectMessage) { - int userId = UserHandle.getUserId(uid); - verifyIncomingUid(uid); verifyIncomingOp(code); - verifyIncomingUser(userId); - verifyIncomingPackage(packageName, userId); + verifyIncomingPackage(packageName, UserHandle.getUserId(uid)); String resolvedPackageName = resolvePackageName(uid, packageName); if (resolvedPackageName == null) { @@ -3430,12 +3409,9 @@ public class AppOpsService extends IAppOpsService.Stub { public int startOperation(IBinder clientId, int code, int uid, String packageName, String attributionTag, boolean startIfModeDefault, boolean shouldCollectAsyncNotedOp, String message, boolean shouldCollectMessage) { - int userId = UserHandle.getUserId(uid); - verifyIncomingUid(uid); verifyIncomingOp(code); - verifyIncomingUser(userId); - verifyIncomingPackage(packageName, userId); + verifyIncomingPackage(packageName, UserHandle.getUserId(uid)); String resolvedPackageName = resolvePackageName(uid, packageName); if (resolvedPackageName == null) { @@ -3515,12 +3491,9 @@ public class AppOpsService extends IAppOpsService.Stub { @Override public void finishOperation(IBinder clientId, int code, int uid, String packageName, String attributionTag) { - int userId = UserHandle.getUserId(uid); - verifyIncomingUid(uid); verifyIncomingOp(code); - verifyIncomingUser(userId); - verifyIncomingPackage(packageName, userId); + verifyIncomingPackage(packageName, UserHandle.getUserId(uid)); String resolvedPackageName = resolvePackageName(uid, packageName); if (resolvedPackageName == null) { @@ -3749,33 +3722,6 @@ public class AppOpsService extends IAppOpsService.Stub { } } - private void verifyIncomingUser(@UserIdInt int userId) { - int callingUid = Binder.getCallingUid(); - int callingUserId = UserHandle.getUserId(callingUid); - int callingPid = Binder.getCallingPid(); - - if (callingUserId != userId) { - // Prevent endless loop between when checking appops inside of handleIncomingUser - if (Binder.getCallingPid() == ActivityManagerService.MY_PID) { - return; - } - long token = Binder.clearCallingIdentity(); - try { - try { - LocalServices.getService(ActivityManagerInternal.class).handleIncomingUser( - callingPid, callingUid, userId, /* allowAll */ false, - ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_NON_FULL, "appop operation", null); - } catch (Exception e) { - EventLog.writeEvent(0x534e4554, "153996875", "appop", userId); - - throw e; - } - } finally { - Binder.restoreCallingIdentity(token); - } - } - } - private @Nullable UidState getUidStateLocked(int uid, boolean edit) { UidState uidState = mUidStates.get(uid); if (uidState == null) { @@ -5855,11 +5801,8 @@ public class AppOpsService extends IAppOpsService.Stub { return false; } } - int userId = UserHandle.getUserId(uid); - verifyIncomingOp(code); - verifyIncomingUser(userId); - verifyIncomingPackage(packageName, userId); + verifyIncomingPackage(packageName, UserHandle.getUserId(uid)); final String resolvedPackageName = resolvePackageName(uid, packageName); if (resolvedPackageName == null) { diff --git a/services/core/java/com/android/server/appop/TEST_MAPPING b/services/core/java/com/android/server/appop/TEST_MAPPING index a3e1b7a7e5c5..84de25c06ebf 100644 --- a/services/core/java/com/android/server/appop/TEST_MAPPING +++ b/services/core/java/com/android/server/appop/TEST_MAPPING @@ -7,9 +7,6 @@ "name": "CtsAppOps2TestCases" }, { - "name": "CtsAppOpHostTestCases" - }, - { "name": "FrameworksServicesTests", "options": [ { diff --git a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java index 6e0efb09aff3..be93b8f95b79 100644 --- a/services/core/java/com/android/server/pm/permission/PermissionManagerService.java +++ b/services/core/java/com/android/server/pm/permission/PermissionManagerService.java @@ -137,7 +137,6 @@ import com.android.server.LocalServices; import com.android.server.ServiceThread; import com.android.server.SystemConfig; import com.android.server.Watchdog; -import com.android.server.am.ActivityManagerService; import com.android.server.pm.ApexManager; import com.android.server.pm.PackageManagerServiceUtils; import com.android.server.pm.PackageSetting; @@ -922,16 +921,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { } final int uid = UserHandle.getUid(userId, pkg.getUid()); - - try { - enforceCrossUserOrProfilePermission(Binder.getCallingUid(), UserHandle.getUserId(uid), - false, false, "checkPermissionInternal"); - } catch (Exception e) { - EventLog.writeEvent(0x534e4554, "153996875", "checkPermission", uid); - - throw e; - } - final PackageSetting ps = (PackageSetting) mPackageManagerInt.getPackageSetting( pkg.getPackageName()); if (ps == null) { @@ -4399,7 +4388,7 @@ public class PermissionManagerService extends IPermissionManager.Stub { } final int callingUserId = UserHandle.getUserId(callingUid); if (hasCrossUserPermission( - Binder.getCallingPid(), callingUid, callingUserId, userId, requireFullPermission, + callingUid, callingUserId, userId, requireFullPermission, requirePermissionWhenSameUser)) { return; } @@ -4426,54 +4415,37 @@ public class PermissionManagerService extends IPermissionManager.Stub { private void enforceCrossUserOrProfilePermission(int callingUid, int userId, boolean requireFullPermission, boolean checkShell, String message) { - int callingPid = Binder.getCallingPid(); - final int callingUserId = UserHandle.getUserId(callingUid); - if (userId < 0) { throw new IllegalArgumentException("Invalid userId " + userId); } - - if (callingUserId == userId) { - return; + if (checkShell) { + PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt, + UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); } - - // Prevent endless loop between when checking permission while checking a permission - if (callingPid == ActivityManagerService.MY_PID) { + final int callingUserId = UserHandle.getUserId(callingUid); + if (hasCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission, + /*requirePermissionWhenSameUser= */ false)) { return; } - - long token = Binder.clearCallingIdentity(); - try { - if (checkShell) { - PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt, - UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); - } - if (hasCrossUserPermission(callingPid, callingUid, callingUserId, userId, - requireFullPermission, /*requirePermissionWhenSameUser= */ false)) { - return; - } - final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, userId); - if (isSameProfileGroup && PermissionChecker.checkPermissionForPreflight( - mContext, - android.Manifest.permission.INTERACT_ACROSS_PROFILES, - PermissionChecker.PID_UNKNOWN, - callingUid, - mPackageManagerInt.getPackage(callingUid).getPackageName()) - == PermissionChecker.PERMISSION_GRANTED) { - return; - } - - String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage( - message, requireFullPermission, isSameProfileGroup); - Slog.w(TAG, errorMessage); - throw new SecurityException(errorMessage); - } finally { - Binder.restoreCallingIdentity(token); + final boolean isSameProfileGroup = isSameProfileGroup(callingUserId, userId); + if (isSameProfileGroup && PermissionChecker.checkPermissionForPreflight( + mContext, + android.Manifest.permission.INTERACT_ACROSS_PROFILES, + PermissionChecker.PID_UNKNOWN, + callingUid, + mPackageManagerInt.getPackage(callingUid).getPackageName()) + == PermissionChecker.PERMISSION_GRANTED) { + return; } + String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage( + message, requireFullPermission, isSameProfileGroup); + Slog.w(TAG, errorMessage); + throw new SecurityException(errorMessage); } - private boolean hasCrossUserPermission(int callingPid, int callingUid, int callingUserId, - int userId, boolean requireFullPermission, boolean requirePermissionWhenSameUser) { + private boolean hasCrossUserPermission( + int callingUid, int callingUserId, int userId, boolean requireFullPermission, + boolean requirePermissionWhenSameUser) { if (!requirePermissionWhenSameUser && userId == callingUserId) { return true; } @@ -4481,11 +4453,15 @@ public class PermissionManagerService extends IPermissionManager.Stub { return true; } if (requireFullPermission) { - return mContext.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, - callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; + return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL); } - return mContext.checkPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, - callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; + return hasPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) + || hasPermission(Manifest.permission.INTERACT_ACROSS_USERS); + } + + private boolean hasPermission(String permission) { + return mContext.checkCallingOrSelfPermission(permission) + == PackageManager.PERMISSION_GRANTED; } private boolean isSameProfileGroup(@UserIdInt int callerUserId, @UserIdInt int userId) { diff --git a/services/core/java/com/android/server/pm/permission/TEST_MAPPING b/services/core/java/com/android/server/pm/permission/TEST_MAPPING index 65dc320eadc2..c0d71ac26853 100644 --- a/services/core/java/com/android/server/pm/permission/TEST_MAPPING +++ b/services/core/java/com/android/server/pm/permission/TEST_MAPPING @@ -18,24 +18,21 @@ ] }, { - "name": "CtsPermission2TestCases", + "name": "CtsAppSecurityHostTestCases", "options": [ { - "include-filter": "android.permission2.cts.RestrictedPermissionsTest" - }, - { - "include-filter": "android.permission.cts.PermissionMaxSdkVersionTest" + "include-filter": "android.appsecurity.cts.AppSecurityTests#rebootWithDuplicatePermission" } ] }, { - "name": "CtsPermissionHostTestCases" - }, - { - "name": "CtsAppSecurityHostTestCases", + "name": "CtsPermission2TestCases", "options": [ { - "include-filter": "android.appsecurity.cts.AppSecurityTests#rebootWithDuplicatePermission" + "include-filter": "android.permission2.cts.RestrictedPermissionsTest" + }, + { + "include-filter": "android.permission.cts.PermissionMaxSdkVersionTest" } ] }, |