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

Commit 8423dd15 authored by Jackal Guo's avatar Jackal Guo
Browse files

Verify the incoming package first.

The callingPackage is a parameter from the Binder, and the caller
could forge any name they want. We should verify if it's trusted.

Bug: 194105935
Bug: 194106074
Bug: 214894893
Test: atest -p core/java/android/app/
Test: atest -p services/tests/servicestests/src/com/android/server/am
Test: manually using the PoC in the buganizer to ensure the symptom
      no longer exists.
Change-Id: Ib7b4676d5c54df304d896b9f8260fe08c79dd3ce
parent 35eef324
Loading
Loading
Loading
Loading
+46 −22
Original line number Diff line number Diff line
@@ -2870,13 +2870,51 @@ public class ActivityManagerService extends IActivityManager.Stub
        return mode == AppOpsManager.MODE_ALLOWED;
    }
    @Override
    public int getPackageProcessState(String packageName, String callingPackage) {
    /**
     * Checks whether the calling package is trusted.
     *
     * The calling package is trusted if it's from system or the supposed package name matches the
     * UID making the call.
     *
     * @throws SecurityException if the package name and UID don't match.
     */
    private void verifyCallingPackage(String callingPackage) {
        final int callingUid = Binder.getCallingUid();
        // The caller is System or Shell.
        if (callingUid == SYSTEM_UID || isCallerShell()) {
            return;
        }
        // Handle the special UIDs that don't have real package (audioserver, cameraserver, etc).
        final String resolvedPackage = AppOpsManager.resolvePackageName(callingUid,
                null /* packageName */);
        if (resolvedPackage != null && resolvedPackage.equals(callingPackage)) {
            return;
        }
        final int claimedUid = getPackageManagerInternal().getPackageUid(callingPackage,
                0 /* flags */, UserHandle.getUserId(callingUid));
        if (callingUid == claimedUid) {
            return;
        }
        throw new SecurityException(
                "Claimed calling package " + callingPackage + " does not match the calling UID "
                        + Binder.getCallingUid());
    }
    private void enforceUsageStatsPermission(String callingPackage, String func) {
        verifyCallingPackage(callingPackage);
        // Since the protection level of PACKAGE_USAGE_STATS has 'appop', apps may grant this
        // permission via that way. We need to check both app-ops and permission.
        if (!hasUsageStatsPermission(callingPackage)) {
            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
                    "getPackageProcessState");
            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS, func);
        }
    }
    @Override
    public int getPackageProcessState(String packageName, String callingPackage) {
        enforceUsageStatsPermission(callingPackage, "getPackageProcessState");
        final int[] procState = {PROCESS_STATE_NONEXISTENT};
        synchronized (mProcLock) {
            mProcessList.forEachLruProcessesLOSP(false, proc -> {
@@ -6937,11 +6975,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public int getUidProcessState(int uid, String callingPackage) {
        if (!hasUsageStatsPermission(callingPackage)) {
            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
                    "getUidProcessState");
        }
        enforceUsageStatsPermission(callingPackage, "getUidProcessState");
        synchronized (mProcLock) {
            return mProcessList.getUidProcStateLOSP(uid);
        }
@@ -6949,11 +6983,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public @ProcessCapability int getUidProcessCapabilities(int uid, String callingPackage) {
        if (!hasUsageStatsPermission(callingPackage)) {
            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
                    "getUidProcessState");
        }
        enforceUsageStatsPermission(callingPackage, "getUidProcessCapabilities");
        synchronized (mProcLock) {
            return mProcessList.getUidProcessCapabilityLOSP(uid);
        }
@@ -6962,10 +6992,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public void registerUidObserver(IUidObserver observer, int which, int cutpoint,
            String callingPackage) {
        if (!hasUsageStatsPermission(callingPackage)) {
            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
                    "registerUidObserver");
        }
        enforceUsageStatsPermission(callingPackage, "registerUidObserver");
        mUidObserverController.register(observer, which, cutpoint, callingPackage,
                Binder.getCallingUid());
    }
@@ -6977,10 +7004,7 @@ public class ActivityManagerService extends IActivityManager.Stub
    @Override
    public boolean isUidActive(int uid, String callingPackage) {
        if (!hasUsageStatsPermission(callingPackage)) {
            enforceCallingPermission(android.Manifest.permission.PACKAGE_USAGE_STATS,
                    "isUidActive");
        }
        enforceUsageStatsPermission(callingPackage, "isUidActive");
        synchronized (mProcLock) {
            if (isUidActiveLOSP(uid)) {
                return true;
+1 −1
Original line number Diff line number Diff line
@@ -168,7 +168,7 @@ final class VibrationSettings {
        try {
            ActivityManager.getService().registerUidObserver(mUidObserver,
                    ActivityManager.UID_OBSERVER_PROCSTATE | ActivityManager.UID_OBSERVER_GONE,
                    ActivityManager.PROCESS_STATE_UNKNOWN, null);
                    ActivityManager.PROCESS_STATE_UNKNOWN, mContext.getOpPackageName());
        } catch (RemoteException e) {
            // ignored; both services live in system_server
        }
+11 −4
Original line number Diff line number Diff line
@@ -541,11 +541,14 @@ public class ActivityManagerServiceTest {
                    | ActivityManager.UID_OBSERVER_CAPABILITY
        };
        final IUidObserver[] observers = new IUidObserver.Stub[changesToObserve.length];
        doReturn(Process.myUid()).when(sPackageManagerInternal)
                .getPackageUid(mContext.getOpPackageName(), 0 /* flags */, mContext.getUserId());
        for (int i = 0; i < observers.length; ++i) {
            observers[i] = mock(IUidObserver.Stub.class);
            when(observers[i].asBinder()).thenReturn((IBinder) observers[i]);
            mAms.registerUidObserver(observers[i], changesToObserve[i] /* which */,
                    ActivityManager.PROCESS_STATE_UNKNOWN /* cutpoint */, null /* caller */);
                    ActivityManager.PROCESS_STATE_UNKNOWN /* cutpoint */,
                    mContext.getOpPackageName());

            // When we invoke AMS.registerUidObserver, there are some interactions with observers[i]
            // mock in RemoteCallbackList class. We don't want to test those interactions and
@@ -674,10 +677,12 @@ public class ActivityManagerServiceTest {
        mockNoteOperation();

        final IUidObserver observer = mock(IUidObserver.Stub.class);

        when(observer.asBinder()).thenReturn((IBinder) observer);
        doReturn(Process.myUid()).when(sPackageManagerInternal)
                .getPackageUid(mContext.getOpPackageName(), 0 /* flags */, mContext.getUserId());
        mAms.registerUidObserver(observer, ActivityManager.UID_OBSERVER_PROCSTATE /* which */,
                ActivityManager.PROCESS_STATE_SERVICE /* cutpoint */, null /* callingPackage */);
                ActivityManager.PROCESS_STATE_SERVICE /* cutpoint */,
                mContext.getOpPackageName());
        // When we invoke AMS.registerUidObserver, there are some interactions with observer
        // mock in RemoteCallbackList class. We don't want to test those interactions and
        // at the same time, we don't want those to interfere with verifyNoMoreInteractions.
@@ -771,7 +776,9 @@ public class ActivityManagerServiceTest {

        final IUidObserver observer = mock(IUidObserver.Stub.class);
        when(observer.asBinder()).thenReturn((IBinder) observer);
        mAms.registerUidObserver(observer, 0, 0, null);
        doReturn(Process.myUid()).when(sPackageManagerInternal)
                .getPackageUid(mContext.getOpPackageName(), 0 /* flags */, mContext.getUserId());
        mAms.registerUidObserver(observer, 0, 0, mContext.getOpPackageName());
        // Verify that when observers are registered, then validateUids is correctly updated.
        addPendingUidChanges(pendingItemsForUids);
        mAms.mUidObserverController.dispatchUidsChanged();