Loading services/core/java/com/android/server/IntentResolver.java +6 −2 Original line number Diff line number Diff line Loading @@ -81,7 +81,7 @@ public abstract class IntentResolver<F, R extends Object> { * Returns whether an intent matches the IntentFilter with a pre-resolved type. */ public static boolean intentMatchesFilter( IntentFilter filter, Intent intent, String resolvedType) { IntentFilter filter, Intent intent, String resolvedType, boolean defaultOnly) { final boolean debug = localLOGV || ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); Loading @@ -94,9 +94,13 @@ public abstract class IntentResolver<F, R extends Object> { filter.dump(logPrinter, " "); } final int match = filter.match(intent.getAction(), resolvedType, intent.getScheme(), int match = filter.match(intent.getAction(), resolvedType, intent.getScheme(), intent.getData(), intent.getCategories(), TAG); if (match >= 0 && defaultOnly && !filter.hasCategory(Intent.CATEGORY_DEFAULT)) { match = IntentFilter.NO_MATCH_CATEGORY; } if (match >= 0) { if (debug) { Slog.v(TAG, "Filter matched! match=0x" + Integer.toHexString(match)); Loading services/core/java/com/android/server/compat/PlatformCompat.java +20 −10 Original line number Diff line number Diff line Loading @@ -150,16 +150,7 @@ public class PlatformCompat extends IPlatformCompat.Stub { public boolean isChangeEnabledByUid(long changeId, int uid) { super.isChangeEnabledByUid_enforcePermission(); String[] packages = mContext.getPackageManager().getPackagesForUid(uid); if (packages == null || packages.length == 0) { return mCompatConfig.defaultChangeIdValue(changeId); } boolean enabled = true; for (String packageName : packages) { enabled &= isChangeEnabledByPackageName(changeId, packageName, UserHandle.getUserId(uid)); } return enabled; return isChangeEnabledByUidInternal(changeId, uid); } /** Loading Loading @@ -208,6 +199,25 @@ public class PlatformCompat extends IPlatformCompat.Stub { return false; } /** * Internal version of {@link #isChangeEnabledByUid(long, int)}. * * <p>Does not perform costly permission check. */ public boolean isChangeEnabledByUidInternal(long changeId, int uid) { String[] packages = mContext.getPackageManager().getPackagesForUid(uid); if (packages == null || packages.length == 0) { return mCompatConfig.defaultChangeIdValue(changeId); } boolean enabled = true; final int userId = UserHandle.getUserId(uid); for (String packageName : packages) { final var appInfo = getApplicationInfo(packageName, userId); enabled &= isChangeEnabledInternal(changeId, appInfo); } return enabled; } @Override @EnforcePermission(OVERRIDE_COMPAT_CHANGE_CONFIG) public void setOverrides(CompatibilityChangeConfig overrides, String packageName) { Loading services/core/java/com/android/server/pm/ComputerEngine.java +4 −4 Original line number Diff line number Diff line Loading @@ -580,7 +580,7 @@ public class ComputerEngine implements Computer { list.add(ri); PackageManagerServiceUtils.applyEnforceIntentFilterMatching( mInjector.getCompatibility(), mComponentResolver, list, false, intent, resolvedType, filterCallingUid); list, false, intent, resolvedType, flags, filterCallingUid); } } } else { Loading Loading @@ -610,7 +610,7 @@ public class ComputerEngine implements Computer { // We also have to ensure all components match the original intent PackageManagerServiceUtils.applyEnforceIntentFilterMatching( mInjector.getCompatibility(), mComponentResolver, list, false, originalIntent, resolvedType, filterCallingUid); list, false, originalIntent, resolvedType, flags, filterCallingUid); } return skipPostResolution ? list : applyPostResolutionFilter( Loading Loading @@ -699,7 +699,7 @@ public class ComputerEngine implements Computer { list.add(ri); PackageManagerServiceUtils.applyEnforceIntentFilterMatching( mInjector.getCompatibility(), mComponentResolver, list, false, intent, resolvedType, callingUid); list, false, intent, resolvedType, flags, callingUid); } } } else { Loading @@ -711,7 +711,7 @@ public class ComputerEngine implements Computer { // We also have to ensure all components match the original intent PackageManagerServiceUtils.applyEnforceIntentFilterMatching( mInjector.getCompatibility(), mComponentResolver, list, false, originalIntent, resolvedType, callingUid); list, false, originalIntent, resolvedType, flags, callingUid); } return list; Loading services/core/java/com/android/server/pm/PackageManagerServiceUtils.java +21 −12 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.annotation.UserIdInt; import android.app.ActivityManager; import android.compat.annotation.ChangeId; import android.compat.annotation.Disabled; import android.compat.annotation.Overridable; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; Loading @@ -69,6 +70,7 @@ import android.os.Environment; import android.os.FileUtils; import android.os.Process; import android.os.SystemProperties; import android.os.UserHandle; import android.os.incremental.IncrementalManager; import android.os.incremental.IncrementalStorage; import android.os.incremental.V4Signature; Loading Loading @@ -180,8 +182,9 @@ public class PackageManagerServiceUtils { public @interface SharedUserIdJoinType {} /** * Components of apps targeting Android T and above will stop receiving intents from * external callers that do not match its declared intent filters. * Intents sent from apps targeting Android V and above will stop resolving to components with * non matching intent filters, even when explicitly setting a component name, unless the * target components are in the same app as the calling app. * * When an app registers an exported component in its manifest and adds an <intent-filter>, * the component can be started by any intent - even those that do not match the intent filter. Loading @@ -189,8 +192,9 @@ public class PackageManagerServiceUtils { * Without checking the intent when the component is started, in some circumstances this can * allow 3P apps to trigger internal-only functionality. */ @Overridable @ChangeId @Disabled /* Revert enforcement: b/274147456 */ @Disabled /* Enforcement reverted in T: b/274147456 */ private static final long ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS = 161252188; /** Loading Loading @@ -1187,19 +1191,27 @@ public class PackageManagerServiceUtils { public static void applyEnforceIntentFilterMatching( PlatformCompat compat, ComponentResolverApi resolver, List<ResolveInfo> resolveInfos, boolean isReceiver, Intent intent, String resolvedType, int filterCallingUid) { Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int filterCallingUid) { if (DISABLE_ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS.get()) return; // Do not enforce filter matching when the caller is system or root if (ActivityManager.canAccessUnexportedComponents(filterCallingUid)) return; final Printer logPrinter = DEBUG_INTENT_MATCHING ? new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM) : null; final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; final boolean enforce = compat.isChangeEnabledByUidInternal( ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS, filterCallingUid); for (int i = resolveInfos.size() - 1; i >= 0; --i) { final ComponentInfo info = resolveInfos.get(i).getComponentInfo(); // Do not enforce filter matching when the caller is system, root, or the same app if (ActivityManager.checkComponentPermission(null, filterCallingUid, info.applicationInfo.uid, false) == PackageManager.PERMISSION_GRANTED) { // Skip filter matching when the caller is targeting the same app if (UserHandle.isSameApp(filterCallingUid, info.applicationInfo.uid)) { continue; } Loading @@ -1221,14 +1233,11 @@ public class PackageManagerServiceUtils { continue; } // Only enforce filter matching if target app's target SDK >= T final boolean enforce = compat.isChangeEnabledInternal( ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS, info.applicationInfo); boolean match = false; for (int j = 0, size = comp.getIntents().size(); j < size; ++j) { IntentFilter intentFilter = comp.getIntents().get(j).getIntentFilter(); if (IntentResolver.intentMatchesFilter(intentFilter, intent, resolvedType)) { if (IntentResolver.intentMatchesFilter( intentFilter, intent, resolvedType, defaultOnly)) { match = true; break; } Loading services/core/java/com/android/server/pm/ResolveIntentHelper.java +2 −2 Original line number Diff line number Diff line Loading @@ -459,7 +459,7 @@ final class ResolveIntentHelper { list.add(ri); PackageManagerServiceUtils.applyEnforceIntentFilterMatching( mPlatformCompat, componentResolver, list, true, intent, resolvedType, filterCallingUid); resolvedType, flags, filterCallingUid); } } } else { Loading @@ -485,7 +485,7 @@ final class ResolveIntentHelper { // We also have to ensure all components match the original intent PackageManagerServiceUtils.applyEnforceIntentFilterMatching( mPlatformCompat, componentResolver, list, true, originalIntent, resolvedType, filterCallingUid); list, true, originalIntent, resolvedType, flags, filterCallingUid); } return computer.applyPostResolutionFilter(list, instantAppPkgName, false, queryingUid, Loading Loading
services/core/java/com/android/server/IntentResolver.java +6 −2 Original line number Diff line number Diff line Loading @@ -81,7 +81,7 @@ public abstract class IntentResolver<F, R extends Object> { * Returns whether an intent matches the IntentFilter with a pre-resolved type. */ public static boolean intentMatchesFilter( IntentFilter filter, Intent intent, String resolvedType) { IntentFilter filter, Intent intent, String resolvedType, boolean defaultOnly) { final boolean debug = localLOGV || ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0); Loading @@ -94,9 +94,13 @@ public abstract class IntentResolver<F, R extends Object> { filter.dump(logPrinter, " "); } final int match = filter.match(intent.getAction(), resolvedType, intent.getScheme(), int match = filter.match(intent.getAction(), resolvedType, intent.getScheme(), intent.getData(), intent.getCategories(), TAG); if (match >= 0 && defaultOnly && !filter.hasCategory(Intent.CATEGORY_DEFAULT)) { match = IntentFilter.NO_MATCH_CATEGORY; } if (match >= 0) { if (debug) { Slog.v(TAG, "Filter matched! match=0x" + Integer.toHexString(match)); Loading
services/core/java/com/android/server/compat/PlatformCompat.java +20 −10 Original line number Diff line number Diff line Loading @@ -150,16 +150,7 @@ public class PlatformCompat extends IPlatformCompat.Stub { public boolean isChangeEnabledByUid(long changeId, int uid) { super.isChangeEnabledByUid_enforcePermission(); String[] packages = mContext.getPackageManager().getPackagesForUid(uid); if (packages == null || packages.length == 0) { return mCompatConfig.defaultChangeIdValue(changeId); } boolean enabled = true; for (String packageName : packages) { enabled &= isChangeEnabledByPackageName(changeId, packageName, UserHandle.getUserId(uid)); } return enabled; return isChangeEnabledByUidInternal(changeId, uid); } /** Loading Loading @@ -208,6 +199,25 @@ public class PlatformCompat extends IPlatformCompat.Stub { return false; } /** * Internal version of {@link #isChangeEnabledByUid(long, int)}. * * <p>Does not perform costly permission check. */ public boolean isChangeEnabledByUidInternal(long changeId, int uid) { String[] packages = mContext.getPackageManager().getPackagesForUid(uid); if (packages == null || packages.length == 0) { return mCompatConfig.defaultChangeIdValue(changeId); } boolean enabled = true; final int userId = UserHandle.getUserId(uid); for (String packageName : packages) { final var appInfo = getApplicationInfo(packageName, userId); enabled &= isChangeEnabledInternal(changeId, appInfo); } return enabled; } @Override @EnforcePermission(OVERRIDE_COMPAT_CHANGE_CONFIG) public void setOverrides(CompatibilityChangeConfig overrides, String packageName) { Loading
services/core/java/com/android/server/pm/ComputerEngine.java +4 −4 Original line number Diff line number Diff line Loading @@ -580,7 +580,7 @@ public class ComputerEngine implements Computer { list.add(ri); PackageManagerServiceUtils.applyEnforceIntentFilterMatching( mInjector.getCompatibility(), mComponentResolver, list, false, intent, resolvedType, filterCallingUid); list, false, intent, resolvedType, flags, filterCallingUid); } } } else { Loading Loading @@ -610,7 +610,7 @@ public class ComputerEngine implements Computer { // We also have to ensure all components match the original intent PackageManagerServiceUtils.applyEnforceIntentFilterMatching( mInjector.getCompatibility(), mComponentResolver, list, false, originalIntent, resolvedType, filterCallingUid); list, false, originalIntent, resolvedType, flags, filterCallingUid); } return skipPostResolution ? list : applyPostResolutionFilter( Loading Loading @@ -699,7 +699,7 @@ public class ComputerEngine implements Computer { list.add(ri); PackageManagerServiceUtils.applyEnforceIntentFilterMatching( mInjector.getCompatibility(), mComponentResolver, list, false, intent, resolvedType, callingUid); list, false, intent, resolvedType, flags, callingUid); } } } else { Loading @@ -711,7 +711,7 @@ public class ComputerEngine implements Computer { // We also have to ensure all components match the original intent PackageManagerServiceUtils.applyEnforceIntentFilterMatching( mInjector.getCompatibility(), mComponentResolver, list, false, originalIntent, resolvedType, callingUid); list, false, originalIntent, resolvedType, flags, callingUid); } return list; Loading
services/core/java/com/android/server/pm/PackageManagerServiceUtils.java +21 −12 Original line number Diff line number Diff line Loading @@ -44,6 +44,7 @@ import android.annotation.UserIdInt; import android.app.ActivityManager; import android.compat.annotation.ChangeId; import android.compat.annotation.Disabled; import android.compat.annotation.Overridable; import android.content.Context; import android.content.Intent; import android.content.IntentFilter; Loading @@ -69,6 +70,7 @@ import android.os.Environment; import android.os.FileUtils; import android.os.Process; import android.os.SystemProperties; import android.os.UserHandle; import android.os.incremental.IncrementalManager; import android.os.incremental.IncrementalStorage; import android.os.incremental.V4Signature; Loading Loading @@ -180,8 +182,9 @@ public class PackageManagerServiceUtils { public @interface SharedUserIdJoinType {} /** * Components of apps targeting Android T and above will stop receiving intents from * external callers that do not match its declared intent filters. * Intents sent from apps targeting Android V and above will stop resolving to components with * non matching intent filters, even when explicitly setting a component name, unless the * target components are in the same app as the calling app. * * When an app registers an exported component in its manifest and adds an <intent-filter>, * the component can be started by any intent - even those that do not match the intent filter. Loading @@ -189,8 +192,9 @@ public class PackageManagerServiceUtils { * Without checking the intent when the component is started, in some circumstances this can * allow 3P apps to trigger internal-only functionality. */ @Overridable @ChangeId @Disabled /* Revert enforcement: b/274147456 */ @Disabled /* Enforcement reverted in T: b/274147456 */ private static final long ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS = 161252188; /** Loading Loading @@ -1187,19 +1191,27 @@ public class PackageManagerServiceUtils { public static void applyEnforceIntentFilterMatching( PlatformCompat compat, ComponentResolverApi resolver, List<ResolveInfo> resolveInfos, boolean isReceiver, Intent intent, String resolvedType, int filterCallingUid) { Intent intent, String resolvedType, @PackageManager.ResolveInfoFlagsBits long flags, int filterCallingUid) { if (DISABLE_ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS.get()) return; // Do not enforce filter matching when the caller is system or root if (ActivityManager.canAccessUnexportedComponents(filterCallingUid)) return; final Printer logPrinter = DEBUG_INTENT_MATCHING ? new LogPrinter(Log.VERBOSE, TAG, Log.LOG_ID_SYSTEM) : null; final boolean defaultOnly = (flags & PackageManager.MATCH_DEFAULT_ONLY) != 0; final boolean enforce = compat.isChangeEnabledByUidInternal( ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS, filterCallingUid); for (int i = resolveInfos.size() - 1; i >= 0; --i) { final ComponentInfo info = resolveInfos.get(i).getComponentInfo(); // Do not enforce filter matching when the caller is system, root, or the same app if (ActivityManager.checkComponentPermission(null, filterCallingUid, info.applicationInfo.uid, false) == PackageManager.PERMISSION_GRANTED) { // Skip filter matching when the caller is targeting the same app if (UserHandle.isSameApp(filterCallingUid, info.applicationInfo.uid)) { continue; } Loading @@ -1221,14 +1233,11 @@ public class PackageManagerServiceUtils { continue; } // Only enforce filter matching if target app's target SDK >= T final boolean enforce = compat.isChangeEnabledInternal( ENFORCE_INTENTS_TO_MATCH_INTENT_FILTERS, info.applicationInfo); boolean match = false; for (int j = 0, size = comp.getIntents().size(); j < size; ++j) { IntentFilter intentFilter = comp.getIntents().get(j).getIntentFilter(); if (IntentResolver.intentMatchesFilter(intentFilter, intent, resolvedType)) { if (IntentResolver.intentMatchesFilter( intentFilter, intent, resolvedType, defaultOnly)) { match = true; break; } Loading
services/core/java/com/android/server/pm/ResolveIntentHelper.java +2 −2 Original line number Diff line number Diff line Loading @@ -459,7 +459,7 @@ final class ResolveIntentHelper { list.add(ri); PackageManagerServiceUtils.applyEnforceIntentFilterMatching( mPlatformCompat, componentResolver, list, true, intent, resolvedType, filterCallingUid); resolvedType, flags, filterCallingUid); } } } else { Loading @@ -485,7 +485,7 @@ final class ResolveIntentHelper { // We also have to ensure all components match the original intent PackageManagerServiceUtils.applyEnforceIntentFilterMatching( mPlatformCompat, componentResolver, list, true, originalIntent, resolvedType, filterCallingUid); list, true, originalIntent, resolvedType, flags, filterCallingUid); } return computer.applyPostResolutionFilter(list, instantAppPkgName, false, queryingUid, Loading