Merge "Check if idsig size is within IncFs limits." into sc-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
23292d7dee
@@ -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;
|
||||
|
||||
@@ -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));
|
||||
|
||||
Reference in New Issue
Block a user