Restrict updates of system packages

By declaring a <restrict-update> tag in its manifest, a system package
can restrict its update to be the singular package that has the same
given hash. An update's hash is the SHA-512 across all its APKs [i.e.
for splits, the SHA-512 is calculated over the concatenation of the
base plus all splits].

The restriction only applies to system packages.

Bug: 28398205
Change-Id: Iec493fc8ef27edee53f1d437cb0caaa78782f329
This commit is contained in:
Todd Kennedy
2016-04-28 12:26:53 -07:00
parent 8438a7297c
commit fdd241a1e0
4 changed files with 74 additions and 2 deletions

View File

@@ -159,6 +159,7 @@ public class PackageParser {
private static final String TAG_SUPPORTS_INPUT = "supports-input";
private static final String TAG_EAT_COMMENT = "eat-comment";
private static final String TAG_PACKAGE = "package";
private static final String TAG_RESTRICT_UPDATE = "restrict-update";
// These are the tags supported by child packages
private static final Set<String> CHILD_PACKAGE_TAGS = new ArraySet<>();
@@ -1639,9 +1640,9 @@ public class PackageParser {
/**
* This is the common parsing routing for handling parent and child
* packages in a base APK. The difference between parent and child
* parsing is that some targs are not supported by child packages as
* parsing is that some tags are not supported by child packages as
* well as some manifest attributes are ignored. The implementation
* assumes the calling code already handled the manifest tag if needed
* assumes the calling code has already handled the manifest tag if needed
* (this applies to the parent only).
*
* @param pkg The package which to populate
@@ -2089,6 +2090,29 @@ public class PackageParser {
// If parsing a child failed the error is already set
return null;
}
} else if (tagName.equals(TAG_RESTRICT_UPDATE)) {
if ((flags & PARSE_IS_SYSTEM_DIR) != 0) {
sa = res.obtainAttributes(parser,
com.android.internal.R.styleable.AndroidManifestRestrictUpdate);
final String hash = sa.getNonConfigurationString(
com.android.internal.R.styleable.AndroidManifestRestrictUpdate_hash, 0);
sa.recycle();
pkg.restrictUpdateHash = null;
if (hash != null) {
final int hashLength = hash.length();
final byte[] hashBytes = new byte[hashLength / 2];
for (int i = 0; i < hashLength; i += 2){
hashBytes[i/2] = (byte) ((Character.digit(hash.charAt(i), 16) << 4)
+ Character.digit(hash.charAt(i + 1), 16));
}
pkg.restrictUpdateHash = hashBytes;
}
}
XmlUtils.skipCurrentTag(parser);
} else if (RIGID_PARSER) {
outError[0] = "Bad element under <manifest>: "
+ parser.getName();
@@ -4822,6 +4846,8 @@ public class PackageParser {
*/
public boolean use32bitAbi;
public byte[] restrictUpdateHash;
public Package(String packageName) {
this.packageName = packageName;
applicationInfo.packageName = packageName;