Loading services/core/java/com/android/server/appop/AppOpsService.java +57 −32 Original line number Diff line number Diff line Loading @@ -604,7 +604,7 @@ public class AppOpsService extends IAppOpsService.Stub { } } /** Returned from {@link #verifyAndGetBypass(int, String, String, String, boolean)}. */ /** Returned from {@link #verifyAndGetBypass(int, String, String, int, String, boolean)}. */ private static final class PackageVerificationResult { final RestrictionBypass bypass; Loading Loading @@ -3087,10 +3087,10 @@ public class AppOpsService extends IAppOpsService.Stub { public int checkPackage(int uid, String packageName) { Objects.requireNonNull(packageName); try { verifyAndGetBypass(uid, packageName, null, null, true); verifyAndGetBypass(uid, packageName, null, Process.INVALID_UID, null, true); // When the caller is the system, it's possible that the packageName is the special // one (e.g., "root") which isn't actually existed. if (resolveUid(packageName) == uid if (resolveNonAppUid(packageName) == uid || (isPackageExisted(packageName) && !filterAppAccessUnlocked(packageName, UserHandle.getUserId(uid)))) { return AppOpsManager.MODE_ALLOWED; Loading Loading @@ -3306,7 +3306,7 @@ public class AppOpsService extends IAppOpsService.Stub { boolean shouldCollectMessage, int notedCount) { PackageVerificationResult pvr; try { pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName); pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyUid, proxyPackageName); if (!pvr.isAttributionTagValid) { attributionTag = null; } Loading Loading @@ -3930,7 +3930,7 @@ public class AppOpsService extends IAppOpsService.Stub { // Test if the proxied operation will succeed before starting the proxy operation final SyncNotedAppOp testProxiedOp = startOperationDryRun(code, proxiedUid, resolvedProxiedPackageName, proxiedAttributionTag, proxiedVirtualDeviceId, resolvedProxyPackageName, proxiedFlags, proxiedVirtualDeviceId, proxyUid, resolvedProxyPackageName, proxiedFlags, startIfModeDefault); if (!shouldStartForMode(testProxiedOp.getOpMode(), startIfModeDefault)) { Loading Loading @@ -3970,7 +3970,7 @@ public class AppOpsService extends IAppOpsService.Stub { int attributionChainId) { PackageVerificationResult pvr; try { pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName); pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyUid, proxyPackageName); if (!pvr.isAttributionTagValid) { attributionTag = null; } Loading Loading @@ -4097,11 +4097,11 @@ public class AppOpsService extends IAppOpsService.Stub { */ private SyncNotedAppOp startOperationDryRun(int code, int uid, @NonNull String packageName, @Nullable String attributionTag, int virtualDeviceId, String proxyPackageName, @OpFlags int flags, int proxyUid, String proxyPackageName, @OpFlags int flags, boolean startIfModeDefault) { PackageVerificationResult pvr; try { pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName); pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyUid, proxyPackageName); if (!pvr.isAttributionTagValid) { attributionTag = null; } Loading Loading @@ -4656,14 +4656,18 @@ public class AppOpsService extends IAppOpsService.Stub { private boolean isSpecialPackage(int callingUid, @Nullable String packageName) { final String resolvedPackage = AppOpsManager.resolvePackageName(callingUid, packageName); return callingUid == Process.SYSTEM_UID || resolveUid(resolvedPackage) != Process.INVALID_UID; || resolveNonAppUid(resolvedPackage) != Process.INVALID_UID; } private boolean isCallerAndAttributionTrusted(@NonNull AttributionSource attributionSource) { if (attributionSource.getUid() != Binder.getCallingUid() && attributionSource.isTrusted(mContext)) { // if there is a next attribution source, it must be trusted, as well. if (attributionSource.getNext() == null || attributionSource.getNext().isTrusted(mContext)) { return true; } } return mContext.checkPermission(android.Manifest.permission.UPDATE_APP_OPS_STATS, Binder.getCallingPid(), Binder.getCallingUid(), null) == PackageManager.PERMISSION_GRANTED; Loading Loading @@ -4757,19 +4761,20 @@ public class AppOpsService extends IAppOpsService.Stub { } /** * @see #verifyAndGetBypass(int, String, String, String, boolean) * @see #verifyAndGetBypass(int, String, String, int, String, boolean) */ private @NonNull PackageVerificationResult verifyAndGetBypass(int uid, String packageName, @Nullable String attributionTag) { return verifyAndGetBypass(uid, packageName, attributionTag, null); return verifyAndGetBypass(uid, packageName, attributionTag, Process.INVALID_UID, null); } /** * @see #verifyAndGetBypass(int, String, String, String, boolean) * @see #verifyAndGetBypass(int, String, String, int, String, boolean) */ private @NonNull PackageVerificationResult verifyAndGetBypass(int uid, String packageName, @Nullable String attributionTag, @Nullable String proxyPackageName) { return verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName, false); @Nullable String attributionTag, int proxyUid, @Nullable String proxyPackageName) { return verifyAndGetBypass(uid, packageName, attributionTag, proxyUid, proxyPackageName, false); } /** Loading @@ -4780,14 +4785,15 @@ public class AppOpsService extends IAppOpsService.Stub { * @param uid The uid the package belongs to * @param packageName The package the might belong to the uid * @param attributionTag attribution tag or {@code null} if no need to verify * @param proxyPackageName The proxy package, from which the attribution tag is to be pulled * @param proxyUid The proxy uid, from which the attribution tag is to be pulled * @param proxyPackageName The proxy package, from which the attribution tag may be pulled * @param suppressErrorLogs Whether to print to logcat about nonmatching parameters * * @return PackageVerificationResult containing {@link RestrictionBypass} and whether the * attribution tag is valid */ private @NonNull PackageVerificationResult verifyAndGetBypass(int uid, String packageName, @Nullable String attributionTag, @Nullable String proxyPackageName, @Nullable String attributionTag, int proxyUid, @Nullable String proxyPackageName, boolean suppressErrorLogs) { if (uid == Process.ROOT_UID) { // For backwards compatibility, don't check package name for root UID. Loading Loading @@ -4831,34 +4837,47 @@ public class AppOpsService extends IAppOpsService.Stub { int callingUid = Binder.getCallingUid(); // Allow any attribution tag for resolvable uids int pkgUid; // Allow any attribution tag for resolvable, non-app uids int nonAppUid; if (Objects.equals(packageName, "com.android.shell")) { // Special case for the shell which is a package but should be able // to bypass app attribution tag restrictions. pkgUid = Process.SHELL_UID; nonAppUid = Process.SHELL_UID; } else { pkgUid = resolveUid(packageName); nonAppUid = resolveNonAppUid(packageName); } if (pkgUid != Process.INVALID_UID) { if (pkgUid != UserHandle.getAppId(uid)) { if (nonAppUid != Process.INVALID_UID) { if (nonAppUid != UserHandle.getAppId(uid)) { if (!suppressErrorLogs) { Slog.e(TAG, "Bad call made by uid " + callingUid + ". " + "Package \"" + packageName + "\" does not belong to uid " + uid + "."); } String otherUidMessage = DEBUG ? " but it is really " + pkgUid : " but it is not"; throw new SecurityException("Specified package \"" + packageName + "\" under uid " + UserHandle.getAppId(uid) + otherUidMessage); String otherUidMessage = DEBUG ? " but it is really " + nonAppUid : " but it is not"; throw new SecurityException("Specified package \"" + packageName + "\" under uid " + UserHandle.getAppId(uid) + otherUidMessage); } // We only allow bypassing the attribution tag verification if the proxy is a // system app (or is null), in order to prevent abusive apps clogging the appops // system with unlimited attribution tags via proxy calls. boolean proxyIsSystemAppOrNull = true; if (proxyPackageName != null) { int proxyAppId = UserHandle.getAppId(proxyUid); if (proxyAppId >= Process.FIRST_APPLICATION_UID) { proxyIsSystemAppOrNull = mPackageManagerInternal.isSystemPackage(proxyPackageName); } } return new PackageVerificationResult(RestrictionBypass.UNRESTRICTED, /* isAttributionTagValid */ true); /* isAttributionTagValid */ proxyIsSystemAppOrNull); } int userId = UserHandle.getUserId(uid); RestrictionBypass bypass = null; boolean isAttributionTagValid = false; int pkgUid = nonAppUid; final long ident = Binder.clearCallingIdentity(); try { PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); Loading Loading @@ -5649,7 +5668,7 @@ public class AppOpsService extends IAppOpsService.Stub { if (nonpackageUid != -1) { packageName = null; } else { packageUid = resolveUid(packageName); packageUid = resolveNonAppUid(packageName); if (packageUid < 0) { packageUid = AppGlobals.getPackageManager().getPackageUid(packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); Loading Loading @@ -6749,11 +6768,17 @@ public class AppOpsService extends IAppOpsService.Stub { if (restricted && attrOp.isRunning()) { attrOp.pause(); } else if (attrOp.isPaused()) { RestrictionBypass bypass = verifyAndGetBypass(uid, ops.packageName, attrOp.tag) .bypass; if (!isOpRestrictedLocked(uid, code, ops.packageName, attrOp.tag, Context.DEVICE_ID_DEFAULT, bypass, false)) { // Only resume if there are no other restrictions remaining on this op attrOp.resume(); } } } } } private void notifyWatchersOnDefaultDevice(int code, int uid) { ArraySet<OnOpModeChangedListener> modeChangedListenerSet; Loading Loading @@ -7198,7 +7223,7 @@ public class AppOpsService extends IAppOpsService.Stub { } } private static int resolveUid(String packageName) { private static int resolveNonAppUid(String packageName) { if (packageName == null) { return Process.INVALID_UID; } Loading Loading
services/core/java/com/android/server/appop/AppOpsService.java +57 −32 Original line number Diff line number Diff line Loading @@ -604,7 +604,7 @@ public class AppOpsService extends IAppOpsService.Stub { } } /** Returned from {@link #verifyAndGetBypass(int, String, String, String, boolean)}. */ /** Returned from {@link #verifyAndGetBypass(int, String, String, int, String, boolean)}. */ private static final class PackageVerificationResult { final RestrictionBypass bypass; Loading Loading @@ -3087,10 +3087,10 @@ public class AppOpsService extends IAppOpsService.Stub { public int checkPackage(int uid, String packageName) { Objects.requireNonNull(packageName); try { verifyAndGetBypass(uid, packageName, null, null, true); verifyAndGetBypass(uid, packageName, null, Process.INVALID_UID, null, true); // When the caller is the system, it's possible that the packageName is the special // one (e.g., "root") which isn't actually existed. if (resolveUid(packageName) == uid if (resolveNonAppUid(packageName) == uid || (isPackageExisted(packageName) && !filterAppAccessUnlocked(packageName, UserHandle.getUserId(uid)))) { return AppOpsManager.MODE_ALLOWED; Loading Loading @@ -3306,7 +3306,7 @@ public class AppOpsService extends IAppOpsService.Stub { boolean shouldCollectMessage, int notedCount) { PackageVerificationResult pvr; try { pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName); pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyUid, proxyPackageName); if (!pvr.isAttributionTagValid) { attributionTag = null; } Loading Loading @@ -3930,7 +3930,7 @@ public class AppOpsService extends IAppOpsService.Stub { // Test if the proxied operation will succeed before starting the proxy operation final SyncNotedAppOp testProxiedOp = startOperationDryRun(code, proxiedUid, resolvedProxiedPackageName, proxiedAttributionTag, proxiedVirtualDeviceId, resolvedProxyPackageName, proxiedFlags, proxiedVirtualDeviceId, proxyUid, resolvedProxyPackageName, proxiedFlags, startIfModeDefault); if (!shouldStartForMode(testProxiedOp.getOpMode(), startIfModeDefault)) { Loading Loading @@ -3970,7 +3970,7 @@ public class AppOpsService extends IAppOpsService.Stub { int attributionChainId) { PackageVerificationResult pvr; try { pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName); pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyUid, proxyPackageName); if (!pvr.isAttributionTagValid) { attributionTag = null; } Loading Loading @@ -4097,11 +4097,11 @@ public class AppOpsService extends IAppOpsService.Stub { */ private SyncNotedAppOp startOperationDryRun(int code, int uid, @NonNull String packageName, @Nullable String attributionTag, int virtualDeviceId, String proxyPackageName, @OpFlags int flags, int proxyUid, String proxyPackageName, @OpFlags int flags, boolean startIfModeDefault) { PackageVerificationResult pvr; try { pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName); pvr = verifyAndGetBypass(uid, packageName, attributionTag, proxyUid, proxyPackageName); if (!pvr.isAttributionTagValid) { attributionTag = null; } Loading Loading @@ -4656,14 +4656,18 @@ public class AppOpsService extends IAppOpsService.Stub { private boolean isSpecialPackage(int callingUid, @Nullable String packageName) { final String resolvedPackage = AppOpsManager.resolvePackageName(callingUid, packageName); return callingUid == Process.SYSTEM_UID || resolveUid(resolvedPackage) != Process.INVALID_UID; || resolveNonAppUid(resolvedPackage) != Process.INVALID_UID; } private boolean isCallerAndAttributionTrusted(@NonNull AttributionSource attributionSource) { if (attributionSource.getUid() != Binder.getCallingUid() && attributionSource.isTrusted(mContext)) { // if there is a next attribution source, it must be trusted, as well. if (attributionSource.getNext() == null || attributionSource.getNext().isTrusted(mContext)) { return true; } } return mContext.checkPermission(android.Manifest.permission.UPDATE_APP_OPS_STATS, Binder.getCallingPid(), Binder.getCallingUid(), null) == PackageManager.PERMISSION_GRANTED; Loading Loading @@ -4757,19 +4761,20 @@ public class AppOpsService extends IAppOpsService.Stub { } /** * @see #verifyAndGetBypass(int, String, String, String, boolean) * @see #verifyAndGetBypass(int, String, String, int, String, boolean) */ private @NonNull PackageVerificationResult verifyAndGetBypass(int uid, String packageName, @Nullable String attributionTag) { return verifyAndGetBypass(uid, packageName, attributionTag, null); return verifyAndGetBypass(uid, packageName, attributionTag, Process.INVALID_UID, null); } /** * @see #verifyAndGetBypass(int, String, String, String, boolean) * @see #verifyAndGetBypass(int, String, String, int, String, boolean) */ private @NonNull PackageVerificationResult verifyAndGetBypass(int uid, String packageName, @Nullable String attributionTag, @Nullable String proxyPackageName) { return verifyAndGetBypass(uid, packageName, attributionTag, proxyPackageName, false); @Nullable String attributionTag, int proxyUid, @Nullable String proxyPackageName) { return verifyAndGetBypass(uid, packageName, attributionTag, proxyUid, proxyPackageName, false); } /** Loading @@ -4780,14 +4785,15 @@ public class AppOpsService extends IAppOpsService.Stub { * @param uid The uid the package belongs to * @param packageName The package the might belong to the uid * @param attributionTag attribution tag or {@code null} if no need to verify * @param proxyPackageName The proxy package, from which the attribution tag is to be pulled * @param proxyUid The proxy uid, from which the attribution tag is to be pulled * @param proxyPackageName The proxy package, from which the attribution tag may be pulled * @param suppressErrorLogs Whether to print to logcat about nonmatching parameters * * @return PackageVerificationResult containing {@link RestrictionBypass} and whether the * attribution tag is valid */ private @NonNull PackageVerificationResult verifyAndGetBypass(int uid, String packageName, @Nullable String attributionTag, @Nullable String proxyPackageName, @Nullable String attributionTag, int proxyUid, @Nullable String proxyPackageName, boolean suppressErrorLogs) { if (uid == Process.ROOT_UID) { // For backwards compatibility, don't check package name for root UID. Loading Loading @@ -4831,34 +4837,47 @@ public class AppOpsService extends IAppOpsService.Stub { int callingUid = Binder.getCallingUid(); // Allow any attribution tag for resolvable uids int pkgUid; // Allow any attribution tag for resolvable, non-app uids int nonAppUid; if (Objects.equals(packageName, "com.android.shell")) { // Special case for the shell which is a package but should be able // to bypass app attribution tag restrictions. pkgUid = Process.SHELL_UID; nonAppUid = Process.SHELL_UID; } else { pkgUid = resolveUid(packageName); nonAppUid = resolveNonAppUid(packageName); } if (pkgUid != Process.INVALID_UID) { if (pkgUid != UserHandle.getAppId(uid)) { if (nonAppUid != Process.INVALID_UID) { if (nonAppUid != UserHandle.getAppId(uid)) { if (!suppressErrorLogs) { Slog.e(TAG, "Bad call made by uid " + callingUid + ". " + "Package \"" + packageName + "\" does not belong to uid " + uid + "."); } String otherUidMessage = DEBUG ? " but it is really " + pkgUid : " but it is not"; throw new SecurityException("Specified package \"" + packageName + "\" under uid " + UserHandle.getAppId(uid) + otherUidMessage); String otherUidMessage = DEBUG ? " but it is really " + nonAppUid : " but it is not"; throw new SecurityException("Specified package \"" + packageName + "\" under uid " + UserHandle.getAppId(uid) + otherUidMessage); } // We only allow bypassing the attribution tag verification if the proxy is a // system app (or is null), in order to prevent abusive apps clogging the appops // system with unlimited attribution tags via proxy calls. boolean proxyIsSystemAppOrNull = true; if (proxyPackageName != null) { int proxyAppId = UserHandle.getAppId(proxyUid); if (proxyAppId >= Process.FIRST_APPLICATION_UID) { proxyIsSystemAppOrNull = mPackageManagerInternal.isSystemPackage(proxyPackageName); } } return new PackageVerificationResult(RestrictionBypass.UNRESTRICTED, /* isAttributionTagValid */ true); /* isAttributionTagValid */ proxyIsSystemAppOrNull); } int userId = UserHandle.getUserId(uid); RestrictionBypass bypass = null; boolean isAttributionTagValid = false; int pkgUid = nonAppUid; final long ident = Binder.clearCallingIdentity(); try { PackageManagerInternal pmInt = LocalServices.getService(PackageManagerInternal.class); Loading Loading @@ -5649,7 +5668,7 @@ public class AppOpsService extends IAppOpsService.Stub { if (nonpackageUid != -1) { packageName = null; } else { packageUid = resolveUid(packageName); packageUid = resolveNonAppUid(packageName); if (packageUid < 0) { packageUid = AppGlobals.getPackageManager().getPackageUid(packageName, PackageManager.MATCH_UNINSTALLED_PACKAGES, userId); Loading Loading @@ -6749,11 +6768,17 @@ public class AppOpsService extends IAppOpsService.Stub { if (restricted && attrOp.isRunning()) { attrOp.pause(); } else if (attrOp.isPaused()) { RestrictionBypass bypass = verifyAndGetBypass(uid, ops.packageName, attrOp.tag) .bypass; if (!isOpRestrictedLocked(uid, code, ops.packageName, attrOp.tag, Context.DEVICE_ID_DEFAULT, bypass, false)) { // Only resume if there are no other restrictions remaining on this op attrOp.resume(); } } } } } private void notifyWatchersOnDefaultDevice(int code, int uid) { ArraySet<OnOpModeChangedListener> modeChangedListenerSet; Loading Loading @@ -7198,7 +7223,7 @@ public class AppOpsService extends IAppOpsService.Stub { } } private static int resolveUid(String packageName) { private static int resolveNonAppUid(String packageName) { if (packageName == null) { return Process.INVALID_UID; } Loading