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

Commit bd9f18f7 authored by Winson's avatar Winson
Browse files

Take package snapshot before locking DomainVerificationService

Because snapshot() can take PMS#mLock when the snapshot is invalid,
there's a potential deadlock if Settings is trying to serialize into
DVS. Instead, take the snapshot before locking DVS, which introduces
a potential race condition, as DVS relies on its internal lock
to serialize package changes, but there's not much better that
can be done until mutate-time snapshots are enabled.

Bug: 220994615

Test: atest com.android.server.pm.test.verify.domain
Test: atest CtsDomainVerificationHostTestCases
Test: atest CtsDomainVerificationDeviceMultiUserTestCases
Test: atest CtsDomainVerificationDeviceStandaloneTestCases

Change-Id: Ib4f4605d6b19ef14e47dffc3df3bee62a745a817
parent f1da716a
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -256,8 +256,8 @@ public class DomainVerificationService extends SystemService
    public DomainVerificationInfo getDomainVerificationInfo(@NonNull String packageName)
            throws NameNotFoundException {
        mEnforcer.assertApprovedQuerent(mConnection.getCallingUid(), mProxy);
        synchronized (mLock) {
        final Computer snapshot = mConnection.snapshot();
        synchronized (mLock) {
            PackageStateInternal pkgSetting = snapshot.getPackageStateInternal(packageName);
            AndroidPackage pkg = pkgSetting == null ? null : pkgSetting.getPkg();
            if (pkg == null) {
@@ -315,8 +315,8 @@ public class DomainVerificationService extends SystemService
            @NonNull Set<String> domains, int state)
            throws NameNotFoundException {
        mEnforcer.assertApprovedVerifier(callingUid, mProxy);
        synchronized (mLock) {
        final Computer snapshot = mConnection.snapshot();
        synchronized (mLock) {
            List<String> verifiedDomains = new ArrayList<>();

            GetAttachedResult result = getAndValidateAttachedLocked(domainSetId, domains,
@@ -369,8 +369,8 @@ public class DomainVerificationService extends SystemService

        ArraySet<String> verifiedDomains = new ArraySet<>();
        if (packageName == null) {
            synchronized (mLock) {
            final Computer snapshot = mConnection.snapshot();
            synchronized (mLock) {
                ArraySet<String> validDomains = new ArraySet<>();

                int size = mAttachedPkgStates.size();
@@ -403,8 +403,8 @@ public class DomainVerificationService extends SystemService
                }
            }
        } else {
            synchronized (mLock) {
            final Computer snapshot = mConnection.snapshot();
            synchronized (mLock) {
                DomainVerificationPkgState pkgState = mAttachedPkgStates.get(packageName);
                if (pkgState == null) {
                    throw DomainVerificationUtils.throwPackageUnavailable(packageName);
@@ -539,8 +539,8 @@ public class DomainVerificationService extends SystemService
            return DomainVerificationManager.ERROR_DOMAIN_SET_ID_INVALID;
        }

        synchronized (mLock) {
        final Computer snapshot = mConnection.snapshot();
        synchronized (mLock) {
            GetAttachedResult result = getAndValidateAttachedLocked(domainSetId, domains,
                    false /* forAutoVerify */, callingUid, userId, snapshot);
            if (result.isError()) {
@@ -578,8 +578,8 @@ public class DomainVerificationService extends SystemService
            @NonNull String packageName, boolean enabled, @Nullable ArraySet<String> domains)
            throws NameNotFoundException {
        mEnforcer.assertInternal(mConnection.getCallingUid());
        synchronized (mLock) {
        final Computer snapshot = mConnection.snapshot();
        synchronized (mLock) {
            DomainVerificationPkgState pkgState = mAttachedPkgStates.get(packageName);
            if (pkgState == null) {
                throw DomainVerificationUtils.throwPackageUnavailable(packageName);
@@ -682,8 +682,8 @@ public class DomainVerificationService extends SystemService
            throw DomainVerificationUtils.throwPackageUnavailable(packageName);
        }

        synchronized (mLock) {
        final Computer snapshot = mConnection.snapshot();
        synchronized (mLock) {
            PackageStateInternal pkgSetting = snapshot.getPackageStateInternal(packageName);
            AndroidPackage pkg = pkgSetting == null ? null : pkgSetting.getPkg();
            if (pkg == null) {
@@ -1179,8 +1179,8 @@ public class DomainVerificationService extends SystemService
    public void printOwnersForPackage(@NonNull IndentingPrintWriter writer,
            @Nullable String packageName, @Nullable @UserIdInt Integer userId)
            throws NameNotFoundException {
        synchronized (mLock) {
        final Computer snapshot = mConnection.snapshot();
        synchronized (mLock) {
            if (packageName == null) {
                int size = mAttachedPkgStates.size();
                for (int index = 0; index < size; index++) {
@@ -1227,8 +1227,8 @@ public class DomainVerificationService extends SystemService
    @Override
    public void printOwnersForDomains(@NonNull IndentingPrintWriter writer,
            @NonNull List<String> domains, @Nullable @UserIdInt Integer userId) {
        synchronized (mLock) {
        final Computer snapshot = mConnection.snapshot();
        synchronized (mLock) {
            int size = domains.size();
            for (int index = 0; index < size; index++) {
                printOwnersForDomain(writer, domains.get(index), userId, snapshot);
@@ -1403,8 +1403,8 @@ public class DomainVerificationService extends SystemService
    @Override
    public void clearDomainVerificationState(@Nullable List<String> packageNames) {
        mEnforcer.assertInternal(mConnection.getCallingUid());
        synchronized (mLock) {
        final Computer snapshot = mConnection.snapshot();
        synchronized (mLock) {
            if (packageNames == null) {
                int size = mAttachedPkgStates.size();
                for (int index = 0; index < size; index++) {