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

Commit b53c1158 authored by Nikhil Kumar's avatar Nikhil Kumar
Browse files

Allow admin user's app with system UID to access blob store.

BlobStore APIs are restricted to be only consumed by the admin user's
app with system uid. Right now there is only one admin user
which is user 0 and for user 0 both the appId and callingUid are same.
So even with callingUid, the existing check works well.

With the new headless mode, there can be several Admin users,
and any Admin user's app with a system uid can call BlobStoreManager APIs. But the appId and callingUid have different values on other(except user 0) amdin users' apps.
callingUid = userId + "0" + appId

Refactored the restriction to use appId instead of callingUid to match with SYSTEM_UID and added an additional check to ensure that the calling user is an admin user.

Removed unused callingUid param in internal method.

Bug: 256119753

Test: atest --test-mapping apex/blobstore
Change-Id: I6717cb8ebeb263c911e3caae924b7c3935e58778
parent 6bc4ed39
Loading
Loading
Loading
Loading
+17 −11
Original line number Diff line number Diff line
@@ -80,6 +80,7 @@ import android.os.Process;
import android.os.RemoteCallback;
import android.os.SystemClock;
import android.os.UserHandle;
import android.os.UserManager;
import android.util.ArrayMap;
import android.util.ArraySet;
import android.util.AtomicFile;
@@ -619,7 +620,7 @@ public class BlobStoreManagerService extends SystemService {
        return blobInfos;
    }

    private void deleteBlobInternal(long blobId, int callingUid) {
    private void deleteBlobInternal(long blobId) {
        synchronized (mBlobsLock) {
            mBlobsMap.entrySet().removeIf(entry -> {
                final BlobMetadata blobMetadata = entry.getValue();
@@ -1612,10 +1613,7 @@ public class BlobStoreManagerService extends SystemService {
        @Override
        @NonNull
        public List<BlobInfo> queryBlobsForUser(@UserIdInt int userId) {
            if (Binder.getCallingUid() != Process.SYSTEM_UID) {
                throw new SecurityException("Only system uid is allowed to call "
                        + "queryBlobsForUser()");
            }
            verifyCallerIsSystemUid("queryBlobsForUser");

            final int resolvedUserId = userId == USER_CURRENT
                    ? ActivityManager.getCurrentUser() : userId;
@@ -1629,13 +1627,9 @@ public class BlobStoreManagerService extends SystemService {

        @Override
        public void deleteBlob(long blobId) {
            final int callingUid = Binder.getCallingUid();
            if (callingUid != Process.SYSTEM_UID) {
                throw new SecurityException("Only system uid is allowed to call "
                        + "deleteBlob()");
            }
            verifyCallerIsSystemUid("deleteBlob");

            deleteBlobInternal(blobId, callingUid);
            deleteBlobInternal(blobId);
        }

        @Override
@@ -1716,6 +1710,18 @@ public class BlobStoreManagerService extends SystemService {
            return new BlobStoreManagerShellCommand(BlobStoreManagerService.this).exec(this,
                    in.getFileDescriptor(), out.getFileDescriptor(), err.getFileDescriptor(), args);
        }

        /**
         * Verify if the caller is an admin user's app with system uid
         */
        private void verifyCallerIsSystemUid(final String operation) {
            if (UserHandle.getCallingAppId() != Process.SYSTEM_UID
                    || !mContext.getSystemService(UserManager.class)
                    .isUserAdmin(UserHandle.getCallingUserId())) {
                throw new SecurityException("Only admin user's app with system uid"
                        + "are allowed to call #" + operation);
            }
        }
    }

    static final class DumpArgs {