Fix two dex file structural verification issues.
First, structural verification failed to check for inconsistencies with
the number of arguments to methods compared to the number of registers
declared by those methods.
Second, neither the dexdump nor dexlist tools would run structural
verification.
As an added bonus, I renamed the function that performs byte swapping
and structural verification to be more descriptive about what it
does.
Bug: 2716693
Change-Id: I58794713967f5bea95010084c85efe1f929ce7d1
diff --git a/libdex/CmdUtils.c b/libdex/CmdUtils.c
index 109d3e5..95e20e7 100644
--- a/libdex/CmdUtils.c
+++ b/libdex/CmdUtils.c
@@ -89,12 +89,17 @@
/*
* Map the specified DEX file read-only (possibly after expanding it into a
* temp file from a Jar). Pass in a MemMapping struct to hold the info.
+ * If the file is an unoptimized DEX file, then byte-swapping and structural
+ * verification are performed on it before the memory is made read-only.
*
* The temp file is deleted after the map succeeds.
*
* This is intended for use by tools (e.g. dexdump) that need to get a
* read-only copy of a DEX file that could be in a number of different states.
*
+ * If "tempFileName" is NULL, a default value is used. The temp file is
+ * deleted after the map succeeds.
+ *
* If "quiet" is set, don't report common errors.
*
* Returns 0 (kUTFRSuccess) on success.
@@ -150,6 +155,8 @@
}
}
+ result = kUTFRGenericFailure;
+
/*
* Pop open the (presumed) DEX file.
*/
@@ -162,13 +169,34 @@
goto bail;
}
- if (sysMapFileInShmemReadOnly(fd, pMap) != 0) {
- fprintf(stderr, "ERROR: Unable to map %s\n", fileName);
- close(fd);
+ if (sysMapFileInShmemWritableReadOnly(fd, pMap) != 0) {
+ fprintf(stderr, "ERROR: Unable to map '%s'\n", fileName);
goto bail;
}
/*
+ * This call will fail if the file exists on a filesystem that
+ * doesn't support mprotect(). If that's the case, then the file
+ * will have already been mapped private-writable by the previous
+ * call, so we don't need to do anything special if this call
+ * returns non-zero.
+ */
+ sysChangeMapAccess(pMap->addr, pMap->length, true, pMap);
+
+ if (dexSwapAndVerifyIfNecessary(pMap->addr, pMap->length)) {
+ fprintf(stderr, "ERROR: Failed structural verification of '%s'\n",
+ fileName);
+ goto bail;
+ }
+
+ /*
+ * Similar to above, this call will fail if the file wasn't ever
+ * read-only to begin with. This is innocuous, though it is
+ * undesirable from a memory hygiene perspective.
+ */
+ sysChangeMapAccess(pMap->addr, pMap->length, false, pMap);
+
+ /*
* Success! Close the file and return with the start/length in pMap.
*/
result = 0;
@@ -178,7 +206,7 @@
close(fd);
if (removeTemp) {
if (unlink(tempFileName) != 0) {
- fprintf(stderr, "Warning: unable to remove temp '%s'\n",
+ fprintf(stderr, "WARNING: unable to remove temp '%s'\n",
tempFileName);
}
}