Loading core/java/android/security/responsible_apis_flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,14 @@ flag { bug: "361143368" } flag { name: "prevent_intent_redirect_show_toast" namespace: "responsible_apis" description: "Prevent intent redirect attacks by showing a toast when activity start is blocked" bug: "361143368" is_fixed_read_only: true } flag { name: "enable_intent_matching_flags" is_exported: true Loading services/core/java/com/android/server/wm/ActivityStartController.java +1 −1 Original line number Diff line number Diff line Loading @@ -478,7 +478,7 @@ public class ActivityStartController { intentGrants.merge(creatorIntentGrants); } } catch (SecurityException securityException) { ActivityStarter.logAndThrowExceptionForIntentRedirect( ActivityStarter.logAndThrowExceptionForIntentRedirect(mService.mContext, "Creator URI Grant Caused Exception.", intent, creatorUid, creatorPackage, filterCallingUid, callingPackage, securityException); Loading services/core/java/com/android/server/wm/ActivityStarter.java +30 −13 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP; import static android.content.pm.ActivityInfo.launchModeToString; import static android.os.Process.INVALID_UID; import static android.security.Flags.preventIntentRedirectAbortOrThrowException; import static android.security.Flags.preventIntentRedirectShowToast; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.TRANSIT_NONE; import static android.view.WindowManager.TRANSIT_OPEN; Loading Loading @@ -105,6 +106,7 @@ import android.compat.annotation.ChangeId; import android.compat.annotation.Disabled; import android.compat.annotation.EnabledSince; import android.compat.annotation.Overridable; import android.content.Context; import android.content.IIntentSender; import android.content.Intent; import android.content.IntentSender; Loading @@ -128,12 +130,14 @@ import android.service.voice.IVoiceInteractionSession; import android.text.TextUtils; import android.util.Pools.SynchronizedPool; import android.util.Slog; import android.widget.Toast; import android.window.RemoteTransition; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.HeavyWeightSwitcherActivity; import com.android.internal.app.IVoiceInteractor; import com.android.internal.protolog.ProtoLog; import com.android.server.UiThread; import com.android.server.am.ActivityManagerService.IntentCreatorToken; import com.android.server.am.PendingIntentRecord; import com.android.server.pm.InstantAppResolver; Loading Loading @@ -614,7 +618,7 @@ class ActivityStarter { // Check if the Intent was redirected if ((intent.getExtendedFlags() & Intent.EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN) != 0) { ActivityStarter.logAndThrowExceptionForIntentRedirect( logAndThrowExceptionForIntentRedirect(supervisor.mService.mContext, "Unparceled intent does not have a creator token set.", intent, intentCreatorUid, intentCreatorPackage, resolvedCallingUid, resolvedCallingPackage, null); Loading Loading @@ -650,7 +654,7 @@ class ActivityStarter { intentGrants.merge(creatorIntentGrants); } } catch (SecurityException securityException) { ActivityStarter.logAndThrowExceptionForIntentRedirect( logAndThrowExceptionForIntentRedirect(supervisor.mService.mContext, "Creator URI Grant Caused Exception.", intent, intentCreatorUid, intentCreatorPackage, resolvedCallingUid, resolvedCallingPackage, securityException); Loading @@ -674,7 +678,7 @@ class ActivityStarter { intentGrants.merge(creatorIntentGrants); } } catch (SecurityException securityException) { ActivityStarter.logAndThrowExceptionForIntentRedirect( logAndThrowExceptionForIntentRedirect(supervisor.mService.mContext, "Creator URI Grant Caused Exception.", intent, intentCreatorUid, intentCreatorPackage, resolvedCallingUid, resolvedCallingPackage, securityException); Loading Loading @@ -1250,27 +1254,27 @@ class ActivityStarter { requestCode, 0, intentCreatorUid, intentCreatorPackage, "", request.ignoreTargetSecurity, inTask != null, null, resultRecord, resultRootTask)) { abort = logAndAbortForIntentRedirect( abort = logAndAbortForIntentRedirect(mService.mContext, "Creator checkStartAnyActivityPermission Caused abortion.", intent, intentCreatorUid, intentCreatorPackage, callingUid, callingPackage); } } catch (SecurityException e) { logAndThrowExceptionForIntentRedirect( logAndThrowExceptionForIntentRedirect(mService.mContext, "Creator checkStartAnyActivityPermission Caused Exception.", intent, intentCreatorUid, intentCreatorPackage, callingUid, callingPackage, e); } if (!mService.mIntentFirewall.checkStartActivity(intent, intentCreatorUid, 0, resolvedType, aInfo.applicationInfo)) { abort = logAndAbortForIntentRedirect( abort = logAndAbortForIntentRedirect(mService.mContext, "Creator IntentFirewall.checkStartActivity Caused abortion.", intent, intentCreatorUid, intentCreatorPackage, callingUid, callingPackage); } if (!mService.getPermissionPolicyInternal().checkStartActivity(intent, intentCreatorUid, intentCreatorPackage)) { abort = logAndAbortForIntentRedirect( abort = logAndAbortForIntentRedirect(mService.mContext, "Creator PermissionPolicyService.checkStartActivity Caused abortion.", intent, intentCreatorUid, intentCreatorPackage, callingUid, callingPackage); } Loading Loading @@ -3596,25 +3600,38 @@ class ActivityStarter { pw.println(mInTaskFragment); } static void logAndThrowExceptionForIntentRedirect(@NonNull String message, @NonNull Intent intent, int intentCreatorUid, @Nullable String intentCreatorPackage, int callingUid, @Nullable String callingPackage, static void logAndThrowExceptionForIntentRedirect(@NonNull Context context, @NonNull String message, @NonNull Intent intent, int intentCreatorUid, @Nullable String intentCreatorPackage, int callingUid, @Nullable String callingPackage, @Nullable SecurityException originalException) { String msg = getIntentRedirectPreventedLogMessage(message, intent, intentCreatorUid, intentCreatorPackage, callingUid, callingPackage); Slog.wtf(TAG, msg); if (preventIntentRedirectShowToast()) { UiThread.getHandler().post( () -> Toast.makeText(context, "Activity launch blocked. go/report-bug-intentRedir to report a bug", Toast.LENGTH_LONG).show()); } if (preventIntentRedirectAbortOrThrowException() && CompatChanges.isChangeEnabled( ENABLE_PREVENT_INTENT_REDIRECT_TAKE_ACTION, callingUid)) { throw new SecurityException(msg, originalException); } } private static boolean logAndAbortForIntentRedirect(@NonNull String message, @NonNull Intent intent, int intentCreatorUid, @Nullable String intentCreatorPackage, int callingUid, @Nullable String callingPackage) { private static boolean logAndAbortForIntentRedirect(@NonNull Context context, @NonNull String message, @NonNull Intent intent, int intentCreatorUid, @Nullable String intentCreatorPackage, int callingUid, @Nullable String callingPackage) { String msg = getIntentRedirectPreventedLogMessage(message, intent, intentCreatorUid, intentCreatorPackage, callingUid, callingPackage); Slog.wtf(TAG, msg); if (preventIntentRedirectShowToast()) { UiThread.getHandler().post( () -> Toast.makeText(context, "Activity launch blocked. go/report-bug-intentRedir to report a bug", Toast.LENGTH_LONG).show()); } return preventIntentRedirectAbortOrThrowException() && CompatChanges.isChangeEnabled( ENABLE_PREVENT_INTENT_REDIRECT_TAKE_ACTION, callingUid); } Loading Loading
core/java/android/security/responsible_apis_flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -86,6 +86,14 @@ flag { bug: "361143368" } flag { name: "prevent_intent_redirect_show_toast" namespace: "responsible_apis" description: "Prevent intent redirect attacks by showing a toast when activity start is blocked" bug: "361143368" is_fixed_read_only: true } flag { name: "enable_intent_matching_flags" is_exported: true Loading
services/core/java/com/android/server/wm/ActivityStartController.java +1 −1 Original line number Diff line number Diff line Loading @@ -478,7 +478,7 @@ public class ActivityStartController { intentGrants.merge(creatorIntentGrants); } } catch (SecurityException securityException) { ActivityStarter.logAndThrowExceptionForIntentRedirect( ActivityStarter.logAndThrowExceptionForIntentRedirect(mService.mContext, "Creator URI Grant Caused Exception.", intent, creatorUid, creatorPackage, filterCallingUid, callingPackage, securityException); Loading
services/core/java/com/android/server/wm/ActivityStarter.java +30 −13 Original line number Diff line number Diff line Loading @@ -55,6 +55,7 @@ import static android.content.pm.ActivityInfo.LAUNCH_SINGLE_TOP; import static android.content.pm.ActivityInfo.launchModeToString; import static android.os.Process.INVALID_UID; import static android.security.Flags.preventIntentRedirectAbortOrThrowException; import static android.security.Flags.preventIntentRedirectShowToast; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.WindowManager.TRANSIT_NONE; import static android.view.WindowManager.TRANSIT_OPEN; Loading Loading @@ -105,6 +106,7 @@ import android.compat.annotation.ChangeId; import android.compat.annotation.Disabled; import android.compat.annotation.EnabledSince; import android.compat.annotation.Overridable; import android.content.Context; import android.content.IIntentSender; import android.content.Intent; import android.content.IntentSender; Loading @@ -128,12 +130,14 @@ import android.service.voice.IVoiceInteractionSession; import android.text.TextUtils; import android.util.Pools.SynchronizedPool; import android.util.Slog; import android.widget.Toast; import android.window.RemoteTransition; import com.android.internal.annotations.VisibleForTesting; import com.android.internal.app.HeavyWeightSwitcherActivity; import com.android.internal.app.IVoiceInteractor; import com.android.internal.protolog.ProtoLog; import com.android.server.UiThread; import com.android.server.am.ActivityManagerService.IntentCreatorToken; import com.android.server.am.PendingIntentRecord; import com.android.server.pm.InstantAppResolver; Loading Loading @@ -614,7 +618,7 @@ class ActivityStarter { // Check if the Intent was redirected if ((intent.getExtendedFlags() & Intent.EXTENDED_FLAG_MISSING_CREATOR_OR_INVALID_TOKEN) != 0) { ActivityStarter.logAndThrowExceptionForIntentRedirect( logAndThrowExceptionForIntentRedirect(supervisor.mService.mContext, "Unparceled intent does not have a creator token set.", intent, intentCreatorUid, intentCreatorPackage, resolvedCallingUid, resolvedCallingPackage, null); Loading Loading @@ -650,7 +654,7 @@ class ActivityStarter { intentGrants.merge(creatorIntentGrants); } } catch (SecurityException securityException) { ActivityStarter.logAndThrowExceptionForIntentRedirect( logAndThrowExceptionForIntentRedirect(supervisor.mService.mContext, "Creator URI Grant Caused Exception.", intent, intentCreatorUid, intentCreatorPackage, resolvedCallingUid, resolvedCallingPackage, securityException); Loading @@ -674,7 +678,7 @@ class ActivityStarter { intentGrants.merge(creatorIntentGrants); } } catch (SecurityException securityException) { ActivityStarter.logAndThrowExceptionForIntentRedirect( logAndThrowExceptionForIntentRedirect(supervisor.mService.mContext, "Creator URI Grant Caused Exception.", intent, intentCreatorUid, intentCreatorPackage, resolvedCallingUid, resolvedCallingPackage, securityException); Loading Loading @@ -1250,27 +1254,27 @@ class ActivityStarter { requestCode, 0, intentCreatorUid, intentCreatorPackage, "", request.ignoreTargetSecurity, inTask != null, null, resultRecord, resultRootTask)) { abort = logAndAbortForIntentRedirect( abort = logAndAbortForIntentRedirect(mService.mContext, "Creator checkStartAnyActivityPermission Caused abortion.", intent, intentCreatorUid, intentCreatorPackage, callingUid, callingPackage); } } catch (SecurityException e) { logAndThrowExceptionForIntentRedirect( logAndThrowExceptionForIntentRedirect(mService.mContext, "Creator checkStartAnyActivityPermission Caused Exception.", intent, intentCreatorUid, intentCreatorPackage, callingUid, callingPackage, e); } if (!mService.mIntentFirewall.checkStartActivity(intent, intentCreatorUid, 0, resolvedType, aInfo.applicationInfo)) { abort = logAndAbortForIntentRedirect( abort = logAndAbortForIntentRedirect(mService.mContext, "Creator IntentFirewall.checkStartActivity Caused abortion.", intent, intentCreatorUid, intentCreatorPackage, callingUid, callingPackage); } if (!mService.getPermissionPolicyInternal().checkStartActivity(intent, intentCreatorUid, intentCreatorPackage)) { abort = logAndAbortForIntentRedirect( abort = logAndAbortForIntentRedirect(mService.mContext, "Creator PermissionPolicyService.checkStartActivity Caused abortion.", intent, intentCreatorUid, intentCreatorPackage, callingUid, callingPackage); } Loading Loading @@ -3596,25 +3600,38 @@ class ActivityStarter { pw.println(mInTaskFragment); } static void logAndThrowExceptionForIntentRedirect(@NonNull String message, @NonNull Intent intent, int intentCreatorUid, @Nullable String intentCreatorPackage, int callingUid, @Nullable String callingPackage, static void logAndThrowExceptionForIntentRedirect(@NonNull Context context, @NonNull String message, @NonNull Intent intent, int intentCreatorUid, @Nullable String intentCreatorPackage, int callingUid, @Nullable String callingPackage, @Nullable SecurityException originalException) { String msg = getIntentRedirectPreventedLogMessage(message, intent, intentCreatorUid, intentCreatorPackage, callingUid, callingPackage); Slog.wtf(TAG, msg); if (preventIntentRedirectShowToast()) { UiThread.getHandler().post( () -> Toast.makeText(context, "Activity launch blocked. go/report-bug-intentRedir to report a bug", Toast.LENGTH_LONG).show()); } if (preventIntentRedirectAbortOrThrowException() && CompatChanges.isChangeEnabled( ENABLE_PREVENT_INTENT_REDIRECT_TAKE_ACTION, callingUid)) { throw new SecurityException(msg, originalException); } } private static boolean logAndAbortForIntentRedirect(@NonNull String message, @NonNull Intent intent, int intentCreatorUid, @Nullable String intentCreatorPackage, int callingUid, @Nullable String callingPackage) { private static boolean logAndAbortForIntentRedirect(@NonNull Context context, @NonNull String message, @NonNull Intent intent, int intentCreatorUid, @Nullable String intentCreatorPackage, int callingUid, @Nullable String callingPackage) { String msg = getIntentRedirectPreventedLogMessage(message, intent, intentCreatorUid, intentCreatorPackage, callingUid, callingPackage); Slog.wtf(TAG, msg); if (preventIntentRedirectShowToast()) { UiThread.getHandler().post( () -> Toast.makeText(context, "Activity launch blocked. go/report-bug-intentRedir to report a bug", Toast.LENGTH_LONG).show()); } return preventIntentRedirectAbortOrThrowException() && CompatChanges.isChangeEnabled( ENABLE_PREVENT_INTENT_REDIRECT_TAKE_ACTION, callingUid); } Loading