From 7cdcdaae7627e4708076b759800132435dbfcc6e Mon Sep 17 00:00:00 2001 From: Nan Wu Date: Thu, 26 Sep 2024 18:11:48 +0000 Subject: ChooserActivity refreshes creator token ChooserActivity has to refresh creator tokens for the intent it launches. Bug: 369856138 Test: Manual test Flag: android.security.prevent_intent_redirect Change-Id: I1874c2197577939ee60c4c058366ba8c7aac23ca --- .../intentresolver/chooser/DisplayResolveInfo.java | 2 ++ .../intentresolver/chooser/SelectableTargetInfo.java | 1 + .../android/intentresolver/chooser/TargetInfo.java | 20 ++++++++++++++++++++ 3 files changed, 23 insertions(+) (limited to 'java/src/com') diff --git a/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java b/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java index f0674a27..e641944e 100644 --- a/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java +++ b/java/src/com/android/intentresolver/chooser/DisplayResolveInfo.java @@ -205,6 +205,7 @@ public class DisplayResolveInfo implements TargetInfo { @Override public boolean startAsCaller(Activity activity, Bundle options, int userId) { TargetInfo.prepareIntentForCrossProfileLaunch(mResolvedIntent, userId); + TargetInfo.refreshIntentCreatorToken(mResolvedIntent); activity.startActivityAsCaller(mResolvedIntent, options, false, userId); return true; } @@ -212,6 +213,7 @@ public class DisplayResolveInfo implements TargetInfo { @Override public boolean startAsUser(Activity activity, Bundle options, UserHandle user) { TargetInfo.prepareIntentForCrossProfileLaunch(mResolvedIntent, user.getIdentifier()); + TargetInfo.refreshIntentCreatorToken(mResolvedIntent); // TODO: is this equivalent to `startActivityAsCaller` with `ignoreTargetSecurity=true`? If // so, we can consolidate on the one API method to show that this flag is the only // distinction between `startAsCaller` and `startAsUser`. We can even bake that flag into diff --git a/java/src/com/android/intentresolver/chooser/SelectableTargetInfo.java b/java/src/com/android/intentresolver/chooser/SelectableTargetInfo.java index c4aa9021..2658f3e5 100644 --- a/java/src/com/android/intentresolver/chooser/SelectableTargetInfo.java +++ b/java/src/com/android/intentresolver/chooser/SelectableTargetInfo.java @@ -229,6 +229,7 @@ public final class SelectableTargetInfo extends ChooserTargetInfo { intent.setComponent(getChooserTargetComponentName()); intent.putExtras(mChooserTargetIntentExtras); 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 where we got the diff --git a/java/src/com/android/intentresolver/chooser/TargetInfo.java b/java/src/com/android/intentresolver/chooser/TargetInfo.java index e5f40001..0935c6e8 100644 --- a/java/src/com/android/intentresolver/chooser/TargetInfo.java +++ b/java/src/com/android/intentresolver/chooser/TargetInfo.java @@ -17,7 +17,10 @@ package com.android.intentresolver.chooser; +import static android.security.Flags.preventIntentRedirect; + import android.app.Activity; +import android.app.ActivityManager; import android.app.prediction.AppTarget; import android.content.ComponentName; import android.content.Context; @@ -28,6 +31,7 @@ import android.content.pm.ShortcutInfo; import android.content.pm.ShortcutManager; import android.graphics.drawable.Drawable; import android.os.Bundle; +import android.os.RemoteException; import android.os.UserHandle; import android.service.chooser.ChooserTarget; import android.text.TextUtils; @@ -462,6 +466,22 @@ public interface TargetInfo { } } + /** + * 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); + } + } + /** * Derive a "complete" intent from a proposed `refinement` intent by merging it into a matching * `base` intent, without modifying the filter-equality properties of the `base` intent, while -- cgit v1.2.3-59-g8ed1b