Loading core/java/android/os/incremental/V4Signature.java +13 −3 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ public class V4Signature { public static final int HASHING_ALGORITHM_SHA256 = 1; public static final byte LOG2_BLOCK_SIZE_4096_BYTES = 12; public static final int INCFS_MAX_SIGNATURE_SIZE = 8096; // incrementalfs.h /** * IncFS hashing data. */ Loading Loading @@ -191,8 +193,12 @@ public class V4Signature { private static V4Signature readFrom(InputStream stream) throws IOException { final int version = readIntLE(stream); final byte[] hashingInfo = readBytes(stream); final byte[] signingInfo = readBytes(stream); int maxSize = INCFS_MAX_SIGNATURE_SIZE; final byte[] hashingInfo = readBytes(stream, maxSize); if (hashingInfo != null) { maxSize -= hashingInfo.length; } final byte[] signingInfo = readBytes(stream, maxSize); return new V4Signature(version, hashingInfo, signingInfo); } Loading Loading @@ -231,9 +237,13 @@ public class V4Signature { stream.write(buffer); } private static byte[] readBytes(InputStream stream) throws IOException { private static byte[] readBytes(InputStream stream, int maxSize) throws IOException { try { final int size = readIntLE(stream); if (size > maxSize) { throw new IOException( "Signature is too long. Max allowed is " + INCFS_MAX_SIGNATURE_SIZE); } final byte[] bytes = new byte[size]; readFully(stream, bytes); return bytes; Loading services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp +19 −9 Original line number Diff line number Diff line Loading @@ -171,17 +171,23 @@ static inline int32_t readLEInt32(borrowed_fd fd) { return result; } static inline std::vector<char> readBytes(borrowed_fd fd) { int32_t size = readLEInt32(fd); std::vector<char> result(size); android::base::ReadFully(fd, result.data(), size); return result; static inline bool skipBytes(borrowed_fd fd, int* max_size) { int32_t size = std::min(readLEInt32(fd), *max_size); if (size <= 0) { return false; } *max_size -= size; return (TEMP_FAILURE_RETRY(lseek64(fd.get(), size, SEEK_CUR)) >= 0); } static inline int32_t skipIdSigHeaders(borrowed_fd fd) { readLEInt32(fd); // version readBytes(fd); // hashingInfo readBytes(fd); // signingInfo // version auto version = readLEInt32(fd); int max_size = INCFS_MAX_SIGNATURE_SIZE - sizeof(version); // hashingInfo and signingInfo if (!skipBytes(fd, &max_size) || !skipBytes(fd, &max_size)) { return -1; } return readLEInt32(fd); // size of the verity tree } Loading Loading @@ -253,8 +259,12 @@ static inline InputDescs openLocalFile(JNIEnv* env, const JniIds& jni, jobject s unique_fd idsigFd = openLocalFile(env, jni, shellCommand, idsigPath); if (idsigFd.ok()) { auto treeSize = verityTreeSizeForFile(size); auto actualTreeSize = skipIdSigHeaders(idsigFd); if (actualTreeSize < 0) { ALOGE("Error reading .idsig file: wrong format."); return {}; } auto treeSize = verityTreeSizeForFile(size); if (treeSize != actualTreeSize) { ALOGE("Verity tree size mismatch: %d vs .idsig: %d.", int(treeSize), int(actualTreeSize)); Loading Loading
core/java/android/os/incremental/V4Signature.java +13 −3 Original line number Diff line number Diff line Loading @@ -41,6 +41,8 @@ public class V4Signature { public static final int HASHING_ALGORITHM_SHA256 = 1; public static final byte LOG2_BLOCK_SIZE_4096_BYTES = 12; public static final int INCFS_MAX_SIGNATURE_SIZE = 8096; // incrementalfs.h /** * IncFS hashing data. */ Loading Loading @@ -191,8 +193,12 @@ public class V4Signature { private static V4Signature readFrom(InputStream stream) throws IOException { final int version = readIntLE(stream); final byte[] hashingInfo = readBytes(stream); final byte[] signingInfo = readBytes(stream); int maxSize = INCFS_MAX_SIGNATURE_SIZE; final byte[] hashingInfo = readBytes(stream, maxSize); if (hashingInfo != null) { maxSize -= hashingInfo.length; } final byte[] signingInfo = readBytes(stream, maxSize); return new V4Signature(version, hashingInfo, signingInfo); } Loading Loading @@ -231,9 +237,13 @@ public class V4Signature { stream.write(buffer); } private static byte[] readBytes(InputStream stream) throws IOException { private static byte[] readBytes(InputStream stream, int maxSize) throws IOException { try { final int size = readIntLE(stream); if (size > maxSize) { throw new IOException( "Signature is too long. Max allowed is " + INCFS_MAX_SIGNATURE_SIZE); } final byte[] bytes = new byte[size]; readFully(stream, bytes); return bytes; Loading
services/core/jni/com_android_server_pm_PackageManagerShellCommandDataLoader.cpp +19 −9 Original line number Diff line number Diff line Loading @@ -171,17 +171,23 @@ static inline int32_t readLEInt32(borrowed_fd fd) { return result; } static inline std::vector<char> readBytes(borrowed_fd fd) { int32_t size = readLEInt32(fd); std::vector<char> result(size); android::base::ReadFully(fd, result.data(), size); return result; static inline bool skipBytes(borrowed_fd fd, int* max_size) { int32_t size = std::min(readLEInt32(fd), *max_size); if (size <= 0) { return false; } *max_size -= size; return (TEMP_FAILURE_RETRY(lseek64(fd.get(), size, SEEK_CUR)) >= 0); } static inline int32_t skipIdSigHeaders(borrowed_fd fd) { readLEInt32(fd); // version readBytes(fd); // hashingInfo readBytes(fd); // signingInfo // version auto version = readLEInt32(fd); int max_size = INCFS_MAX_SIGNATURE_SIZE - sizeof(version); // hashingInfo and signingInfo if (!skipBytes(fd, &max_size) || !skipBytes(fd, &max_size)) { return -1; } return readLEInt32(fd); // size of the verity tree } Loading Loading @@ -253,8 +259,12 @@ static inline InputDescs openLocalFile(JNIEnv* env, const JniIds& jni, jobject s unique_fd idsigFd = openLocalFile(env, jni, shellCommand, idsigPath); if (idsigFd.ok()) { auto treeSize = verityTreeSizeForFile(size); auto actualTreeSize = skipIdSigHeaders(idsigFd); if (actualTreeSize < 0) { ALOGE("Error reading .idsig file: wrong format."); return {}; } auto treeSize = verityTreeSizeForFile(size); if (treeSize != actualTreeSize) { ALOGE("Verity tree size mismatch: %d vs .idsig: %d.", int(treeSize), int(actualTreeSize)); Loading