Verify querent for printing app links state
Verifies that printing domain verification state asserts that the caller is an approved querent, to match the getDomainVerificationInfo Java API. Also allows callers with the DUMP permission to be a querent, so that dumpsys package still works. Test: atest DomainVerificationEnforcerTest Change-Id: I9ad409ba15ce1a358ca8c0e047444a2fa6d2140b
This commit is contained in:
@@ -3156,7 +3156,7 @@ public class ComputerEngine implements Computer {
|
|||||||
try {
|
try {
|
||||||
mDomainVerificationManager.printState(writer, packageName,
|
mDomainVerificationManager.printState(writer, packageName,
|
||||||
UserHandle.USER_ALL, mSettings::getPackage);
|
UserHandle.USER_ALL, mSettings::getPackage);
|
||||||
} catch (PackageManager.NameNotFoundException e) {
|
} catch (Exception e) {
|
||||||
pw.println("Failure printing domain verification information");
|
pw.println("Failure printing domain verification information");
|
||||||
Slog.e(TAG, "Failure printing domain verification information", e);
|
Slog.e(TAG, "Failure printing domain verification information", e);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,8 +70,11 @@ public class DomainVerificationEnforcer {
|
|||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (!proxy.isCallerVerifier(callingUid)) {
|
if (!proxy.isCallerVerifier(callingUid)) {
|
||||||
throw new SecurityException(
|
mContext.enforcePermission(android.Manifest.permission.DUMP,
|
||||||
"Caller is not allowed to query domain verification state");
|
Binder.getCallingPid(), callingUid,
|
||||||
|
"Caller " + callingUid
|
||||||
|
+ " is not allowed to query domain verification state");
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
mContext.enforcePermission(android.Manifest.permission.QUERY_ALL_PACKAGES,
|
mContext.enforcePermission(android.Manifest.permission.QUERY_ALL_PACKAGES,
|
||||||
|
|||||||
@@ -1197,6 +1197,7 @@ public class DomainVerificationService extends SystemService
|
|||||||
@Nullable @UserIdInt Integer userId,
|
@Nullable @UserIdInt Integer userId,
|
||||||
@NonNull Function<String, PackageStateInternal> pkgSettingFunction)
|
@NonNull Function<String, PackageStateInternal> pkgSettingFunction)
|
||||||
throws NameNotFoundException {
|
throws NameNotFoundException {
|
||||||
|
mEnforcer.assertApprovedQuerent(mConnection.getCallingUid(), mProxy);
|
||||||
synchronized (mLock) {
|
synchronized (mLock) {
|
||||||
mDebug.printState(writer, packageName, userId, pkgSettingFunction, mAttachedPkgStates);
|
mDebug.printState(writer, packageName, userId, pkgSettingFunction, mAttachedPkgStates);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,7 @@ package com.android.server.pm.test.verify.domain
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.Intent
|
import android.content.Intent
|
||||||
import android.content.pm.PackageManager
|
import android.content.pm.PackageManager
|
||||||
|
import android.content.pm.SigningDetails
|
||||||
import android.content.pm.parsing.component.ParsedActivityImpl
|
import android.content.pm.parsing.component.ParsedActivityImpl
|
||||||
import android.content.pm.parsing.component.ParsedIntentInfoImpl
|
import android.content.pm.parsing.component.ParsedIntentInfoImpl
|
||||||
import android.content.pm.verify.domain.DomainVerificationManager
|
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.Build
|
||||||
import android.os.Process
|
import android.os.Process
|
||||||
import android.util.ArraySet
|
import android.util.ArraySet
|
||||||
|
import android.util.IndentingPrintWriter
|
||||||
import android.util.SparseArray
|
import android.util.SparseArray
|
||||||
import androidx.test.platform.app.InstrumentationRegistry
|
import androidx.test.platform.app.InstrumentationRegistry
|
||||||
import com.android.server.pm.parsing.pkg.AndroidPackage
|
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.anyLong
|
||||||
import org.mockito.Mockito.anyString
|
import org.mockito.Mockito.anyString
|
||||||
import org.mockito.Mockito.eq
|
import org.mockito.Mockito.eq
|
||||||
|
import org.mockito.Mockito.mock
|
||||||
import org.mockito.Mockito.verifyNoMoreInteractions
|
import org.mockito.Mockito.verifyNoMoreInteractions
|
||||||
import java.util.UUID
|
import java.util.UUID
|
||||||
import java.util.concurrent.atomic.AtomicBoolean
|
import java.util.concurrent.atomic.AtomicBoolean
|
||||||
@@ -204,6 +207,14 @@ class DomainVerificationEnforcerTest {
|
|||||||
service(Type.QUERENT, "getInfo") {
|
service(Type.QUERENT, "getInfo") {
|
||||||
getDomainVerificationInfo(it.targetPackageName)
|
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") {
|
service(Type.VERIFIER, "setStatus") {
|
||||||
setDomainVerificationStatus(
|
setDomainVerificationStatus(
|
||||||
it.targetDomainSetId,
|
it.targetDomainSetId,
|
||||||
@@ -311,6 +322,7 @@ class DomainVerificationEnforcerTest {
|
|||||||
}
|
}
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
whenever(signingDetails) { SigningDetails.UNKNOWN }
|
||||||
}
|
}
|
||||||
|
|
||||||
fun mockPkgState(packageName: String, domainSetId: UUID) =
|
fun mockPkgState(packageName: String, domainSetId: UUID) =
|
||||||
@@ -327,6 +339,7 @@ class DomainVerificationEnforcerTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
whenever(isSystem) { false }
|
whenever(isSystem) { false }
|
||||||
|
whenever(signingDetails) { SigningDetails.UNKNOWN }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -373,6 +386,7 @@ class DomainVerificationEnforcerTest {
|
|||||||
val allowUserState = AtomicBoolean(false)
|
val allowUserState = AtomicBoolean(false)
|
||||||
val allowPreferredApps = AtomicBoolean(false)
|
val allowPreferredApps = AtomicBoolean(false)
|
||||||
val allowQueryAll = AtomicBoolean(false)
|
val allowQueryAll = AtomicBoolean(false)
|
||||||
|
val allowDump = AtomicBoolean(false)
|
||||||
val context: Context = mockThrowOnUnmocked {
|
val context: Context = mockThrowOnUnmocked {
|
||||||
initPermission(
|
initPermission(
|
||||||
allowUserState,
|
allowUserState,
|
||||||
@@ -383,6 +397,7 @@ class DomainVerificationEnforcerTest {
|
|||||||
android.Manifest.permission.SET_PREFERRED_APPLICATIONS
|
android.Manifest.permission.SET_PREFERRED_APPLICATIONS
|
||||||
)
|
)
|
||||||
initPermission(allowQueryAll, android.Manifest.permission.QUERY_ALL_PACKAGES)
|
initPermission(allowQueryAll, android.Manifest.permission.QUERY_ALL_PACKAGES)
|
||||||
|
initPermission(allowDump, android.Manifest.permission.DUMP)
|
||||||
}
|
}
|
||||||
val target = params.construct(context)
|
val target = params.construct(context)
|
||||||
|
|
||||||
@@ -409,6 +424,10 @@ class DomainVerificationEnforcerTest {
|
|||||||
allowQueryAll.set(true)
|
allowQueryAll.set(true)
|
||||||
|
|
||||||
assertFails { runMethod(target, NON_VERIFIER_UID) }
|
assertFails { runMethod(target, NON_VERIFIER_UID) }
|
||||||
|
|
||||||
|
allowDump.set(true)
|
||||||
|
|
||||||
|
runMethod(target, NON_VERIFIER_UID)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun approvedVerifier() {
|
private fun approvedVerifier() {
|
||||||
@@ -794,8 +813,12 @@ class DomainVerificationEnforcerTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
val valueAsInt = value as? Int
|
val valueAsInt = value as? Int
|
||||||
if (valueAsInt != null && valueAsInt == DomainVerificationManager.STATUS_OK) {
|
if (valueAsInt != null) {
|
||||||
throw AssertionError("Expected call to return false, was $value")
|
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: SecurityException) {
|
||||||
} catch (e: PackageManager.NameNotFoundException) {
|
} catch (e: PackageManager.NameNotFoundException) {
|
||||||
@@ -807,7 +830,7 @@ class DomainVerificationEnforcerTest {
|
|||||||
// System/shell only
|
// System/shell only
|
||||||
INTERNAL,
|
INTERNAL,
|
||||||
|
|
||||||
// INTERNAL || non-legacy domain verification agent
|
// INTERNAL || non-legacy domain verification agent || DUMP permission
|
||||||
QUERENT,
|
QUERENT,
|
||||||
|
|
||||||
// INTERNAL || domain verification agent
|
// INTERNAL || domain verification agent
|
||||||
|
|||||||
Reference in New Issue
Block a user