From c69aa1be70009c10e76196f71023f229cc667b7a Mon Sep 17 00:00:00 2001 From: Kunal Malhotra Date: Tue, 12 Jul 2022 22:28:45 +0000 Subject: Restrict readability of uid state changes so that uid states of other users uids are not exposed to those that do not have permission. Test: manual test Bug: 217934898 Change-Id: I3f52d4ca32c22c54fa9b1663954a43b44d9000a0 --- data/etc/platform.xml | 3 ++- .../com/android/server/am/UidObserverController.java | 16 ++++++++++++++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/data/etc/platform.xml b/data/etc/platform.xml index 6897c01844a8..9a1b8a90dbfd 100644 --- a/data/etc/platform.xml +++ b/data/etc/platform.xml @@ -171,10 +171,11 @@ - + + diff --git a/services/core/java/com/android/server/am/UidObserverController.java b/services/core/java/com/android/server/am/UidObserverController.java index e8c1b545eb96..51cb9878c0b3 100644 --- a/services/core/java/com/android/server/am/UidObserverController.java +++ b/services/core/java/com/android/server/am/UidObserverController.java @@ -15,6 +15,7 @@ */ package com.android.server.am; +import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL; import static android.app.ActivityManager.PROCESS_STATE_NONEXISTENT; import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS; @@ -25,6 +26,7 @@ import android.annotation.Nullable; import android.app.ActivityManager; import android.app.ActivityManagerProto; import android.app.IUidObserver; +import android.content.pm.PackageManager; import android.os.Handler; import android.os.RemoteCallbackList; import android.os.RemoteException; @@ -81,7 +83,9 @@ public class UidObserverController { @NonNull String callingPackage, int callingUid) { synchronized (mLock) { mUidObservers.register(observer, new UidObserverRegistration(callingUid, - callingPackage, which, cutpoint)); + callingPackage, which, cutpoint, + ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, callingUid) + == PackageManager.PERMISSION_GRANTED)); } } @@ -252,6 +256,11 @@ public class UidObserverController { final ChangeRecord item = mActiveUidChanges[j]; final long start = SystemClock.uptimeMillis(); final int change = item.change; + // Does the user have permission? Don't send a non user UID change otherwise + if (UserHandle.getUserId(item.uid) != UserHandle.getUserId(reg.mUid) + && !reg.mCanInteractAcrossUsers) { + continue; + } if (change == UidRecord.CHANGE_PROCSTATE && (reg.mWhich & ActivityManager.UID_OBSERVER_PROCSTATE) == 0) { // No-op common case: no significant change, the observer is not @@ -437,6 +446,7 @@ public class UidObserverController { private final String mPkg; private final int mWhich; private final int mCutpoint; + private final boolean mCanInteractAcrossUsers; /** * Total # of callback calls that took more than {@link #SLOW_UID_OBSERVER_THRESHOLD_MS}. @@ -467,11 +477,13 @@ public class UidObserverController { ActivityManagerProto.UID_OBSERVER_FLAG_PROC_OOM_ADJ, }; - UidObserverRegistration(int uid, @NonNull String pkg, int which, int cutpoint) { + UidObserverRegistration(int uid, @NonNull String pkg, int which, int cutpoint, + boolean canInteractAcrossUsers) { this.mUid = uid; this.mPkg = pkg; this.mWhich = which; this.mCutpoint = cutpoint; + this.mCanInteractAcrossUsers = canInteractAcrossUsers; mLastProcStates = cutpoint >= ActivityManager.MIN_PROCESS_STATE ? new SparseIntArray() : null; } -- cgit v1.2.3-59-g8ed1b