diff options
author | 2024-11-26 01:32:19 +0000 | |
---|---|---|
committer | 2024-12-02 17:46:11 +0000 | |
commit | 3bd17cdcd467b054a97256a719df5545f2141d7f (patch) | |
tree | c71274f0b7671e8f077614c19c236c10d553dc21 | |
parent | 50201ffc6aae71f5a41d153748d9bd4c890ebdd1 (diff) |
ResolverActivity and IntentForwarderActivity refreshes token
These 2 Activiies are still in use and have to refresh creator
tokens before they launch the intents.
Bug: 369856138
Test: Manual test
Flag: android.security.prevent_intent_redirect
Change-Id: I4df6849bec9a1c10e92ce6c452ec3989780ef510
4 files changed, 28 insertions, 0 deletions
diff --git a/core/java/com/android/internal/app/IntentForwarderActivity.java b/core/java/com/android/internal/app/IntentForwarderActivity.java index ee5bd65e76de..644d69919998 100644 --- a/core/java/com/android/internal/app/IntentForwarderActivity.java +++ b/core/java/com/android/internal/app/IntentForwarderActivity.java @@ -70,6 +70,7 @@ import android.widget.Toast; import com.android.internal.R; import com.android.internal.annotations.VisibleForTesting; +import com.android.internal.app.chooser.TargetInfo; import com.android.internal.logging.MetricsLogger; import com.android.internal.logging.nano.MetricsProto.MetricsEvent; @@ -352,6 +353,7 @@ public class IntentForwarderActivity extends Activity { findViewById(R.id.use_same_profile_browser).setOnClickListener(v -> finish()); findViewById(R.id.button_open).setOnClickListener(v -> { + TargetInfo.refreshIntentCreatorToken(launchIntent); startActivityAsCaller( launchIntent, ActivityOptions.makeCustomAnimation( @@ -476,6 +478,7 @@ public class IntentForwarderActivity extends Activity { private void startActivityAsCaller(Intent newIntent, int userId) { try { + TargetInfo.refreshIntentCreatorToken(newIntent); startActivityAsCaller( newIntent, /* options= */ null, @@ -502,6 +505,7 @@ public class IntentForwarderActivity extends Activity { return; } sanitizeIntent(innerIntent); + TargetInfo.refreshIntentCreatorToken(intentReceived); startActivityAsCaller(intentReceived, null, false, getUserId()); finish(); } @@ -525,6 +529,7 @@ public class IntentForwarderActivity extends Activity { if (singleTabOnly) { intentReceived.putExtra(EXTRA_RESTRICT_TO_SINGLE_USER, true); } + TargetInfo.refreshIntentCreatorToken(intentReceived); startActivityAsCaller(intentReceived, null, false, userId); finish(); } diff --git a/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java b/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java index 473134ea46f3..0c650774105e 100644 --- a/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java +++ b/core/java/com/android/internal/app/chooser/DisplayResolveInfo.java @@ -173,6 +173,7 @@ public class DisplayResolveInfo implements TargetInfo, Parcelable { @Override public boolean startAsCaller(ResolverActivity activity, Bundle options, int userId) { TargetInfo.prepareIntentForCrossProfileLaunch(mResolvedIntent, userId); + TargetInfo.refreshIntentCreatorToken(mResolvedIntent); activity.startActivityAsCaller(mResolvedIntent, options, false, userId); return true; } @@ -180,6 +181,7 @@ public class DisplayResolveInfo implements TargetInfo, Parcelable { @Override public boolean startAsUser(Activity activity, Bundle options, UserHandle user) { TargetInfo.prepareIntentForCrossProfileLaunch(mResolvedIntent, user.getIdentifier()); + TargetInfo.refreshIntentCreatorToken(mResolvedIntent); activity.startActivityAsUser(mResolvedIntent, options, user); return false; } diff --git a/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java b/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java index d7f3a76c61e0..0eaa43d2c6e8 100644 --- a/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java +++ b/core/java/com/android/internal/app/chooser/SelectableTargetInfo.java @@ -260,6 +260,7 @@ public final class SelectableTargetInfo implements ChooserTargetInfo { intent.setComponent(mChooserTarget.getComponentName()); intent.putExtras(mChooserTarget.getIntentExtras()); TargetInfo.prepareIntentForCrossProfileLaunch(intent, userId); + TargetInfo.refreshIntentCreatorToken(intent); // Important: we will ignore the target security checks in ActivityManager // if and only if the ChooserTarget's target package is the same package diff --git a/core/java/com/android/internal/app/chooser/TargetInfo.java b/core/java/com/android/internal/app/chooser/TargetInfo.java index 7bb7ddc65c6d..fcf5883cc84b 100644 --- a/core/java/com/android/internal/app/chooser/TargetInfo.java +++ b/core/java/com/android/internal/app/chooser/TargetInfo.java @@ -17,13 +17,17 @@ package com.android.internal.app.chooser; +import static android.security.Flags.preventIntentRedirect; + import android.app.Activity; +import android.app.ActivityManager; import android.content.ComponentName; import android.content.Context; import android.content.Intent; import android.content.pm.ResolveInfo; import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.os.RemoteException; import android.os.UserHandle; import com.android.internal.app.ResolverActivity; @@ -141,4 +145,20 @@ public interface TargetInfo { intent.fixUris(currentUserId); } } + + /** + * refreshes intent's creatorToken with its current intent key fields. This allows + * ChooserActivity to still keep original creatorToken's creator uid after making changes to + * the intent and still keep it valid. + * @param intent the intent's creatorToken needs to up refreshed. + */ + static void refreshIntentCreatorToken(Intent intent) { + if (!preventIntentRedirect()) return; + try { + intent.setCreatorToken(ActivityManager.getService().refreshIntentCreatorToken( + intent.cloneForCreatorToken())); + } catch (RemoteException e) { + throw new RuntimeException("Failure from system", e); + } + } } |