From bc817f1eff9889292bd2b3cad4d4eed56a9a4830 Mon Sep 17 00:00:00 2001 From: Riddle Hsu Date: Fri, 27 Aug 2021 20:58:53 +0800 Subject: [PATCH] Provide referrer package with respect to package visibility Otherwise the app can easily get the caller package name by Activity#getReferrer() with removing intent extra or use reflection to get Activity#mReferrer directly. Bug: 191954233 Test: atest ActivityTaskSupervisorTests#testFilteredReferred Change-Id: I59bfa69ae19e3bec8d9619fbdae3626675fb0d26 --- .../com/android/server/wm/ActivityRecord.java | 15 ++++++++++++- .../server/wm/ActivityTaskSupervisor.java | 6 +++--- .../wm/ActivityTaskSupervisorTests.java | 21 +++++++++++++++++++ .../android/server/wm/WindowTestsBase.java | 7 +++++++ 4 files changed, 45 insertions(+), 4 deletions(-) diff --git a/services/core/java/com/android/server/wm/ActivityRecord.java b/services/core/java/com/android/server/wm/ActivityRecord.java index c2cfe0b7bd927..d13c8ba96d487 100644 --- a/services/core/java/com/android/server/wm/ActivityRecord.java +++ b/services/core/java/com/android/server/wm/ActivityRecord.java @@ -4148,7 +4148,7 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A // The activity now gets access to the data associated with this Intent. mAtmService.mUgmInternal.grantUriPermissionUncheckedFromIntent(intentGrants, getUriPermissionsLocked()); - final ReferrerIntent rintent = new ReferrerIntent(intent, referrer); + final ReferrerIntent rintent = new ReferrerIntent(intent, getFilteredReferrer(referrer)); boolean unsent = true; final boolean isTopActivityWhileSleeping = isTopRunningActivity() && isSleeping(); @@ -8504,6 +8504,19 @@ final class ActivityRecord extends WindowToken implements WindowManagerService.A return launchedFromUid; } + /** + * Gets the referrer package name with respect to package visibility. This method returns null + * if the given package is not visible to this activity. + */ + String getFilteredReferrer(String referrerPackage) { + if (referrerPackage == null || (!referrerPackage.equals(packageName) + && mWmService.mPmInternal.filterAppAccess( + referrerPackage, info.applicationInfo.uid, mUserId))) { + return null; + } + return referrerPackage; + } + /** * Determines whether this ActivityRecord can turn the screen on. It checks whether the flag * {@link ActivityRecord#getTurnScreenOnFlag} is set and checks whether the ActivityRecord diff --git a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java index e3459a1edc0f5..efa67e934543f 100644 --- a/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java +++ b/services/core/java/com/android/server/wm/ActivityTaskSupervisor.java @@ -848,9 +848,9 @@ public class ActivityTaskSupervisor implements RecentTasks.Callbacks { // and override configs. mergedConfiguration.getGlobalConfiguration(), mergedConfiguration.getOverrideConfiguration(), r.compat, - r.launchedFromPackage, task.voiceInteractor, proc.getReportedProcState(), - r.getSavedState(), r.getPersistentSavedState(), results, newIntents, - r.takeOptions(), isTransitionForward, + r.getFilteredReferrer(r.launchedFromPackage), task.voiceInteractor, + proc.getReportedProcState(), r.getSavedState(), r.getPersistentSavedState(), + results, newIntents, r.takeOptions(), isTransitionForward, proc.createProfilerInfoIfNeeded(), r.assistToken, activityClientController, r.createFixedRotationAdjustmentsIfNeeded(), r.shareableActivityToken, r.getLaunchedFromBubble())); diff --git a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java index 0d177c14427b8..19f9b758811fc 100644 --- a/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java +++ b/services/tests/wmtests/src/com/android/server/wm/ActivityTaskSupervisorTests.java @@ -30,6 +30,7 @@ import static com.google.common.truth.Truth.assertThat; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import static org.mockito.ArgumentMatchers.anyInt; @@ -40,8 +41,10 @@ import static org.mockito.Mockito.timeout; import android.app.WaitResult; import android.content.ComponentName; +import android.content.Intent; import android.content.pm.ActivityInfo; import android.os.ConditionVariable; +import android.os.RemoteException; import android.platform.test.annotations.Presubmit; import android.view.Display; @@ -187,6 +190,24 @@ public class ActivityTaskSupervisorTests extends WindowTestsBase { verify(taskChangeNotifier, never()).notifyActivityDismissingDockedRootTask(); } + /** Ensures that the calling package name passed to client complies with package visibility. */ + @Test + public void testFilteredReferred() { + final ActivityRecord activity = new ActivityBuilder(mAtm) + .setLaunchedFromPackage("other.package").setCreateTask(true).build(); + assertNotNull(activity.launchedFromPackage); + try { + mSupervisor.realStartActivityLocked(activity, activity.app, false /* andResume */, + false /* checkConfig */); + } catch (RemoteException ignored) { + } + verify(activity).getFilteredReferrer(eq(activity.launchedFromPackage)); + + activity.deliverNewIntentLocked(ActivityBuilder.DEFAULT_FAKE_UID, + new Intent(), null /* intentGrants */, "other.package2"); + verify(activity).getFilteredReferrer(eq("other.package2")); + } + /** * Ensures that notify focus task changes. */ diff --git a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java index 588089996d6c8..611b3f5e62a52 100644 --- a/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java +++ b/services/tests/wmtests/src/com/android/server/wm/WindowTestsBase.java @@ -801,6 +801,7 @@ class WindowTestsBase extends SystemServiceTestsBase { private int mConfigChanges; private int mLaunchedFromPid; private int mLaunchedFromUid; + private String mLaunchedFromPackage; private WindowProcessController mWpc; private Bundle mIntentExtras; private boolean mOnTop = false; @@ -911,6 +912,11 @@ class WindowTestsBase extends SystemServiceTestsBase { return this; } + ActivityBuilder setLaunchedFromPackage(String packageName) { + mLaunchedFromPackage = packageName; + return this; + } + ActivityBuilder setUseProcess(WindowProcessController wpc) { mWpc = wpc; return this; @@ -1000,6 +1006,7 @@ class WindowTestsBase extends SystemServiceTestsBase { final ActivityRecord activity = new ActivityRecord.Builder(mService) .setLaunchedFromPid(mLaunchedFromPid) .setLaunchedFromUid(mLaunchedFromUid) + .setLaunchedFromPackage(mLaunchedFromPackage) .setIntent(intent) .setActivityInfo(aInfo) .setActivityOptions(options)