Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit b58049a0 authored by Will Burr's avatar Will Burr
Browse files

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
parent 47ac0112
Loading
Loading
Loading
Loading
+10 −1
Original line number Diff line number Diff line
@@ -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 {
+24 −8
Original line number Diff line number Diff line
@@ -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();
            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;
                    }