From b58049a0b67b3637c90c7949bc56fed0013b7ee3 Mon Sep 17 00:00:00 2001 From: Will Burr Date: Mon, 24 Apr 2023 11:44:03 +0000 Subject: [PATCH] Store SDK sandbox exit reasons under real UID and package UID SDK sandbox processes have the same package UID, but have real UIDs corresponding to the client app which started the sandbox. To allow SDKs to view their own exit reasons, we need to store SDK sandbox exit reasons under their real UID. To allow apps with the DUMP permission to see exit reasons for all SDK sandboxes, we also store the same objects under the package UID. This requires additional logic to ensure the trace input is not reset if already set. Fixes: 241524222 Test: manual (kill sandbox process and call getHistoricalProcessExitReasons from app w/ DUMP permission) Test: manual (kill sandbox process and call getHistoricalProcessExitReasons from SDK sandbox) Test: atest SdkSandboxMetricsHostTest Change-Id: I4279c22cbcb033b43013988c51fc441e4d2a66b7 --- .../server/am/ActivityManagerService.java | 11 ++++++- .../android/server/am/AppExitInfoTracker.java | 32 ++++++++++++++----- 2 files changed, 34 insertions(+), 9 deletions(-) diff --git a/services/core/java/com/android/server/am/ActivityManagerService.java b/services/core/java/com/android/server/am/ActivityManagerService.java index a992765c0411a..a9b5086bc1297 100644 --- a/services/core/java/com/android/server/am/ActivityManagerService.java +++ b/services/core/java/com/android/server/am/ActivityManagerService.java @@ -9478,11 +9478,20 @@ public class ActivityManagerService extends IActivityManager.Stub * Check if the calling process has the permission to dump given package, * throw SecurityException if it doesn't have the permission. * - * @return The UID of the given package, or {@link android.os.Process#INVALID_UID} + * @return The real UID of process that can be dumped, or {@link android.os.Process#INVALID_UID} * if the package is not found. */ int enforceDumpPermissionForPackage(String packageName, int userId, int callingUid, String function) { + // Allow SDK sandbox process to dump for its own process (under SDK sandbox package) + try { + if (Process.isSdkSandboxUid(callingUid) + && getPackageManager().getSdkSandboxPackageName().equals(packageName)) { + return callingUid; + } + } catch (RemoteException e) { + Log.e(TAG, "Could not get SDK sandbox package name"); + } final long identity = Binder.clearCallingIdentity(); int uid = INVALID_UID; try { diff --git a/services/core/java/com/android/server/am/AppExitInfoTracker.java b/services/core/java/com/android/server/am/AppExitInfoTracker.java index 4c0dd115a3cc5..666e5600a8b65 100644 --- a/services/core/java/com/android/server/am/AppExitInfoTracker.java +++ b/services/core/java/com/android/server/am/AppExitInfoTracker.java @@ -467,6 +467,13 @@ public final class AppExitInfoTracker { addExitInfoInnerLocked(packages[i], uid, info, recoverable); } + // SDK sandbox exits are stored under both real and package UID + if (Process.isSdkSandboxUid(uid)) { + for (int i = 0; i < packages.length; i++) { + addExitInfoInnerLocked(packages[i], raw.getPackageUid(), info, recoverable); + } + } + schedulePersistProcessExitInfo(false); return info; @@ -1400,11 +1407,20 @@ public final class AppExitInfoTracker { } } // Claim the state information if there is any - final int uid = info.getPackageUid(); + int uid = info.getPackageUid(); + // SDK sandbox app states and app traces are stored under real UID + if (Process.isSdkSandboxUid(info.getRealUid())) { + uid = info.getRealUid(); + } final int pid = info.getPid(); - info.setProcessStateSummary(findAndRemoveFromSparse2dArray( - mActiveAppStateSummary, uid, pid)); - info.setTraceFile(findAndRemoveFromSparse2dArray(mActiveAppTraces, uid, pid)); + if (info.getProcessStateSummary() == null) { + info.setProcessStateSummary(findAndRemoveFromSparse2dArray( + mActiveAppStateSummary, uid, pid)); + } + if (info.getTraceFile() == null) { + info.setTraceFile(findAndRemoveFromSparse2dArray(mActiveAppTraces, uid, pid)); + } + info.setAppTraceRetriever(mAppTraceRetriever); map.append(pid, info); } @@ -1905,15 +1921,15 @@ public final class AppExitInfoTracker { } final int callingPid = Binder.getCallingPid(); final int callingUid = Binder.getCallingUid(); - final int callingUserId = UserHandle.getCallingUserId(); final int userId = UserHandle.getUserId(uid); mService.mUserController.handleIncomingUser(callingPid, callingUid, userId, true, ALLOW_NON_FULL, "getTraceFileDescriptor", null); - if (mService.enforceDumpPermissionForPackage(packageName, userId, - callingUid, "getTraceFileDescriptor") != Process.INVALID_UID) { + final int filterUid = mService.enforceDumpPermissionForPackage(packageName, userId, + callingUid, "getTraceFileDescriptor"); + if (filterUid != Process.INVALID_UID) { synchronized (mLock) { - final ApplicationExitInfo info = getExitInfoLocked(packageName, uid, pid); + final ApplicationExitInfo info = getExitInfoLocked(packageName, filterUid, pid); if (info == null) { return null; }