diff options
4 files changed, 68 insertions, 17 deletions
diff --git a/core/java/android/app/ActivityManagerInternal.java b/core/java/android/app/ActivityManagerInternal.java index ccb54f93ba33..da9f72855e09 100644 --- a/core/java/android/app/ActivityManagerInternal.java +++ b/core/java/android/app/ActivityManagerInternal.java @@ -339,4 +339,9 @@ public abstract class ActivityManagerInternal { * Returns maximum number of users that can run simultaneously. */ public abstract int getMaxRunningUsers(); + + /** + * Returns is the caller has the same uid as the Recents component + */ + public abstract boolean isCallerRecents(int callingUid); } diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index c0c684c41bc5..00918f2ed090 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -27,9 +27,9 @@ import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS; import static android.Manifest.permission.READ_FRAME_BUFFER; import static android.Manifest.permission.REMOVE_TASKS; import static android.Manifest.permission.START_TASKS_FROM_RECENTS; -import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.app.ActivityManager.LOCK_TASK_MODE_NONE; import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW; +import static android.app.ActivityManager.SPLIT_SCREEN_CREATE_MODE_TOP_OR_LEFT; import static android.app.ActivityManager.StackId.INVALID_STACK_ID; import static android.app.ActivityManagerInternal.ASSIST_KEY_CONTENT; import static android.app.ActivityManagerInternal.ASSIST_KEY_DATA; @@ -120,6 +120,7 @@ import static android.service.voice.VoiceInteractionSession.SHOW_SOURCE_APPLICAT import static android.text.format.DateUtils.DAY_IN_MILLIS; import static android.view.Display.DEFAULT_DISPLAY; import static android.view.Display.INVALID_DISPLAY; + import static com.android.internal.util.XmlUtils.readBooleanAttribute; import static com.android.internal.util.XmlUtils.readIntAttribute; import static com.android.internal.util.XmlUtils.readLongAttribute; @@ -198,6 +199,7 @@ import static android.view.WindowManager.TRANSIT_NONE; import static android.view.WindowManager.TRANSIT_TASK_IN_PLACE; import static android.view.WindowManager.TRANSIT_TASK_OPEN; import static android.view.WindowManager.TRANSIT_TASK_TO_FRONT; + import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT; import static org.xmlpull.v1.XmlPullParser.START_TAG; @@ -277,8 +279,8 @@ import android.content.pm.IPackageManager; import android.content.pm.InstrumentationInfo; import android.content.pm.PackageInfo; import android.content.pm.PackageManager; -import android.content.pm.PackageManagerInternal; import android.content.pm.PackageManager.NameNotFoundException; +import android.content.pm.PackageManagerInternal; import android.content.pm.ParceledListSlice; import android.content.pm.PathPermission; import android.content.pm.PermissionInfo; @@ -356,18 +358,18 @@ import android.text.style.SuggestionSpan; import android.util.ArrayMap; import android.util.ArraySet; import android.util.AtomicFile; -import android.util.LongSparseArray; -import android.util.StatsLog; -import android.util.TimingsTraceLog; import android.util.DebugUtils; import android.util.EventLog; import android.util.Log; +import android.util.LongSparseArray; import android.util.Pair; import android.util.PrintWriterPrinter; import android.util.Slog; import android.util.SparseArray; import android.util.SparseIntArray; +import android.util.StatsLog; import android.util.TimeUtils; +import android.util.TimingsTraceLog; import android.util.Xml; import android.util.proto.ProtoOutputStream; import android.view.Gravity; @@ -440,6 +442,12 @@ import com.android.server.utils.PriorityDump; import com.android.server.vr.VrManagerInternal; import com.android.server.wm.PinnedStackWindowController; import com.android.server.wm.WindowManagerService; + +import dalvik.system.VMRuntime; + +import libcore.io.IoUtils; +import libcore.util.EmptyArray; + import com.google.android.collect.Lists; import com.google.android.collect.Maps; @@ -479,11 +487,6 @@ import java.util.concurrent.Executor; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicLong; -import dalvik.system.VMRuntime; - -import libcore.io.IoUtils; -import libcore.util.EmptyArray; - public class ActivityManagerService extends IActivityManager.Stub implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback { @@ -10414,10 +10417,9 @@ public class ActivityManagerService extends IActivityManager.Stub @Override public Bitmap getTaskDescriptionIcon(String filePath, int userId) { - if (userId != UserHandle.getCallingUserId()) { - enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL, - "getTaskDescriptionIcon"); - } + userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(), + userId, false, ALLOW_FULL_ONLY, "getTaskDescriptionIcon", null); + final File passedIconFile = new File(filePath); final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId), passedIconFile.getName()); @@ -25159,6 +25161,10 @@ public class ActivityManagerService extends IActivityManager.Stub public int getMaxRunningUsers() { return mUserController.mMaxRunningUsers; } + + public boolean isCallerRecents(int callingUid) { + return getRecentTasks().isCallerRecents(callingUid); + } } /** diff --git a/services/core/java/com/android/server/am/UserController.java b/services/core/java/com/android/server/am/UserController.java index 1a47aa5cd777..5ada484e9e32 100644 --- a/services/core/java/com/android/server/am/UserController.java +++ b/services/core/java/com/android/server/am/UserController.java @@ -1431,7 +1431,13 @@ class UserController implements Handler.Callback { if (callingUid != 0 && callingUid != SYSTEM_UID) { final boolean allow; - if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, + if (mInjector.isCallerRecents(callingUid) + && callingUserId == getCurrentUserId() + && isSameProfileGroup(callingUserId, targetUserId)) { + // If the caller is Recents and it is running in the current user, we then allow it + // to access its profiles. + allow = true; + } else if (mInjector.checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid, callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) { // If the caller has this permission, they always pass go. And collect $200. allow = true; @@ -2149,5 +2155,9 @@ class UserController implements Handler.Callback { mService.mLockTaskController.clearLockedTasks(reason); } } + + protected boolean isCallerRecents(int callingUid) { + return mService.getRecentTasks().isCallerRecents(callingUid); + } } } diff --git a/services/core/java/com/android/server/pm/PackageManagerService.java b/services/core/java/com/android/server/pm/PackageManagerService.java index 10b377d9a81e..faf6114237cd 100644 --- a/services/core/java/com/android/server/pm/PackageManagerService.java +++ b/services/core/java/com/android/server/pm/PackageManagerService.java @@ -118,6 +118,7 @@ import android.annotation.IntDef; import android.annotation.NonNull; import android.annotation.Nullable; import android.app.ActivityManager; +import android.app.ActivityManagerInternal; import android.app.AppOpsManager; import android.app.IActivityManager; import android.app.ResourcesManager; @@ -992,6 +993,7 @@ public class PackageManagerService extends IPackageManager.Stub private List<String> mKeepUninstalledPackages; private UserManagerInternal mUserManagerInternal; + private ActivityManagerInternal mActivityManagerInternal; private DeviceIdleController.LocalService mDeviceIdleController; @@ -4575,6 +4577,14 @@ Slog.e("TODD", return mUserManagerInternal; } + private ActivityManagerInternal getActivityManagerInternal() { + if (mActivityManagerInternal == null) { + mActivityManagerInternal = LocalServices.getService(ActivityManagerInternal.class); + } + return mActivityManagerInternal; + } + + private DeviceIdleController.LocalService getDeviceIdleController() { if (mDeviceIdleController == null) { mDeviceIdleController = @@ -4735,8 +4745,12 @@ Slog.e("TODD", int filterCallingUid, int userId) { if (!sUserManager.exists(userId)) return null; flags = updateFlagsForComponent(flags, userId, component); - mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, - false /* requireFullPermission */, false /* checkShell */, "get activity info"); + + if (!isRecentsAccessingChildProfiles(Binder.getCallingUid(), userId)) { + mPermissionManager.enforceCrossUserPermission(Binder.getCallingUid(), userId, + false /* requireFullPermission */, false /* checkShell */, "get activity info"); + } + synchronized (mPackages) { PackageParser.Activity a = mActivities.mActivities.get(component); @@ -4758,6 +4772,22 @@ Slog.e("TODD", return null; } + private boolean isRecentsAccessingChildProfiles(int callingUid, int targetUserId) { + if (!getActivityManagerInternal().isCallerRecents(callingUid)) { + return false; + } + final long token = Binder.clearCallingIdentity(); + try { + final int callingUserId = UserHandle.getUserId(callingUid); + if (ActivityManager.getCurrentUser() != callingUserId) { + return false; + } + return sUserManager.isSameProfileGroup(callingUserId, targetUserId); + } finally { + Binder.restoreCallingIdentity(token); + } + } + @Override public boolean activitySupportsIntent(ComponentName component, Intent intent, String resolvedType) { |