Merge "Check if idsig size is within IncFs limits." into sc-dev

This commit is contained in:
TreeHugger Robot
2021-04-19 22:28:09 +00:00
committed by Android (Google) Code Review
2 changed files with 32 additions and 12 deletions

View File

@@ -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.
*/
@@ -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);
}
@@ -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;

View File

@@ -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
}
@@ -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));