mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-18 10:35:23 +00:00
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> (cherry picked from crosvm commit 93b0c02227f3acf2c6ff127976875cf3ce98c003) Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
20f8d8d700
commit
7d6bf75138
@ -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
|
||||
@ -400,6 +407,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);
|
||||
@ -1839,6 +1851,15 @@ mod tests {
|
||||
});
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_header_crazy_file_size_rejected() {
|
||||
let mut header = valid_header_v3();
|
||||
&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_v3();
|
||||
|
Loading…
x
Reference in New Issue
Block a user