Clean up app-link verification policy
If an app claims to be the official auto-verified app for any domain
and thus the automatic handler for ACTION_VIEW / {http,https}://...
intents naming that domain, then we require that it verify as the
official app for *all* domains it purports to handle, even if the
other domains are not flagged for verify.
Bug 21335460
Change-Id: I3fdd8620defa31aea36ce738fa63ac94fc53c5f7
This commit is contained in:
@@ -731,6 +731,10 @@ public abstract class IntentResolver<F extends IntentFilter, R extends Object> {
|
||||
if (filter.getAutoVerify()) {
|
||||
if (localVerificationLOGV || debug) {
|
||||
Slog.v(TAG, " Filter verified: " + isFilterVerified(filter));
|
||||
int authorities = filter.countDataAuthorities();
|
||||
for (int z = 0; z < authorities; z++) {
|
||||
Slog.v(TAG, " " + filter.getDataAuthority(z).getHost());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -268,6 +268,7 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
static final boolean DEBUG_SETTINGS = false;
|
||||
static final boolean DEBUG_PREFERRED = false;
|
||||
static final boolean DEBUG_UPGRADE = false;
|
||||
static final boolean DEBUG_DOMAIN_VERIFICATION = false;
|
||||
private static final boolean DEBUG_BACKUP = true;
|
||||
private static final boolean DEBUG_INSTALL = false;
|
||||
private static final boolean DEBUG_REMOVE = false;
|
||||
@@ -279,7 +280,6 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
private static final boolean DEBUG_VERIFY = false;
|
||||
private static final boolean DEBUG_DEXOPT = false;
|
||||
private static final boolean DEBUG_ABI_SELECTION = false;
|
||||
private static final boolean DEBUG_DOMAIN_VERIFICATION = false;
|
||||
|
||||
private static final int RADIO_UID = Process.PHONE_UID;
|
||||
private static final int LOG_UID = Process.LOG_UID;
|
||||
@@ -11818,50 +11818,45 @@ public class PackageManagerService extends IPackageManager.Stub {
|
||||
final int verificationId = mIntentFilterVerificationToken++;
|
||||
int count = 0;
|
||||
final String packageName = pkg.packageName;
|
||||
ArrayList<String> allHosts = new ArrayList<>();
|
||||
boolean needToVerify = false;
|
||||
|
||||
synchronized (mPackages) {
|
||||
// If any filters need to be verified, then all need to be.
|
||||
for (PackageParser.Activity a : pkg.activities) {
|
||||
for (ActivityIntentInfo filter : a.intents) {
|
||||
boolean needsFilterVerification = filter.needsVerification();
|
||||
if (needsFilterVerification && needsNetworkVerificationLPr(filter)) {
|
||||
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
|
||||
"Verification needed for IntentFilter:" + filter.toString());
|
||||
mIntentFilterVerifier.addOneIntentFilterVerification(
|
||||
verifierUid, userId, verificationId, filter, packageName);
|
||||
count++;
|
||||
} else if (!needsFilterVerification) {
|
||||
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
|
||||
"No verification needed for IntentFilter:" + filter.toString());
|
||||
if (hasValidDomains(filter)) {
|
||||
ArrayList<String> hosts = filter.getHostsList();
|
||||
if (hosts.size() > 0) {
|
||||
allHosts.addAll(hosts);
|
||||
} else {
|
||||
if (allHosts.isEmpty()) {
|
||||
allHosts.add("*");
|
||||
}
|
||||
}
|
||||
if (filter.needsVerification() && needsNetworkVerificationLPr(filter)) {
|
||||
if (DEBUG_DOMAIN_VERIFICATION) {
|
||||
Slog.d(TAG, "Intent filter needs verification, so processing all filters");
|
||||
}
|
||||
needToVerify = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (needToVerify) {
|
||||
for (PackageParser.Activity a : pkg.activities) {
|
||||
for (ActivityIntentInfo filter : a.intents) {
|
||||
boolean needsFilterVerification = filter.hasWebDataURI();
|
||||
if (needsFilterVerification && needsNetworkVerificationLPr(filter)) {
|
||||
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
|
||||
"Verification needed for IntentFilter:" + filter.toString());
|
||||
mIntentFilterVerifier.addOneIntentFilterVerification(
|
||||
verifierUid, userId, verificationId, filter, packageName);
|
||||
count++;
|
||||
}
|
||||
} else {
|
||||
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
|
||||
"Verification already done for IntentFilter:" + filter.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (count > 0) {
|
||||
mIntentFilterVerifier.startVerifications(userId);
|
||||
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Started " + count
|
||||
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG, "Starting " + count
|
||||
+ " IntentFilter verification" + (count > 1 ? "s" : "")
|
||||
+ " for userId:" + userId + "!");
|
||||
+ " for userId:" + userId);
|
||||
mIntentFilterVerifier.startVerifications(userId);
|
||||
} else {
|
||||
if (DEBUG_DOMAIN_VERIFICATION) Slog.d(TAG,
|
||||
"No need to start any IntentFilter verification!");
|
||||
if (allHosts.size() > 0 && mSettings.createIntentFilterVerificationIfNeededLPw(
|
||||
packageName, allHosts) != null) {
|
||||
scheduleWriteSettingsLocked();
|
||||
if (DEBUG_DOMAIN_VERIFICATION) {
|
||||
Slog.d(TAG, "No filters or not all autoVerify for " + packageName);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -27,6 +27,7 @@ import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATIO
|
||||
import static android.content.pm.PackageManager.INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
|
||||
import static android.os.Process.SYSTEM_UID;
|
||||
import static android.os.Process.PACKAGE_INFO_GID;
|
||||
import static com.android.server.pm.PackageManagerService.DEBUG_DOMAIN_VERIFICATION;
|
||||
|
||||
import android.content.IntentFilter;
|
||||
import android.content.pm.ActivityInfo;
|
||||
@@ -977,7 +978,9 @@ final class Settings {
|
||||
IntentFilterVerificationInfo getIntentFilterVerificationLPr(String packageName) {
|
||||
PackageSetting ps = mPackages.get(packageName);
|
||||
if (ps == null) {
|
||||
Slog.w(PackageManagerService.TAG, "No package known for name: " + packageName);
|
||||
if (DEBUG_DOMAIN_VERIFICATION) {
|
||||
Slog.w(PackageManagerService.TAG, "No package known: " + packageName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
return ps.getIntentFilterVerificationInfo();
|
||||
@@ -988,20 +991,26 @@ final class Settings {
|
||||
ArrayList<String> domains) {
|
||||
PackageSetting ps = mPackages.get(packageName);
|
||||
if (ps == null) {
|
||||
Slog.w(PackageManagerService.TAG, "No package known for name: " + packageName);
|
||||
if (DEBUG_DOMAIN_VERIFICATION) {
|
||||
Slog.w(PackageManagerService.TAG, "No package known: " + packageName);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
IntentFilterVerificationInfo ivi = ps.getIntentFilterVerificationInfo();
|
||||
if (ivi == null) {
|
||||
ivi = new IntentFilterVerificationInfo(packageName, domains);
|
||||
ps.setIntentFilterVerificationInfo(ivi);
|
||||
Slog.d(PackageManagerService.TAG,
|
||||
"Creating new IntentFilterVerificationInfo for packageName: " + packageName);
|
||||
if (DEBUG_DOMAIN_VERIFICATION) {
|
||||
Slog.d(PackageManagerService.TAG,
|
||||
"Creating new IntentFilterVerificationInfo for pkg: " + packageName);
|
||||
}
|
||||
} else {
|
||||
ivi.setDomains(domains);
|
||||
Slog.d(PackageManagerService.TAG,
|
||||
"Setting domains to existing IntentFilterVerificationInfo for packageName: " +
|
||||
packageName + " and with domains: " + ivi.getDomainsString());
|
||||
if (DEBUG_DOMAIN_VERIFICATION) {
|
||||
Slog.d(PackageManagerService.TAG,
|
||||
"Setting domains to existing IntentFilterVerificationInfo for pkg: " +
|
||||
packageName + " and with domains: " + ivi.getDomainsString());
|
||||
}
|
||||
}
|
||||
return ivi;
|
||||
}
|
||||
@@ -1009,7 +1018,9 @@ final class Settings {
|
||||
int getIntentFilterVerificationStatusLPr(String packageName, int userId) {
|
||||
PackageSetting ps = mPackages.get(packageName);
|
||||
if (ps == null) {
|
||||
Slog.w(PackageManagerService.TAG, "No package known for name: " + packageName);
|
||||
if (DEBUG_DOMAIN_VERIFICATION) {
|
||||
Slog.w(PackageManagerService.TAG, "No package known: " + packageName);
|
||||
}
|
||||
return INTENT_FILTER_DOMAIN_VERIFICATION_STATUS_UNDEFINED;
|
||||
}
|
||||
int status = ps.getDomainVerificationStatusForUser(userId);
|
||||
@@ -1025,14 +1036,18 @@ final class Settings {
|
||||
// Update the status for the current package
|
||||
PackageSetting current = mPackages.get(packageName);
|
||||
if (current == null) {
|
||||
Slog.w(PackageManagerService.TAG, "No package known for name: " + packageName);
|
||||
if (DEBUG_DOMAIN_VERIFICATION) {
|
||||
Slog.w(PackageManagerService.TAG, "No package known: " + packageName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
current.setDomainVerificationStatusForUser(status, userId);
|
||||
|
||||
if (current.getIntentFilterVerificationInfo() == null) {
|
||||
Slog.w(PackageManagerService.TAG,
|
||||
"No IntentFilterVerificationInfo known for name: " + packageName);
|
||||
if (DEBUG_DOMAIN_VERIFICATION) {
|
||||
Slog.w(PackageManagerService.TAG,
|
||||
"No IntentFilterVerificationInfo known: " + packageName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
@@ -1080,7 +1095,9 @@ final class Settings {
|
||||
boolean removeIntentFilterVerificationLPw(String packageName, int userId) {
|
||||
PackageSetting ps = mPackages.get(packageName);
|
||||
if (ps == null) {
|
||||
Slog.w(PackageManagerService.TAG, "No package known for name: " + packageName);
|
||||
if (DEBUG_DOMAIN_VERIFICATION) {
|
||||
Slog.w(PackageManagerService.TAG, "No package known: " + packageName);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
ps.clearDomainVerificationStatusForUser(userId);
|
||||
@@ -1549,8 +1566,10 @@ final class Settings {
|
||||
if (verificationInfo != null && verificationInfo.getPackageName() != null) {
|
||||
serializer.startTag(null, TAG_DOMAIN_VERIFICATION);
|
||||
verificationInfo.writeToXml(serializer);
|
||||
Log.d(TAG, "Wrote domain verification for package: "
|
||||
+ verificationInfo.getPackageName());
|
||||
if (DEBUG_DOMAIN_VERIFICATION) {
|
||||
Slog.d(TAG, "Wrote domain verification for package: "
|
||||
+ verificationInfo.getPackageName());
|
||||
}
|
||||
serializer.endTag(null, TAG_DOMAIN_VERIFICATION);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user