From 3143ed11aacc3007621988f0a9422e263e0dc028 Mon Sep 17 00:00:00 2001 From: Rhed Jao Date: Fri, 3 Feb 2023 13:34:11 +0800 Subject: [PATCH] Fix a package visiblity gap in the start activity api The package existence information can be detected through the start activity api, if the target package declare an activity protected by a permission. Bug: 197946545 Test: atest AppEnumerationTests Change-Id: I8b3861d9d15823c4af7cb6b975ae614fe943a4b7 --- .../android/server/wm/ActivityStarter.java | 31 ++++++++++++++++--- 1 file changed, 27 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityStarter.java b/services/core/java/com/android/server/wm/ActivityStarter.java index 50eb356a0b377..c37a3d7f43ee2 100644 --- a/services/core/java/com/android/server/wm/ActivityStarter.java +++ b/services/core/java/com/android/server/wm/ActivityStarter.java @@ -1033,10 +1033,33 @@ class ActivityStarter { return err; } - boolean abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho, - requestCode, callingPid, callingUid, callingPackage, callingFeatureId, - request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord, - resultRootTask); + boolean abort; + try { + abort = !mSupervisor.checkStartAnyActivityPermission(intent, aInfo, resultWho, + requestCode, callingPid, callingUid, callingPackage, callingFeatureId, + request.ignoreTargetSecurity, inTask != null, callerApp, resultRecord, + resultRootTask); + } catch (SecurityException e) { + // Return activity not found for the explicit intent if the caller can't see the target + // to prevent the disclosure of package existence. + final Intent originalIntent = request.ephemeralIntent; + if (originalIntent != null && (originalIntent.getComponent() != null + || originalIntent.getPackage() != null)) { + final String targetPackageName = originalIntent.getComponent() != null + ? originalIntent.getComponent().getPackageName() + : originalIntent.getPackage(); + if (mService.getPackageManagerInternalLocked() + .filterAppAccess(targetPackageName, callingUid, userId)) { + if (resultRecord != null) { + resultRecord.sendResult(INVALID_UID, resultWho, requestCode, + RESULT_CANCELED, null /* data */, null /* dataGrants */); + } + SafeActivityOptions.abort(options); + return ActivityManager.START_CLASS_NOT_FOUND; + } + } + throw e; + } abort |= !mService.mIntentFirewall.checkStartActivity(intent, callingUid, callingPid, resolvedType, aInfo.applicationInfo); abort |= !mService.getPermissionPolicyInternal().checkStartActivity(intent, callingUid,