Loading services/core/java/com/android/server/pm/PackageManagerService.java +6 −2 Original line number Diff line number Diff line Loading @@ -1749,6 +1749,11 @@ public class PackageManagerService extends IPackageManager.Stub public AndroidPackage getPackage(@NonNull String packageName) { return getPackageLocked(packageName); } @Override public boolean filterAppAccess(String packageName, int callingUid, int userId) { return mPmInternal.filterAppAccess(packageName, callingUid, userId); } } /** Loading Loading @@ -16157,8 +16162,7 @@ public class PackageManagerService extends IPackageManager.Stub @Deprecated @Override public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { mDomainVerificationManager.setLegacyUserState(packageName, userId, status); return true; return mDomainVerificationManager.setLegacyUserState(packageName, userId, status); } @Deprecated services/core/java/com/android/server/pm/Settings.java +0 −1 Original line number Diff line number Diff line Loading @@ -2712,7 +2712,6 @@ public final class Settings implements Watchable, Snappable { writeSigningKeySetLPr(serializer, pkg.keySetData); writeUpgradeKeySetsLPr(serializer, pkg.keySetData); writeKeySetAliasesLPr(serializer, pkg.keySetData); mDomainVerificationManager.writeLegacySettings(serializer, pkg.name); writeMimeGroupLPr(serializer, pkg.mimeGroups); serializer.endTag(null, "package"); Loading services/core/java/com/android/server/pm/verify/domain/DomainVerificationEnforcer.java +78 −11 Original line number Diff line number Diff line Loading @@ -18,8 +18,10 @@ package com.android.server.pm.verify.domain; import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.Context; import android.content.pm.PackageManager; import android.os.Binder; import android.os.Process; Loading @@ -30,10 +32,17 @@ public class DomainVerificationEnforcer { @NonNull private final Context mContext; @NonNull private Callback mCallback; public DomainVerificationEnforcer(@NonNull Context context) { mContext = context; } public void setCallback(@NonNull Callback callback) { mCallback = callback; } /** * Enforced when mutating any state from shell or internally in the system process. */ Loading Loading @@ -67,6 +76,11 @@ public class DomainVerificationEnforcer { "Caller " + callingUid + " is not allowed to query domain verification state"); } mContext.enforcePermission(android.Manifest.permission.QUERY_ALL_PACKAGES, Binder.getCallingPid(), callingUid, "Caller " + callingUid + " does not hold " + android.Manifest.permission.QUERY_ALL_PACKAGES); break; } } Loading @@ -84,28 +98,42 @@ public class DomainVerificationEnforcer { isAllowed = true; break; default: // TODO(b/159952358): Remove permission check? The component package should // have been checked when the verifier component was first scanned in PMS. mContext.enforcePermission( android.Manifest.permission.DOMAIN_VERIFICATION_AGENT, Binder.getCallingPid(), callingUid, "Caller " + callingUid + " does not hold DOMAIN_VERIFICATION_AGENT"); final int callingPid = Binder.getCallingPid(); boolean isLegacyVerificationAgent = false; if (mContext.checkPermission( android.Manifest.permission.DOMAIN_VERIFICATION_AGENT, callingPid, callingUid) != PackageManager.PERMISSION_GRANTED) { isLegacyVerificationAgent = mContext.checkPermission( android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; if (!isLegacyVerificationAgent) { throw new SecurityException("Caller " + callingUid + " does not hold " + android.Manifest.permission.DOMAIN_VERIFICATION_AGENT); } } // If the caller isn't a legacy verifier, it needs the QUERY_ALL permission if (!isLegacyVerificationAgent) { mContext.enforcePermission(android.Manifest.permission.QUERY_ALL_PACKAGES, callingPid, callingUid, "Caller " + callingUid + " does not hold " + android.Manifest.permission.QUERY_ALL_PACKAGES); } isAllowed = proxy.isCallerVerifier(callingUid); break; } if (!isAllowed) { throw new SecurityException("Caller " + callingUid + " is not the approved domain verification agent, isVerifier = " + proxy.isCallerVerifier(callingUid)); + " is not the approved domain verification agent"); } } /** * Enforced when mutating user selection state inside an exposed API method. */ public void assertApprovedUserSelector(int callingUid, @UserIdInt int callingUserId, @UserIdInt int targetUserId) throws SecurityException { public boolean assertApprovedUserSelector(int callingUid, @UserIdInt int callingUserId, @Nullable String packageName, @UserIdInt int targetUserId) throws SecurityException { if (callingUserId != targetUserId) { mContext.enforcePermission( Manifest.permission.INTERACT_ACROSS_USERS, Loading @@ -117,12 +145,51 @@ public class DomainVerificationEnforcer { android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION, Binder.getCallingPid(), callingUid, "Caller is not allowed to edit user selections"); if (packageName == null) { return true; } return !mCallback.filterAppAccess(packageName, callingUid, targetUserId); } public void callerIsLegacyUserSelector(int callingUid) { public boolean callerIsLegacyUserSelector(int callingUid, @UserIdInt int callingUserId, @NonNull String packageName, @UserIdInt int targetUserId) { mContext.enforcePermission( android.Manifest.permission.SET_PREFERRED_APPLICATIONS, Binder.getCallingPid(), callingUid, "Caller is not allowed to edit user state"); if (callingUserId != targetUserId) { if (mContext.checkPermission( Manifest.permission.INTERACT_ACROSS_USERS, Binder.getCallingPid(), callingUid) != PackageManager.PERMISSION_GRANTED) { // Legacy API did not enforce this, so for backwards compatibility, fail silently return false; } } return !mCallback.filterAppAccess(packageName, callingUid, targetUserId); } public boolean callerIsLegacyUserQuerent(int callingUid, @UserIdInt int callingUserId, @NonNull String packageName, @UserIdInt int targetUserId) { if (callingUserId != targetUserId) { // The legacy API enforces the _FULL variant, so maintain that here mContext.enforcePermission( Manifest.permission.INTERACT_ACROSS_USERS_FULL, Binder.getCallingPid(), callingUid, "Caller is not allowed to edit other users"); } return !mCallback.filterAppAccess(packageName, callingUid, targetUserId); } public interface Callback { /** * @return true if access to the given package should be filtered and the method failed as * if the package was not installed */ boolean filterAppAccess(@NonNull String packageName, int callingUid, @UserIdInt int userId); } } services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerInternal.java +5 −8 Original line number Diff line number Diff line Loading @@ -174,8 +174,10 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan * Set aside a legacy user selection that will be restored to a pending * {@link DomainVerificationPkgState} once it's added through * {@link #addPackage(PackageSetting)}. * * @return true if state changed successfully */ void setLegacyUserState(@NonNull String packageName, @UserIdInt int userId, int state); boolean setLegacyUserState(@NonNull String packageName, @UserIdInt int userId, int state); /** * Until the legacy APIs are entirely removed, returns the legacy state from the previously Loading @@ -183,12 +185,6 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan */ int getLegacyState(@NonNull String packageName, @UserIdInt int userId); /** * Serialize a legacy setting that wasn't attached yet. * TODO: Does this even matter? Should consider for removal. */ void writeLegacySettings(TypedXmlSerializer serializer, String name); /** * Print the verification state and user selection state of a package. * Loading Loading @@ -235,7 +231,8 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan throws IllegalArgumentException, NameNotFoundException; interface Connection extends Function<String, PackageSetting> { interface Connection extends DomainVerificationEnforcer.Callback, Function<String, PackageSetting> { /** * Notify that a settings change has been made and that eventually Loading services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java +46 −19 Original line number Diff line number Diff line Loading @@ -47,12 +47,12 @@ import com.android.server.SystemConfig; import com.android.server.SystemService; import com.android.server.compat.PlatformCompat; import com.android.server.pm.PackageSetting; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.pm.verify.domain.models.DomainVerificationPkgState; import com.android.server.pm.verify.domain.models.DomainVerificationStateMap; import com.android.server.pm.verify.domain.models.DomainVerificationUserState; import com.android.server.pm.verify.domain.proxy.DomainVerificationProxy; import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyUnavailable; import com.android.server.pm.parsing.pkg.AndroidPackage; import org.xmlpull.v1.XmlPullParserException; Loading Loading @@ -92,9 +92,9 @@ public class DomainVerificationService extends SystemService * immediately attached once its available. * <p> * Generally this should be not accessed directly. Prefer calling {@link * #getAndValidateAttachedLocked(UUID, Set, boolean)}. * #getAndValidateAttachedLocked(UUID, Set, boolean, int, Integer)}. * * @see #getAndValidateAttachedLocked(UUID, Set, boolean) * @see #getAndValidateAttachedLocked(UUID, Set, boolean, int, Integer) **/ @GuardedBy("mLock") @NonNull Loading Loading @@ -160,6 +160,7 @@ public class DomainVerificationService extends SystemService @Override public void setConnection(@NonNull Connection connection) { mConnection = connection; mEnforcer.setCallback(mConnection); } @NonNull Loading Loading @@ -285,7 +286,7 @@ public class DomainVerificationService extends SystemService mEnforcer.assertApprovedVerifier(callingUid, mProxy); synchronized (mLock) { DomainVerificationPkgState pkgState = getAndValidateAttachedLocked(domainSetId, domains, true /* forAutoVerify */); true /* forAutoVerify */, callingUid, null /* userId */); ArrayMap<String, Integer> stateMap = pkgState.getStateMap(); for (String domain : domains) { Integer previousState = stateMap.get(domain); Loading Loading @@ -389,8 +390,10 @@ public class DomainVerificationService extends SystemService public void setDomainVerificationLinkHandlingAllowed(@NonNull String packageName, boolean allowed, @UserIdInt int userId) throws NameNotFoundException { mEnforcer.assertApprovedUserSelector(mConnection.getCallingUid(), mConnection.getCallingUserId(), userId); if (!mEnforcer.assertApprovedUserSelector(mConnection.getCallingUid(), mConnection.getCallingUserId(), packageName, userId)) { throw DomainVerificationUtils.throwPackageUnavailable(packageName); } synchronized (mLock) { DomainVerificationPkgState pkgState = mAttachedPkgStates.get(packageName); if (pkgState == null) { Loading Loading @@ -455,11 +458,18 @@ public class DomainVerificationService extends SystemService public void setDomainVerificationUserSelection(@NonNull UUID domainSetId, @NonNull Set<String> domains, boolean enabled, @UserIdInt int userId) throws InvalidDomainSetException, NameNotFoundException { mEnforcer.assertApprovedUserSelector(mConnection.getCallingUid(), mConnection.getCallingUserId(), userId); synchronized (mLock) { final int callingUid = mConnection.getCallingUid(); // Pass null for package name here and do the app visibility enforcement inside // getAndValidateAttachedLocked instead, since this has to fail with the same invalid // ID reason if the target app is invisible if (!mEnforcer.assertApprovedUserSelector(callingUid, mConnection.getCallingUserId(), null /* packageName */, userId)) { throw new InvalidDomainSetException(domainSetId, null, InvalidDomainSetException.REASON_ID_INVALID); } DomainVerificationPkgState pkgState = getAndValidateAttachedLocked(domainSetId, domains, false /* forAutoVerify */); false /* forAutoVerify */, callingUid, userId); DomainVerificationUserState userState = pkgState.getOrCreateUserSelectionState(userId); if (enabled) { userState.addHosts(domains); Loading Loading @@ -556,8 +566,10 @@ public class DomainVerificationService extends SystemService @Override public DomainVerificationUserSelection getDomainVerificationUserSelection( @NonNull String packageName, @UserIdInt int userId) throws NameNotFoundException { mEnforcer.assertApprovedUserSelector(mConnection.getCallingUid(), mConnection.getCallingUserId(), userId); if (!mEnforcer.assertApprovedUserSelector(mConnection.getCallingUid(), mConnection.getCallingUserId(), packageName, userId)) { throw DomainVerificationUtils.throwPackageUnavailable(packageName); } synchronized (mLock) { DomainVerificationPkgState pkgState = mAttachedPkgStates.get(packageName); if (pkgState == null) { Loading Loading @@ -844,20 +856,24 @@ public class DomainVerificationService extends SystemService } @Override public void setLegacyUserState(@NonNull String packageName, @UserIdInt int userId, int state) { mEnforcer.callerIsLegacyUserSelector(mConnection.getCallingUid()); public boolean setLegacyUserState(@NonNull String packageName, @UserIdInt int userId, int state) { if (!mEnforcer.callerIsLegacyUserSelector(mConnection.getCallingUid(), mConnection.getCallingUserId(), packageName, userId)) { return false; } mLegacySettings.add(packageName, userId, state); mConnection.scheduleWriteSettings(); return true; } @Override public int getLegacyState(@NonNull String packageName, @UserIdInt int userId) { return mLegacySettings.getUserState(packageName, userId); if (!mEnforcer.callerIsLegacyUserQuerent(mConnection.getCallingUid(), mConnection.getCallingUserId(), packageName, userId)) { return PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; } @Override public void writeLegacySettings(TypedXmlSerializer serializer, String name) { return mLegacySettings.getUserState(packageName, userId); } @Override Loading Loading @@ -935,10 +951,14 @@ public class DomainVerificationService extends SystemService * Validates parameters provided by an external caller. Checks that an ID is still live and that * any provided domains are valid. Should be called at the beginning of each API that takes in a * {@link UUID} domain set ID. * * @param userIdForFilter which user to filter app access to, or null if the caller has already * validated package visibility */ @GuardedBy("mLock") private DomainVerificationPkgState getAndValidateAttachedLocked(@NonNull UUID domainSetId, @NonNull Set<String> domains, boolean forAutoVerify) @NonNull Set<String> domains, boolean forAutoVerify, int callingUid, @Nullable Integer userIdForFilter) throws InvalidDomainSetException, NameNotFoundException { if (domainSetId == null) { throw new InvalidDomainSetException(null, null, Loading @@ -952,6 +972,13 @@ public class DomainVerificationService extends SystemService } String pkgName = pkgState.getPackageName(); if (userIdForFilter != null && mConnection.filterAppAccess(pkgName, callingUid, userIdForFilter)) { throw new InvalidDomainSetException(domainSetId, null, InvalidDomainSetException.REASON_ID_INVALID); } PackageSetting pkgSetting = mConnection.getPackageSettingLocked(pkgName); if (pkgSetting == null || pkgSetting.getPkg() == null) { throw DomainVerificationUtils.throwPackageUnavailable(pkgName); Loading Loading
services/core/java/com/android/server/pm/PackageManagerService.java +6 −2 Original line number Diff line number Diff line Loading @@ -1749,6 +1749,11 @@ public class PackageManagerService extends IPackageManager.Stub public AndroidPackage getPackage(@NonNull String packageName) { return getPackageLocked(packageName); } @Override public boolean filterAppAccess(String packageName, int callingUid, int userId) { return mPmInternal.filterAppAccess(packageName, callingUid, userId); } } /** Loading Loading @@ -16157,8 +16162,7 @@ public class PackageManagerService extends IPackageManager.Stub @Deprecated @Override public boolean updateIntentVerificationStatus(String packageName, int status, int userId) { mDomainVerificationManager.setLegacyUserState(packageName, userId, status); return true; return mDomainVerificationManager.setLegacyUserState(packageName, userId, status); } @Deprecated
services/core/java/com/android/server/pm/Settings.java +0 −1 Original line number Diff line number Diff line Loading @@ -2712,7 +2712,6 @@ public final class Settings implements Watchable, Snappable { writeSigningKeySetLPr(serializer, pkg.keySetData); writeUpgradeKeySetsLPr(serializer, pkg.keySetData); writeKeySetAliasesLPr(serializer, pkg.keySetData); mDomainVerificationManager.writeLegacySettings(serializer, pkg.name); writeMimeGroupLPr(serializer, pkg.mimeGroups); serializer.endTag(null, "package"); Loading
services/core/java/com/android/server/pm/verify/domain/DomainVerificationEnforcer.java +78 −11 Original line number Diff line number Diff line Loading @@ -18,8 +18,10 @@ package com.android.server.pm.verify.domain; import android.Manifest; import android.annotation.NonNull; import android.annotation.Nullable; import android.annotation.UserIdInt; import android.content.Context; import android.content.pm.PackageManager; import android.os.Binder; import android.os.Process; Loading @@ -30,10 +32,17 @@ public class DomainVerificationEnforcer { @NonNull private final Context mContext; @NonNull private Callback mCallback; public DomainVerificationEnforcer(@NonNull Context context) { mContext = context; } public void setCallback(@NonNull Callback callback) { mCallback = callback; } /** * Enforced when mutating any state from shell or internally in the system process. */ Loading Loading @@ -67,6 +76,11 @@ public class DomainVerificationEnforcer { "Caller " + callingUid + " is not allowed to query domain verification state"); } mContext.enforcePermission(android.Manifest.permission.QUERY_ALL_PACKAGES, Binder.getCallingPid(), callingUid, "Caller " + callingUid + " does not hold " + android.Manifest.permission.QUERY_ALL_PACKAGES); break; } } Loading @@ -84,28 +98,42 @@ public class DomainVerificationEnforcer { isAllowed = true; break; default: // TODO(b/159952358): Remove permission check? The component package should // have been checked when the verifier component was first scanned in PMS. mContext.enforcePermission( android.Manifest.permission.DOMAIN_VERIFICATION_AGENT, Binder.getCallingPid(), callingUid, "Caller " + callingUid + " does not hold DOMAIN_VERIFICATION_AGENT"); final int callingPid = Binder.getCallingPid(); boolean isLegacyVerificationAgent = false; if (mContext.checkPermission( android.Manifest.permission.DOMAIN_VERIFICATION_AGENT, callingPid, callingUid) != PackageManager.PERMISSION_GRANTED) { isLegacyVerificationAgent = mContext.checkPermission( android.Manifest.permission.INTENT_FILTER_VERIFICATION_AGENT, callingPid, callingUid) == PackageManager.PERMISSION_GRANTED; if (!isLegacyVerificationAgent) { throw new SecurityException("Caller " + callingUid + " does not hold " + android.Manifest.permission.DOMAIN_VERIFICATION_AGENT); } } // If the caller isn't a legacy verifier, it needs the QUERY_ALL permission if (!isLegacyVerificationAgent) { mContext.enforcePermission(android.Manifest.permission.QUERY_ALL_PACKAGES, callingPid, callingUid, "Caller " + callingUid + " does not hold " + android.Manifest.permission.QUERY_ALL_PACKAGES); } isAllowed = proxy.isCallerVerifier(callingUid); break; } if (!isAllowed) { throw new SecurityException("Caller " + callingUid + " is not the approved domain verification agent, isVerifier = " + proxy.isCallerVerifier(callingUid)); + " is not the approved domain verification agent"); } } /** * Enforced when mutating user selection state inside an exposed API method. */ public void assertApprovedUserSelector(int callingUid, @UserIdInt int callingUserId, @UserIdInt int targetUserId) throws SecurityException { public boolean assertApprovedUserSelector(int callingUid, @UserIdInt int callingUserId, @Nullable String packageName, @UserIdInt int targetUserId) throws SecurityException { if (callingUserId != targetUserId) { mContext.enforcePermission( Manifest.permission.INTERACT_ACROSS_USERS, Loading @@ -117,12 +145,51 @@ public class DomainVerificationEnforcer { android.Manifest.permission.UPDATE_DOMAIN_VERIFICATION_USER_SELECTION, Binder.getCallingPid(), callingUid, "Caller is not allowed to edit user selections"); if (packageName == null) { return true; } return !mCallback.filterAppAccess(packageName, callingUid, targetUserId); } public void callerIsLegacyUserSelector(int callingUid) { public boolean callerIsLegacyUserSelector(int callingUid, @UserIdInt int callingUserId, @NonNull String packageName, @UserIdInt int targetUserId) { mContext.enforcePermission( android.Manifest.permission.SET_PREFERRED_APPLICATIONS, Binder.getCallingPid(), callingUid, "Caller is not allowed to edit user state"); if (callingUserId != targetUserId) { if (mContext.checkPermission( Manifest.permission.INTERACT_ACROSS_USERS, Binder.getCallingPid(), callingUid) != PackageManager.PERMISSION_GRANTED) { // Legacy API did not enforce this, so for backwards compatibility, fail silently return false; } } return !mCallback.filterAppAccess(packageName, callingUid, targetUserId); } public boolean callerIsLegacyUserQuerent(int callingUid, @UserIdInt int callingUserId, @NonNull String packageName, @UserIdInt int targetUserId) { if (callingUserId != targetUserId) { // The legacy API enforces the _FULL variant, so maintain that here mContext.enforcePermission( Manifest.permission.INTERACT_ACROSS_USERS_FULL, Binder.getCallingPid(), callingUid, "Caller is not allowed to edit other users"); } return !mCallback.filterAppAccess(packageName, callingUid, targetUserId); } public interface Callback { /** * @return true if access to the given package should be filtered and the method failed as * if the package was not installed */ boolean filterAppAccess(@NonNull String packageName, int callingUid, @UserIdInt int userId); } }
services/core/java/com/android/server/pm/verify/domain/DomainVerificationManagerInternal.java +5 −8 Original line number Diff line number Diff line Loading @@ -174,8 +174,10 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan * Set aside a legacy user selection that will be restored to a pending * {@link DomainVerificationPkgState} once it's added through * {@link #addPackage(PackageSetting)}. * * @return true if state changed successfully */ void setLegacyUserState(@NonNull String packageName, @UserIdInt int userId, int state); boolean setLegacyUserState(@NonNull String packageName, @UserIdInt int userId, int state); /** * Until the legacy APIs are entirely removed, returns the legacy state from the previously Loading @@ -183,12 +185,6 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan */ int getLegacyState(@NonNull String packageName, @UserIdInt int userId); /** * Serialize a legacy setting that wasn't attached yet. * TODO: Does this even matter? Should consider for removal. */ void writeLegacySettings(TypedXmlSerializer serializer, String name); /** * Print the verification state and user selection state of a package. * Loading Loading @@ -235,7 +231,8 @@ public interface DomainVerificationManagerInternal extends DomainVerificationMan throws IllegalArgumentException, NameNotFoundException; interface Connection extends Function<String, PackageSetting> { interface Connection extends DomainVerificationEnforcer.Callback, Function<String, PackageSetting> { /** * Notify that a settings change has been made and that eventually Loading
services/core/java/com/android/server/pm/verify/domain/DomainVerificationService.java +46 −19 Original line number Diff line number Diff line Loading @@ -47,12 +47,12 @@ import com.android.server.SystemConfig; import com.android.server.SystemService; import com.android.server.compat.PlatformCompat; import com.android.server.pm.PackageSetting; import com.android.server.pm.parsing.pkg.AndroidPackage; import com.android.server.pm.verify.domain.models.DomainVerificationPkgState; import com.android.server.pm.verify.domain.models.DomainVerificationStateMap; import com.android.server.pm.verify.domain.models.DomainVerificationUserState; import com.android.server.pm.verify.domain.proxy.DomainVerificationProxy; import com.android.server.pm.verify.domain.proxy.DomainVerificationProxyUnavailable; import com.android.server.pm.parsing.pkg.AndroidPackage; import org.xmlpull.v1.XmlPullParserException; Loading Loading @@ -92,9 +92,9 @@ public class DomainVerificationService extends SystemService * immediately attached once its available. * <p> * Generally this should be not accessed directly. Prefer calling {@link * #getAndValidateAttachedLocked(UUID, Set, boolean)}. * #getAndValidateAttachedLocked(UUID, Set, boolean, int, Integer)}. * * @see #getAndValidateAttachedLocked(UUID, Set, boolean) * @see #getAndValidateAttachedLocked(UUID, Set, boolean, int, Integer) **/ @GuardedBy("mLock") @NonNull Loading Loading @@ -160,6 +160,7 @@ public class DomainVerificationService extends SystemService @Override public void setConnection(@NonNull Connection connection) { mConnection = connection; mEnforcer.setCallback(mConnection); } @NonNull Loading Loading @@ -285,7 +286,7 @@ public class DomainVerificationService extends SystemService mEnforcer.assertApprovedVerifier(callingUid, mProxy); synchronized (mLock) { DomainVerificationPkgState pkgState = getAndValidateAttachedLocked(domainSetId, domains, true /* forAutoVerify */); true /* forAutoVerify */, callingUid, null /* userId */); ArrayMap<String, Integer> stateMap = pkgState.getStateMap(); for (String domain : domains) { Integer previousState = stateMap.get(domain); Loading Loading @@ -389,8 +390,10 @@ public class DomainVerificationService extends SystemService public void setDomainVerificationLinkHandlingAllowed(@NonNull String packageName, boolean allowed, @UserIdInt int userId) throws NameNotFoundException { mEnforcer.assertApprovedUserSelector(mConnection.getCallingUid(), mConnection.getCallingUserId(), userId); if (!mEnforcer.assertApprovedUserSelector(mConnection.getCallingUid(), mConnection.getCallingUserId(), packageName, userId)) { throw DomainVerificationUtils.throwPackageUnavailable(packageName); } synchronized (mLock) { DomainVerificationPkgState pkgState = mAttachedPkgStates.get(packageName); if (pkgState == null) { Loading Loading @@ -455,11 +458,18 @@ public class DomainVerificationService extends SystemService public void setDomainVerificationUserSelection(@NonNull UUID domainSetId, @NonNull Set<String> domains, boolean enabled, @UserIdInt int userId) throws InvalidDomainSetException, NameNotFoundException { mEnforcer.assertApprovedUserSelector(mConnection.getCallingUid(), mConnection.getCallingUserId(), userId); synchronized (mLock) { final int callingUid = mConnection.getCallingUid(); // Pass null for package name here and do the app visibility enforcement inside // getAndValidateAttachedLocked instead, since this has to fail with the same invalid // ID reason if the target app is invisible if (!mEnforcer.assertApprovedUserSelector(callingUid, mConnection.getCallingUserId(), null /* packageName */, userId)) { throw new InvalidDomainSetException(domainSetId, null, InvalidDomainSetException.REASON_ID_INVALID); } DomainVerificationPkgState pkgState = getAndValidateAttachedLocked(domainSetId, domains, false /* forAutoVerify */); false /* forAutoVerify */, callingUid, userId); DomainVerificationUserState userState = pkgState.getOrCreateUserSelectionState(userId); if (enabled) { userState.addHosts(domains); Loading Loading @@ -556,8 +566,10 @@ public class DomainVerificationService extends SystemService @Override public DomainVerificationUserSelection getDomainVerificationUserSelection( @NonNull String packageName, @UserIdInt int userId) throws NameNotFoundException { mEnforcer.assertApprovedUserSelector(mConnection.getCallingUid(), mConnection.getCallingUserId(), userId); if (!mEnforcer.assertApprovedUserSelector(mConnection.getCallingUid(), mConnection.getCallingUserId(), packageName, userId)) { throw DomainVerificationUtils.throwPackageUnavailable(packageName); } synchronized (mLock) { DomainVerificationPkgState pkgState = mAttachedPkgStates.get(packageName); if (pkgState == null) { Loading Loading @@ -844,20 +856,24 @@ public class DomainVerificationService extends SystemService } @Override public void setLegacyUserState(@NonNull String packageName, @UserIdInt int userId, int state) { mEnforcer.callerIsLegacyUserSelector(mConnection.getCallingUid()); public boolean setLegacyUserState(@NonNull String packageName, @UserIdInt int userId, int state) { if (!mEnforcer.callerIsLegacyUserSelector(mConnection.getCallingUid(), mConnection.getCallingUserId(), packageName, userId)) { return false; } mLegacySettings.add(packageName, userId, state); mConnection.scheduleWriteSettings(); return true; } @Override public int getLegacyState(@NonNull String packageName, @UserIdInt int userId) { return mLegacySettings.getUserState(packageName, userId); if (!mEnforcer.callerIsLegacyUserQuerent(mConnection.getCallingUid(), mConnection.getCallingUserId(), packageName, userId)) { return PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED; } @Override public void writeLegacySettings(TypedXmlSerializer serializer, String name) { return mLegacySettings.getUserState(packageName, userId); } @Override Loading Loading @@ -935,10 +951,14 @@ public class DomainVerificationService extends SystemService * Validates parameters provided by an external caller. Checks that an ID is still live and that * any provided domains are valid. Should be called at the beginning of each API that takes in a * {@link UUID} domain set ID. * * @param userIdForFilter which user to filter app access to, or null if the caller has already * validated package visibility */ @GuardedBy("mLock") private DomainVerificationPkgState getAndValidateAttachedLocked(@NonNull UUID domainSetId, @NonNull Set<String> domains, boolean forAutoVerify) @NonNull Set<String> domains, boolean forAutoVerify, int callingUid, @Nullable Integer userIdForFilter) throws InvalidDomainSetException, NameNotFoundException { if (domainSetId == null) { throw new InvalidDomainSetException(null, null, Loading @@ -952,6 +972,13 @@ public class DomainVerificationService extends SystemService } String pkgName = pkgState.getPackageName(); if (userIdForFilter != null && mConnection.filterAppAccess(pkgName, callingUid, userIdForFilter)) { throw new InvalidDomainSetException(domainSetId, null, InvalidDomainSetException.REASON_ID_INVALID); } PackageSetting pkgSetting = mConnection.getPackageSettingLocked(pkgName); if (pkgSetting == null || pkgSetting.getPkg() == null) { throw DomainVerificationUtils.throwPackageUnavailable(pkgName); Loading