Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 23292d7d authored by TreeHugger Robot's avatar TreeHugger Robot Committed by Android (Google) Code Review
Browse files

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

parents 7f0b9867 c863792d
Loading
Loading
Loading
Loading
+13 −3
Original line number Diff line number Diff line
@@ -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;
+19 −9
Original line number Diff line number Diff line
@@ -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));