diff options
| -rw-r--r-- | services/core/java/com/android/server/pm/PackageManagerService.java | 216 |
1 files changed, 159 insertions, 57 deletions
diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index addaccee7b1f..7ec867f36448 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -102,6 +102,7 @@ import static com.android.server.pm.PermissionsState.PERMISSION_OPERATION_SUCCES import static dalvik.system.DexFile.getNonProfileGuidedCompilerFilter; import android.Manifest; +import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; @@ -300,6 +301,8 @@ import java.io.FileReader; import java.io.FilenameFilter; import java.io.IOException; import java.io.PrintWriter; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; import java.nio.charset.StandardCharsets; import java.security.DigestInputStream; import java.security.MessageDigest; @@ -438,6 +441,21 @@ public class PackageManagerService extends IPackageManager.Stub private static final int[] EMPTY_INT_ARRAY = new int[0]; + private static final int TYPE_UNKNOWN = 0; + private static final int TYPE_ACTIVITY = 1; + private static final int TYPE_RECEIVER = 2; + private static final int TYPE_SERVICE = 3; + private static final int TYPE_PROVIDER = 4; + @IntDef(prefix = { "TYPE_" }, value = { + TYPE_UNKNOWN, + TYPE_ACTIVITY, + TYPE_RECEIVER, + TYPE_SERVICE, + TYPE_PROVIDER, + }) + @Retention(RetentionPolicy.SOURCE) + public @interface ComponentType {} + /** * Timeout (in milliseconds) after which the watchdog should declare that * our handler thread is wedged. The usual default for such things is one @@ -3527,25 +3545,8 @@ public class PackageManagerService extends IPackageManager.Stub // and 2) ephemeral apps that have explicitly interacted with it // * Ephemeral apps can only see their own data and exposed installed apps // * Holding a signature permission allows seeing instant apps - if (!canAccessInstantApps(callingUid)) { - final String instantAppPackageName = getInstantAppPackageName(callingUid); - if (instantAppPackageName != null) { - // ephemeral apps can only get information on themselves or - // installed apps that are exposed. - if (!instantAppPackageName.equals(p.packageName) - && (ps.getInstantApp(userId) || !p.visibleToInstantApps)) { - return null; - } - } else { - if (ps.getInstantApp(userId)) { - // only get access to the ephemeral app if we've been granted access - final int callingAppId = UserHandle.getAppId(callingUid); - if (!mInstantAppRegistry.isInstantAccessGranted( - userId, callingAppId, ps.appId)) { - return null; - } - } - } + if (filterAppAccessLPr(ps, callingUid, userId)) { + return null; } final PermissionsState permissionsState = ps.getPermissionsState(); @@ -3705,6 +3706,47 @@ public class PackageManagerService extends IPackageManager.Stub return null; } + private boolean isComponentVisibleToInstantApp(@Nullable ComponentName component) { + if (isComponentVisibleToInstantApp(component, TYPE_ACTIVITY)) { + return true; + } + if (isComponentVisibleToInstantApp(component, TYPE_SERVICE)) { + return true; + } + if (isComponentVisibleToInstantApp(component, TYPE_PROVIDER)) { + return true; + } + return false; + } + + private boolean isComponentVisibleToInstantApp( + @Nullable ComponentName component, @ComponentType int type) { + if (type == TYPE_ACTIVITY) { + final PackageParser.Activity activity = mActivities.mActivities.get(component); + return activity != null + ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0 + : false; + } else if (type == TYPE_RECEIVER) { + final PackageParser.Activity activity = mReceivers.mActivities.get(component); + return activity != null + ? (activity.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0 + : false; + } else if (type == TYPE_SERVICE) { + final PackageParser.Service service = mServices.mServices.get(component); + return service != null + ? (service.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0 + : false; + } else if (type == TYPE_PROVIDER) { + final PackageParser.Provider provider = mProviders.mProviders.get(component); + return provider != null + ? (provider.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0 + : false; + } else if (type == TYPE_UNKNOWN) { + return isComponentVisibleToInstantApp(component); + } + return false; + } + /** * Returns whether or not access to the application should be filtered. * <p> @@ -3714,7 +3756,7 @@ public class PackageManagerService extends IPackageManager.Stub * @see #canAccessInstantApps(int) */ private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, - @Nullable ComponentName component, boolean componentVisibleToInstantApp, int userId) { + @Nullable ComponentName component, @ComponentType int componentType, int userId) { // if we're in an isolated process, get the real calling UID if (Process.isIsolated(callingUid)) { callingUid = mIsolatedOwners.get(callingUid); @@ -3735,10 +3777,10 @@ public class PackageManagerService extends IPackageManager.Stub if (callerIsInstantApp) { // request for a specific component; if it hasn't been explicitly exposed, filter if (component != null) { - return !componentVisibleToInstantApp; + return !isComponentVisibleToInstantApp(component, componentType); } // request for application; if no components have been explicitly exposed, filter - return !ps.pkg.visibleToInstantApps; + return ps.getInstantApp(userId) || !ps.pkg.visibleToInstantApps; } if (ps.getInstantApp(userId)) { // caller can see all components of all instant applications, don't filter @@ -3760,7 +3802,7 @@ public class PackageManagerService extends IPackageManager.Stub * @see #filterAppAccessLPr(PackageSetting, int, ComponentName, boolean, int) */ private boolean filterAppAccessLPr(@Nullable PackageSetting ps, int callingUid, int userId) { - return filterAppAccessLPr(ps, callingUid, null, false, userId); + return filterAppAccessLPr(ps, callingUid, null, TYPE_UNKNOWN, userId); } private boolean filterSharedLibPackageLPr(@Nullable PackageSetting ps, int uid, int userId, @@ -4412,9 +4454,7 @@ public class PackageManagerService extends IPackageManager.Stub if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); if (ps == null) return null; - final boolean visibleToInstantApp = - (a.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0; - if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) { + if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, userId)) { return null; } return generateActivityInfo(a, flags, ps.readUserState(userId), userId); @@ -4445,9 +4485,7 @@ public class PackageManagerService extends IPackageManager.Stub if (ps == null) { return false; } - final boolean visibleToInstantApp = - (a.info.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0; - if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, callingUserId)) { + if (filterAppAccessLPr(ps, callingUid, component, TYPE_ACTIVITY, callingUserId)) { return false; } for (int i=0; i<a.intents.size(); i++) { @@ -4463,8 +4501,9 @@ public class PackageManagerService extends IPackageManager.Stub @Override public ActivityInfo getReceiverInfo(ComponentName component, int flags, int userId) { if (!sUserManager.exists(userId)) return null; + final int callingUid = Binder.getCallingUid(); flags = updateFlagsForComponent(flags, userId, component); - enforceCrossUserPermission(Binder.getCallingUid(), userId, + enforceCrossUserPermission(callingUid, userId, false /* requireFullPermission */, false /* checkShell */, "get receiver info"); synchronized (mPackages) { PackageParser.Activity a = mReceivers.mActivities.get(component); @@ -4473,6 +4512,9 @@ public class PackageManagerService extends IPackageManager.Stub if (a != null && mSettings.isEnabledAndMatchLPr(a.info, flags, userId)) { PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); if (ps == null) return null; + if (filterAppAccessLPr(ps, callingUid, component, TYPE_RECEIVER, userId)) { + return null; + } return generateActivityInfo(a, flags, ps.readUserState(userId), userId); } } @@ -4606,9 +4648,7 @@ public class PackageManagerService extends IPackageManager.Stub if (s != null && mSettings.isEnabledAndMatchLPr(s.info, flags, userId)) { PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); if (ps == null) return null; - final boolean visibleToInstantApp = - (s.info.flags & ServiceInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0; - if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) { + if (filterAppAccessLPr(ps, callingUid, component, TYPE_SERVICE, userId)) { return null; } ServiceInfo si = PackageParser.generateServiceInfo(s, flags, @@ -4636,9 +4676,7 @@ public class PackageManagerService extends IPackageManager.Stub if (p != null && mSettings.isEnabledAndMatchLPr(p.info, flags, userId)) { PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); if (ps == null) return null; - final boolean visibleToInstantApp = - (p.info.flags & ProviderInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0; - if (filterAppAccessLPr(ps, callingUid, component, visibleToInstantApp, userId)) { + if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) { return null; } ProviderInfo pi = PackageParser.generateProviderInfo(p, flags, @@ -7553,6 +7591,7 @@ public class PackageManagerService extends IPackageManager.Stub String resolvedType, int flags, int userId) { if (!sUserManager.exists(userId)) return Collections.emptyList(); final int callingUid = Binder.getCallingUid(); + final String instantAppPkgName = getInstantAppPackageName(callingUid); flags = updateFlagsForResolve(flags, userId, intent, callingUid, false /*includeInstantApps*/); ComponentName comp = intent.getComponent(); @@ -7563,26 +7602,61 @@ public class PackageManagerService extends IPackageManager.Stub } } if (comp != null) { - List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); - ActivityInfo ai = getReceiverInfo(comp, flags, userId); + final List<ResolveInfo> list = new ArrayList<ResolveInfo>(1); + final ActivityInfo ai = getReceiverInfo(comp, flags, userId); if (ai != null) { - ResolveInfo ri = new ResolveInfo(); - ri.activityInfo = ai; - list.add(ri); + // When specifying an explicit component, we prevent the activity from being + // used when either 1) the calling package is normal and the activity is within + // an instant application or 2) the calling package is ephemeral and the + // activity is not visible to instant applications. + final boolean matchInstantApp = + (flags & PackageManager.MATCH_INSTANT) != 0; + final boolean matchVisibleToInstantAppOnly = + (flags & PackageManager.MATCH_VISIBLE_TO_INSTANT_APP_ONLY) != 0; + final boolean matchExplicitlyVisibleOnly = + (flags & PackageManager.MATCH_EXPLICITLY_VISIBLE_ONLY) != 0; + final boolean isCallerInstantApp = + instantAppPkgName != null; + final boolean isTargetSameInstantApp = + comp.getPackageName().equals(instantAppPkgName); + final boolean isTargetInstantApp = + (ai.applicationInfo.privateFlags + & ApplicationInfo.PRIVATE_FLAG_INSTANT) != 0; + final boolean isTargetVisibleToInstantApp = + (ai.flags & ActivityInfo.FLAG_VISIBLE_TO_INSTANT_APP) != 0; + final boolean isTargetExplicitlyVisibleToInstantApp = + isTargetVisibleToInstantApp + && (ai.flags & ActivityInfo.FLAG_IMPLICITLY_VISIBLE_TO_INSTANT_APP) == 0; + final boolean isTargetHiddenFromInstantApp = + !isTargetVisibleToInstantApp + || (matchExplicitlyVisibleOnly && !isTargetExplicitlyVisibleToInstantApp); + final boolean blockResolution = + !isTargetSameInstantApp + && ((!matchInstantApp && !isCallerInstantApp && isTargetInstantApp) + || (matchVisibleToInstantAppOnly && isCallerInstantApp + && isTargetHiddenFromInstantApp)); + if (!blockResolution) { + ResolveInfo ri = new ResolveInfo(); + ri.activityInfo = ai; + list.add(ri); + } } - return list; + return applyPostResolutionFilter(list, instantAppPkgName); } // reader synchronized (mPackages) { String pkgName = intent.getPackage(); if (pkgName == null) { - return mReceivers.queryIntent(intent, resolvedType, flags, userId); + final List<ResolveInfo> result = + mReceivers.queryIntent(intent, resolvedType, flags, userId); + return applyPostResolutionFilter(result, instantAppPkgName); } final PackageParser.Package pkg = mPackages.get(pkgName); if (pkg != null) { - return mReceivers.queryIntentForPackage(intent, resolvedType, flags, pkg.receivers, - userId); + final List<ResolveInfo> result = mReceivers.queryIntentForPackage( + intent, resolvedType, flags, pkg.receivers, userId); + return applyPostResolutionFilter(result, instantAppPkgName); } return Collections.emptyList(); } @@ -8263,11 +8337,11 @@ public class PackageManagerService extends IPackageManager.Stub @Override public @NonNull ParceledListSlice<ProviderInfo> queryContentProviders(String processName, int uid, int flags, String metaDataKey) { + final int callingUid = Binder.getCallingUid(); final int userId = processName != null ? UserHandle.getUserId(uid) : UserHandle.getCallingUserId(); if (!sUserManager.exists(userId)) return ParceledListSlice.emptyList(); flags = updateFlagsForComponent(flags, userId, processName); - ArrayList<ProviderInfo> finalList = null; // reader synchronized (mPackages) { @@ -8287,7 +8361,11 @@ public class PackageManagerService extends IPackageManager.Stub && (p.metaData == null || !p.metaData.containsKey(metaDataKey))) { continue; } - + final ComponentName component = + new ComponentName(p.info.packageName, p.info.name); + if (filterAppAccessLPr(ps, callingUid, component, TYPE_PROVIDER, userId)) { + continue; + } if (finalList == null) { finalList = new ArrayList<ProviderInfo>(3); } @@ -8309,10 +8387,17 @@ public class PackageManagerService extends IPackageManager.Stub } @Override - public InstrumentationInfo getInstrumentationInfo(ComponentName name, int flags) { + public InstrumentationInfo getInstrumentationInfo(ComponentName component, int flags) { // reader synchronized (mPackages) { - final PackageParser.Instrumentation i = mInstrumentation.get(name); + final int callingUid = Binder.getCallingUid(); + final int callingUserId = UserHandle.getUserId(callingUid); + final PackageSetting ps = mSettings.mPackages.get(component.getPackageName()); + if (ps == null) return null; + if (filterAppAccessLPr(ps, callingUid, component, TYPE_UNKNOWN, callingUserId)) { + return null; + } + final PackageParser.Instrumentation i = mInstrumentation.get(component); return PackageParser.generateInstrumentationInfo(i, flags); } } @@ -8320,6 +8405,12 @@ public class PackageManagerService extends IPackageManager.Stub @Override public @NonNull ParceledListSlice<InstrumentationInfo> queryInstrumentation( String targetPackage, int flags) { + final int callingUid = Binder.getCallingUid(); + final int callingUserId = UserHandle.getUserId(callingUid); + final PackageSetting ps = mSettings.mPackages.get(targetPackage); + if (filterAppAccessLPr(ps, callingUid, callingUserId)) { + return ParceledListSlice.emptyList(); + } return new ParceledListSlice<>(queryInstrumentationInternal(targetPackage, flags)); } @@ -9106,8 +9197,16 @@ public class PackageManagerService extends IPackageManager.Stub @Override public void notifyPackageUse(String packageName, int reason) { synchronized (mPackages) { - if (!isCallerSameApp(packageName, Binder.getCallingUid())) { - return; + final int callingUid = Binder.getCallingUid(); + final int callingUserId = UserHandle.getUserId(callingUid); + if (getInstantAppPackageName(callingUid) != null) { + if (!isCallerSameApp(packageName, callingUid)) { + return; + } + } else { + if (isInstantApp(packageName, callingUserId)) { + return; + } } final PackageParser.Package p = mPackages.get(packageName); if (p == null) { @@ -21004,14 +21103,17 @@ Slog.v(TAG, ":: stepped forward, applying functor at tag " + parser.getName()); } @Override - public int getComponentEnabledSetting(ComponentName componentName, int userId) { + public int getComponentEnabledSetting(ComponentName component, int userId) { if (!sUserManager.exists(userId)) return COMPONENT_ENABLED_STATE_DISABLED; - int uid = Binder.getCallingUid(); - enforceCrossUserPermission(uid, userId, - false /* requireFullPermission */, false /* checkShell */, "get component enabled"); - // reader + int callingUid = Binder.getCallingUid(); + enforceCrossUserPermission(callingUid, userId, + false /*requireFullPermission*/, false /*checkShell*/, "getComponentEnabled"); synchronized (mPackages) { - return mSettings.getComponentEnabledSettingLPr(componentName, userId); + if (filterAppAccessLPr(mSettings.getPackageLPr(component.getPackageName()), callingUid, + component, TYPE_UNKNOWN, userId)) { + return COMPONENT_ENABLED_STATE_DISABLED; + } + return mSettings.getComponentEnabledSettingLPr(component, userId); } } |