diff options
| author | 2020-09-22 15:20:22 +0000 | |
|---|---|---|
| committer | 2020-09-22 15:20:22 +0000 | |
| commit | faeec12c7da59ba2d0d401306dd0251fcceee7a9 (patch) | |
| tree | bb1d400e498efa174b4fb7b5ad64c9823b14de2d | |
| parent | 75c2711f81a60147b296a0f61d5bd32b36e05332 (diff) | |
| parent | aba996799d228e60b4eda277730931c87094a3e0 (diff) | |
Merge changes from topic "revert-12439864-PermAppOpsCrossUserCheck-Fixed-DGFFMARPXU"
* changes:
Revert "Give all non-package services the power to interact accr..."
Revert "Check cross-user interactions for permissions and app-op..."
Revert "Invalidate package/permission cache if cross-profile app..."
10 files changed, 77 insertions, 287 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index a2d0b892aa0a..1f8cf8ac6d1d 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -46,39 +46,20 @@ public abstract class ActivityManagerInternal { // Access modes for handleIncomingUser. - /** - * Allows access to a caller with {@link android.Manifest.permission#INTERACT_ACROSS_USERS} or - * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL}. - */ public static final int ALLOW_NON_FULL = 0; /** * Allows access to a caller with {@link android.Manifest.permission#INTERACT_ACROSS_USERS} - * or {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} if in the same profile - * group. + * 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; - /** - * Allows access to a caller with {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} - * only. - */ + 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} or - * {@link android.Manifest.permission#INTERACT_ACROSS_USERS_FULL} if in the same profile group. + * 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/core/java/android/app/AppOpsManager.java b/core/java/android/app/AppOpsManager.java index 04f72f6dc71d..167b5a8029c0 100644 --- a/core/java/android/app/AppOpsManager.java +++ b/core/java/android/app/AppOpsManager.java @@ -6741,14 +6741,10 @@ public class AppOpsManager { */ @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) public void setUidMode(int code, int uid, @Mode int mode) { - // Clear calling UID to handle calls from inside the system server. See #noteOpNoThrow - long token = Binder.clearCallingIdentity(); try { mService.setUidMode(code, uid, mode); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); - } finally { - Binder.restoreCallingIdentity(token); } } @@ -6766,7 +6762,11 @@ public class AppOpsManager { @TestApi @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) public void setUidMode(@NonNull String appOp, int uid, @Mode int mode) { - setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode); + try { + mService.setUidMode(AppOpsManager.strOpToOp(appOp), uid, mode); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } /** @hide */ @@ -6795,14 +6795,10 @@ public class AppOpsManager { @TestApi @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) public void setMode(int code, int uid, String packageName, @Mode int mode) { - // Clear calling UID to handle calls from inside the system server. See #noteOpNoThrow - long token = Binder.clearCallingIdentity(); try { mService.setMode(code, uid, packageName, mode); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); - } finally { - Binder.restoreCallingIdentity(token); } } @@ -6822,7 +6818,11 @@ public class AppOpsManager { @RequiresPermission(android.Manifest.permission.MANAGE_APP_OPS_MODES) public void setMode(@NonNull String op, int uid, @Nullable String packageName, @Mode int mode) { - setMode(strOpToOp(op), uid, packageName, mode); + try { + mService.setMode(strOpToOp(op), uid, packageName, mode); + } catch (RemoteException e) { + throw e.rethrowFromSystemServer(); + } } /** @@ -7298,14 +7298,10 @@ public class AppOpsManager { * @hide */ public int unsafeCheckOpRawNoThrow(int op, int uid, @NonNull String packageName) { - // Clear calling UID to handle calls from inside the system server. See #noteOpNoThrow - long token = Binder.clearCallingIdentity(); try { return mService.checkOperationRaw(op, uid, packageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); - } finally { - Binder.restoreCallingIdentity(token); } } @@ -7477,20 +7473,8 @@ public class AppOpsManager { } } - int mode; - // Making the binder call "noteOperation" usually sets Binder.callingUid to the calling - // processes UID. Hence clearing the calling UID is superfluous. - // If the call is inside the system server though "noteOperation" is not a binder all, - // it is only a method call. Hence Binder.callingUid might still be set to the app that - // called the system server. This can lead to problems as not every app can see the - // same appops the system server can see. - long token = Binder.clearCallingIdentity(); - try { - mode = mService.noteOperation(op, uid, packageName, attributionTag, - collectionMode == COLLECT_ASYNC, message, shouldCollectMessage); - } finally { - Binder.restoreCallingIdentity(token); - } + int mode = mService.noteOperation(op, uid, packageName, attributionTag, + collectionMode == COLLECT_ASYNC, message, shouldCollectMessage); if (mode == MODE_ALLOWED) { if (collectionMode == COLLECT_SELF) { @@ -7653,17 +7637,10 @@ public class AppOpsManager { } } - int mode; - // Clear calling UID to handle calls from inside the system server. See #noteOpNoThrow - long token = Binder.clearCallingIdentity(); - try { - mode = mService.noteProxyOperation(op, proxiedUid, proxiedPackageName, - proxiedAttributionTag, myUid, mContext.getOpPackageName(), - mContext.getAttributionTag(), collectionMode == COLLECT_ASYNC, message, - shouldCollectMessage); - } finally { - Binder.restoreCallingIdentity(token); - } + int mode = mService.noteProxyOperation(op, proxiedUid, proxiedPackageName, + proxiedAttributionTag, myUid, mContext.getOpPackageName(), + mContext.getAttributionTag(), collectionMode == COLLECT_ASYNC, message, + shouldCollectMessage); if (mode == MODE_ALLOWED) { if (collectionMode == COLLECT_SELF) { @@ -7713,8 +7690,6 @@ public class AppOpsManager { */ @UnsupportedAppUsage public int checkOp(int op, int uid, String packageName) { - // Clear calling UID to handle calls from inside the system server. See #noteOpNoThrow - long token = Binder.clearCallingIdentity(); try { int mode = mService.checkOperation(op, uid, packageName); if (mode == MODE_ERRORED) { @@ -7723,8 +7698,6 @@ public class AppOpsManager { return mode; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); - } finally { - Binder.restoreCallingIdentity(token); } } @@ -7735,15 +7708,11 @@ public class AppOpsManager { */ @UnsupportedAppUsage public int checkOpNoThrow(int op, int uid, String packageName) { - // Clear calling UID to handle calls from inside the system server. See #noteOpNoThrow - long token = Binder.clearCallingIdentity(); try { int mode = mService.checkOperation(op, uid, packageName); return mode == AppOpsManager.MODE_FOREGROUND ? AppOpsManager.MODE_ALLOWED : mode; } catch (RemoteException e) { throw e.rethrowFromSystemServer(); - } finally { - Binder.restoreCallingIdentity(token); } } @@ -7995,16 +7964,9 @@ public class AppOpsManager { } } - int mode; - // Clear calling UID to handle calls from inside the system server. See #noteOpNoThrow - long token = Binder.clearCallingIdentity(); - try { - mode = mService.startOperation(getClientId(), op, uid, packageName, - attributionTag, startIfModeDefault, collectionMode == COLLECT_ASYNC, - message, shouldCollectMessage); - } finally { - Binder.restoreCallingIdentity(token); - } + int mode = mService.startOperation(getClientId(), op, uid, packageName, + attributionTag, startIfModeDefault, collectionMode == COLLECT_ASYNC, message, + shouldCollectMessage); if (mode == MODE_ALLOWED) { if (collectionMode == COLLECT_SELF) { @@ -8067,14 +8029,10 @@ public class AppOpsManager { */ public void finishOp(int op, int uid, @NonNull String packageName, @Nullable String attributionTag) { - // Clear calling UID to handle calls from inside the system server. See #noteOpNoThrow - long token = Binder.clearCallingIdentity(); try { mService.finishOperation(getClientId(), op, uid, packageName, attributionTag); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); - } finally { - Binder.restoreCallingIdentity(token); } } @@ -8666,14 +8624,10 @@ public class AppOpsManager { // TODO: Uncomment below annotation once b/73559440 is fixed // @RequiresPermission(value=Manifest.permission.WATCH_APPOPS, conditional=true) public boolean isOperationActive(int code, int uid, String packageName) { - // Clear calling UID to handle calls from inside the system server. See #noteOpNoThrow - long token = Binder.clearCallingIdentity(); try { return mService.isOperationActive(code, uid, packageName); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); - } finally { - Binder.restoreCallingIdentity(token); } } diff --git a/core/java/android/permission/PermissionManager.java b/core/java/android/permission/PermissionManager.java index b15109e67086..d80a7e794220 100644 --- a/core/java/android/permission/PermissionManager.java +++ b/core/java/android/permission/PermissionManager.java @@ -34,7 +34,6 @@ import android.content.Context; import android.content.pm.IPackageManager; import android.content.pm.PackageManager; import android.content.pm.permission.SplitPermissionInfoParcelable; -import android.os.Binder; import android.os.Process; import android.os.RemoteException; import android.os.ServiceManager; @@ -544,15 +543,10 @@ public final class PermissionManager { + permission); return PackageManager.PERMISSION_DENIED; } - // Clear Binder.callingUid in case this is called inside the system server. See - // more extensive comment in checkPackageNamePermissionUncached - long token = Binder.clearCallingIdentity(); try { return am.checkPermission(permission, pid, uid); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); - } finally { - Binder.restoreCallingIdentity(token); } } @@ -685,20 +679,11 @@ public final class PermissionManager { /* @hide */ private static int checkPackageNamePermissionUncached( String permName, String pkgName, @UserIdInt int userId) { - // Makeing the binder call "checkPermission" usually sets Binder.callingUid to the calling - // processes UID. Hence clearing the calling UID is superflous. - // If the call is inside the system server though "checkPermission" is not a binder all, it - // is only a method call. Hence Binder.callingUid might still be set to the app that called - // the system server. This can lead to problems as not every app can check the same - // permissions the system server can check. - long token = Binder.clearCallingIdentity(); try { return ActivityThread.getPermissionManager().checkPermission( permName, pkgName, userId); } catch (RemoteException e) { throw e.rethrowFromSystemServer(); - } finally { - Binder.restoreCallingIdentity(token); } } diff --git a/data/etc/platform.xml b/data/etc/platform.xml index 0a0681479278..dd8f40d586bc 100644 --- a/data/etc/platform.xml +++ b/data/etc/platform.xml @@ -153,8 +153,8 @@ <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="media" /> <assign-permission name="android.permission.GET_PROCESS_STATE_AND_OOM_SCORE" uid="media" /> <assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="media" /> + <assign-permission name="android.permission.INTERNET" uid="media" /> - <assign-permission name="android.permission.INTERACT_ACROSS_USERS" uid="media" /> <assign-permission name="android.permission.INTERNET" uid="shell" /> @@ -164,7 +164,6 @@ <assign-permission name="android.permission.UPDATE_DEVICE_STATS" uid="audioserver" /> <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="audioserver" /> <assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="audioserver" /> - <assign-permission name="android.permission.INTERACT_ACROSS_USERS" uid="audioserver" /> <assign-permission name="android.permission.MODIFY_AUDIO_SETTINGS" uid="cameraserver" /> <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="cameraserver" /> @@ -175,10 +174,8 @@ <assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="cameraserver" /> <assign-permission name="android.permission.WATCH_APPOPS" uid="cameraserver" /> <assign-permission name="android.permission.MANAGE_APP_OPS_MODES" uid="cameraserver" /> - <assign-permission name="android.permission.INTERACT_ACROSS_USERS" uid="cameraserver" /> <assign-permission name="android.permission.ACCESS_SURFACE_FLINGER" uid="graphics" /> - <assign-permission name="android.permission.INTERACT_ACROSS_USERS" uid="graphics" /> <assign-permission name="android.permission.DUMP" uid="incidentd" /> <assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="incidentd" /> @@ -193,10 +190,8 @@ <assign-permission name="android.permission.PACKAGE_USAGE_STATS" uid="statsd" /> <assign-permission name="android.permission.STATSCOMPANION" uid="statsd" /> <assign-permission name="android.permission.UPDATE_APP_OPS_STATS" uid="statsd" /> - <assign-permission name="android.permission.INTERACT_ACROSS_USERS" uid="statsd" /> <assign-permission name="android.permission.REGISTER_STATS_PULL_ATOM" uid="gpu_service" /> - <assign-permission name="android.permission.INTERACT_ACROSS_USERS" uid="gpu_service" /> <split-permission name="android.permission.ACCESS_FINE_LOCATION"> <new-permission name="android.permission.ACCESS_COARSE_LOCATION" /> diff --git a/services/core/java/com/android/server/am/ActiveServices.java b/services/core/java/com/android/server/am/ActiveServices.java index 4eef89a34875..c0f6011a45cd 100644 --- a/services/core/java/com/android/server/am/ActiveServices.java +++ b/services/core/java/com/android/server/am/ActiveServices.java @@ -2610,12 +2610,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 3dfbcc71dd3c..eb60573e6f17 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_FULL; -import static android.app.ActivityManagerInternal.ALLOW_ACROSS_PROFILES_IN_PROFILE_OR_NON_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; @@ -1912,12 +1911,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; @@ -1944,15 +1942,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); } @@ -1979,8 +1974,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 6099e52e54e9..668713f0fee7 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; @@ -37,7 +36,6 @@ import static android.app.AppOpsManager.OP_CAMERA; import static android.app.AppOpsManager.OP_FLAGS_ALL; import static android.app.AppOpsManager.OP_FLAG_SELF; import static android.app.AppOpsManager.OP_FLAG_TRUSTED_PROXIED; -import static android.app.AppOpsManager.OP_INTERACT_ACROSS_PROFILES; import static android.app.AppOpsManager.OP_NONE; import static android.app.AppOpsManager.OP_PLAY_AUDIO; import static android.app.AppOpsManager.OP_RECORD_AUDIO; @@ -131,7 +129,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; @@ -165,7 +162,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; @@ -2203,11 +2199,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) { @@ -2252,11 +2245,6 @@ public class AppOpsService extends IAppOpsService.Stub { scheduleWriteLocked(); } uidState.evalForegroundOps(mOpModeWatchers); - - if (code == OP_INTERACT_ACROSS_PROFILES) { - // Invalidate package info cache as the visibility of packages might have changed - PackageManager.invalidatePackageInfoCache(); - } } notifyOpChangedForAllPkgsInUid(code, uid, false, permissionPolicyCallback); @@ -2462,12 +2450,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); @@ -2729,9 +2713,6 @@ public class AppOpsService extends IAppOpsService.Stub { if (changed) { scheduleFastWriteLocked(); - - // Invalidate package info cache as the visibility of packages might have changed - PackageManager.invalidatePackageInfoCache(); } } if (callbacks != null) { @@ -2890,11 +2871,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) { @@ -3013,15 +2991,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) { @@ -3071,12 +3044,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) { @@ -3453,12 +3423,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) { @@ -3550,12 +3517,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) { @@ -3784,33 +3748,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) { @@ -5890,11 +5827,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 aa327ba02356..2f9e199bc506 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; @@ -902,16 +901,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { } private int checkPermissionImpl(String permName, String pkgName, int userId) { - try { - enforceCrossUserOrProfilePermission(Binder.getCallingUid(), userId, - false, false, "checkPermissionImpl"); - } catch (Exception e) { - Slog.e(TAG, "Invalid cross user access", e); - EventLog.writeEvent(0x534e4554, "153996875", "checkPermissionImpl", pkgName); - - throw e; - } - final AndroidPackage pkg = mPackageManagerInt.getPackage(pkgName); if (pkg == null) { return PackageManager.PERMISSION_DENIED; @@ -989,16 +978,6 @@ public class PermissionManagerService extends IPermissionManager.Stub { } private int checkUidPermissionImpl(String permName, int uid) { - try { - enforceCrossUserOrProfilePermission(Binder.getCallingUid(), UserHandle.getUserId(uid), - false, false, "checkUidPermissionImpl"); - } catch (Exception e) { - Slog.e(TAG, "Invalid cross user access", e); - EventLog.writeEvent(0x534e4554, "153996875", "checkUidPermissionImpl", uid); - - throw e; - } - final AndroidPackage pkg = mPackageManagerInt.getPackage(uid); return checkUidPermissionInternal(pkg, uid, permName); } @@ -4529,7 +4508,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; } @@ -4556,79 +4535,53 @@ public class PermissionManagerService extends IPermissionManager.Stub { private void enforceCrossUserOrProfilePermission(int callingUid, @UserIdInt 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) { + if (checkShell) { + PackageManagerServiceUtils.enforceShellRestriction(mUserManagerInt, + UserManager.DISALLOW_DEBUGGING_FEATURES, callingUid, userId); + } + final int callingUserId = UserHandle.getUserId(callingUid); + if (hasCrossUserPermission(callingUid, callingUserId, userId, requireFullPermission, + /*requirePermissionWhenSameUser= */ false)) { return; } - - // Prevent endless loop between when checking permission while checking a permission - if (callingPid == ActivityManagerService.MY_PID) { + 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; } - - 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) { - AndroidPackage callingPkg = mPackageManagerInt.getPackage(callingUid); - String callingPkgName = null; - if (callingPkg != null) { - callingPkgName = callingPkg.getPackageName(); - } - - if (PermissionChecker.checkPermissionForPreflight( - mContext, - android.Manifest.permission.INTERACT_ACROSS_PROFILES, - PermissionChecker.PID_UNKNOWN, - callingUid, - callingPkgName) - == PermissionChecker.PERMISSION_GRANTED) { - return; - } - } - String errorMessage = buildInvalidCrossUserOrProfilePermissionMessage( callingUid, userId, message, requireFullPermission, isSameProfileGroup); Slog.w(TAG, errorMessage); throw new SecurityException(errorMessage); - } finally { - Binder.restoreCallingIdentity(token); - } } - 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; } if (callingUid == Process.SYSTEM_UID || callingUid == Process.ROOT_UID) { return true; } - - if (!requireFullPermission) { - if (mContext.checkPermission(android.Manifest.permission.INTERACT_ACROSS_USERS, - callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) { - return true; - } + if (requireFullPermission) { + return hasPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL); } + return hasPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL) + || hasPermission(Manifest.permission.INTERACT_ACROSS_USERS); + } - return mContext.checkPermission(Manifest.permission.INTERACT_ACROSS_USERS_FULL, - callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; + 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" } ] }, |