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

Commit dec5b198 authored by Winson's avatar Winson
Browse files

Verify PackageManagerShellCommand caller is shell

Also verifies that printing domain verification state asserts that
the caller is an approved querent, to match the
getDomainVerificationInfo Java API.

Bug: 200035185

Test: atest DomainVerificationEnforcerTest

Change-Id: I1daeeee9d44e54e21643fe6253ff8012dbe364b8
parent ea2b19eb
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -18,6 +18,7 @@ package com.android.server.pm;

import static android.content.pm.PackageInstaller.LOCATION_DATA_APP;

import android.Manifest;
import android.accounts.IAccountManager;
import android.annotation.NonNull;
import android.annotation.UserIdInt;
@@ -170,6 +171,20 @@ class PackageManagerShellCommand extends ShellCommand {

    @Override
    public int onCommand(String cmd) {
        switch (Binder.getCallingUid()) {
            case Process.ROOT_UID:
            case Process.SHELL_UID:
                break;
            default:
                // This is called from a test and is allowed as non-shell with the right permission
                if ("install-incremental".equals(cmd)) {
                    mContext.enforceCallingPermission(Manifest.permission.USE_SYSTEM_DATA_LOADERS,
                            "Caller missing USE_SYSTEM_DATA_LOADERS permission to use " + cmd);
                } else {
                    throw new IllegalArgumentException("Caller must be root or shell");
                }
        }

        if (cmd == null) {
            return handleDefaultCommands(cmd);
        }
+1 −0
Original line number Diff line number Diff line
@@ -1197,6 +1197,7 @@ public class DomainVerificationService extends SystemService
            @Nullable @UserIdInt Integer userId,
            @NonNull Function<String, PackageStateInternal> pkgSettingFunction)
            throws NameNotFoundException {
        mEnforcer.assertApprovedQuerent(mConnection.getCallingUid(), mProxy);
        synchronized (mLock) {
            mDebug.printState(writer, packageName, userId, pkgSettingFunction, mAttachedPkgStates);
        }
+19 −2
Original line number Diff line number Diff line
@@ -19,6 +19,7 @@ package com.android.server.pm.test.verify.domain
import android.content.Context
import android.content.Intent
import android.content.pm.PackageManager
import android.content.pm.SigningDetails
import android.content.pm.parsing.component.ParsedActivityImpl
import android.content.pm.parsing.component.ParsedIntentInfoImpl
import android.content.pm.verify.domain.DomainVerificationManager
@@ -26,6 +27,7 @@ import android.content.pm.verify.domain.DomainVerificationState
import android.os.Build
import android.os.Process
import android.util.ArraySet
import android.util.IndentingPrintWriter
import android.util.SparseArray
import androidx.test.platform.app.InstrumentationRegistry
import com.android.server.pm.parsing.pkg.AndroidPackage
@@ -46,6 +48,7 @@ import org.mockito.Mockito.anyInt
import org.mockito.Mockito.anyLong
import org.mockito.Mockito.anyString
import org.mockito.Mockito.eq
import org.mockito.Mockito.mock
import org.mockito.Mockito.verifyNoMoreInteractions
import java.util.UUID
import java.util.concurrent.atomic.AtomicBoolean
@@ -204,6 +207,14 @@ class DomainVerificationEnforcerTest {
                service(Type.QUERENT, "getInfo") {
                    getDomainVerificationInfo(it.targetPackageName)
                },
                service(Type.QUERENT, "printState") {
                    printState(mock(IndentingPrintWriter::class.java), null, null)
                },
                service(Type.QUERENT, "printStateInternal") {
                    printState(mock(IndentingPrintWriter::class.java), null, null) {
                        mockPkgState(it, UUID.randomUUID())
                    }
                },
                service(Type.VERIFIER, "setStatus") {
                    setDomainVerificationStatus(
                        it.targetDomainSetId,
@@ -311,6 +322,7 @@ class DomainVerificationEnforcerTest {
                    }
                )
            }
            whenever(signingDetails) { SigningDetails.UNKNOWN }
        }

        fun mockPkgState(packageName: String, domainSetId: UUID) =
@@ -327,6 +339,7 @@ class DomainVerificationEnforcerTest {
                    }
                }
                whenever(isSystem) { false }
                whenever(signingDetails) { SigningDetails.UNKNOWN }
            }
    }

@@ -794,9 +807,13 @@ class DomainVerificationEnforcerTest {
            }

            val valueAsInt = value as? Int
            if (valueAsInt != null && valueAsInt == DomainVerificationManager.STATUS_OK) {
            if (valueAsInt != null) {
                if (valueAsInt == DomainVerificationManager.STATUS_OK) {
                    throw AssertionError("Expected call to return false, was $value")
                }
            } else {
                throw AssertionError("Expected call to fail")
            }
        } catch (e: SecurityException) {
        } catch (e: PackageManager.NameNotFoundException) {
            // Any of these 2 exceptions are considered failures, which is expected