diff options
author | Dylan Reid <dgreid@chromium.org> | 2019-06-28 15:19:57 +1000 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2019-07-09 17:46:22 +0000 |
commit | 93b0c02227f3acf2c6ff127976875cf3ce98c003 (patch) | |
tree | d985c8753788fb6f9d486b3b605b58f835d1e41d | |
parent | eecbccc4d9d70b2fd63681a2b3ced6a6aafe81bb (diff) | |
download | crosvm-93b0c02227f3acf2c6ff127976875cf3ce98c003.tar crosvm-93b0c02227f3acf2c6ff127976875cf3ce98c003.tar.gz crosvm-93b0c02227f3acf2c6ff127976875cf3ce98c003.tar.bz2 crosvm-93b0c02227f3acf2c6ff127976875cf3ce98c003.tar.lz crosvm-93b0c02227f3acf2c6ff127976875cf3ce98c003.tar.xz crosvm-93b0c02227f3acf2c6ff127976875cf3ce98c003.tar.zst crosvm-93b0c02227f3acf2c6ff127976875cf3ce98c003.zip |
qcow: limit the size of a qcow file
There are many corner cases when handling sizes that approach u64::max. Limit the files to 16TB. BUG=979458 TEST=Added unittest to check large disks fail Signed-off-by: Dylan Reid <dgreid@chromium.org> Change-Id: I93a87c17267ae69102f8d46ced9dbea8c686d093 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1679892 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com>
-rw-r--r-- | qcow/src/qcow.rs | 23 |
1 files changed, 22 insertions, 1 deletions
diff --git a/qcow/src/qcow.rs b/qcow/src/qcow.rs index ceaf130..fba511d 100644 --- a/qcow/src/qcow.rs +++ b/qcow/src/qcow.rs @@ -77,7 +77,11 @@ impl Display for Error { BackingFilesNotSupported => write!(f, "backing files not supported"), CompressedBlocksNotSupported => write!(f, "compressed blocks not supported"), EvictingCache(e) => write!(f, "failed to evict cache: {}", e), - FileTooBig(size) => write!(f, "file larger than max of 1TB: {}", size), + FileTooBig(size) => write!( + f, + "file larger than max of {}: {}", + MAX_QCOW_FILE_SIZE, size + ), GettingFileSize(e) => write!(f, "failed to get file size: {}", e), GettingRefcount(e) => write!(f, "failed to get refcount: {}", e), InvalidClusterIndex => write!(f, "invalid cluster index"), @@ -118,6 +122,9 @@ pub enum ImageType { Qcow2, } +// Maximum data size supported. +const MAX_QCOW_FILE_SIZE: u64 = 0x01 << 44; // 16 TB. + // QCOW magic constant that starts the header. const QCOW_MAGIC: u32 = 0x5146_49fb; // Default to a cluster size of 2^DEFAULT_CLUSTER_BITS @@ -370,6 +377,11 @@ impl QcowFile { } let cluster_size = 0x01u64 << cluster_bits; + // Limit the total size of the disk. + if header.size > MAX_QCOW_FILE_SIZE { + return Err(Error::FileTooBig(header.size)); + } + // No current support for backing files. if header.backing_file_offset != 0 { return Err(Error::BackingFilesNotSupported); @@ -1816,6 +1828,15 @@ mod tests { } #[test] + fn test_header_crazy_file_size_rejected() { + let mut header = valid_header(); + &mut header[24..32].copy_from_slice(&[0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x1e]); + with_basic_file(&header, |disk_file: File| { + QcowFile::from(disk_file).expect_err("Failed to create file."); + }); + } + + #[test] fn test_huge_l1_table() { let mut header = valid_header(); header[36] = 0x12; |