mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-06 02:25: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>
This commit is contained in:
parent
eecbccc4d9
commit
93b0c02227
1 changed files with 22 additions and 1 deletions
|
@ -77,7 +77,11 @@ impl Display for Error {
|
||||||
BackingFilesNotSupported => write!(f, "backing files not supported"),
|
BackingFilesNotSupported => write!(f, "backing files not supported"),
|
||||||
CompressedBlocksNotSupported => write!(f, "compressed blocks not supported"),
|
CompressedBlocksNotSupported => write!(f, "compressed blocks not supported"),
|
||||||
EvictingCache(e) => write!(f, "failed to evict cache: {}", e),
|
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),
|
GettingFileSize(e) => write!(f, "failed to get file size: {}", e),
|
||||||
GettingRefcount(e) => write!(f, "failed to get refcount: {}", e),
|
GettingRefcount(e) => write!(f, "failed to get refcount: {}", e),
|
||||||
InvalidClusterIndex => write!(f, "invalid cluster index"),
|
InvalidClusterIndex => write!(f, "invalid cluster index"),
|
||||||
|
@ -118,6 +122,9 @@ pub enum ImageType {
|
||||||
Qcow2,
|
Qcow2,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Maximum data size supported.
|
||||||
|
const MAX_QCOW_FILE_SIZE: u64 = 0x01 << 44; // 16 TB.
|
||||||
|
|
||||||
// QCOW magic constant that starts the header.
|
// QCOW magic constant that starts the header.
|
||||||
const QCOW_MAGIC: u32 = 0x5146_49fb;
|
const QCOW_MAGIC: u32 = 0x5146_49fb;
|
||||||
// Default to a cluster size of 2^DEFAULT_CLUSTER_BITS
|
// Default to a cluster size of 2^DEFAULT_CLUSTER_BITS
|
||||||
|
@ -370,6 +377,11 @@ impl QcowFile {
|
||||||
}
|
}
|
||||||
let cluster_size = 0x01u64 << cluster_bits;
|
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.
|
// No current support for backing files.
|
||||||
if header.backing_file_offset != 0 {
|
if header.backing_file_offset != 0 {
|
||||||
return Err(Error::BackingFilesNotSupported);
|
return Err(Error::BackingFilesNotSupported);
|
||||||
|
@ -1815,6 +1827,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]
|
#[test]
|
||||||
fn test_huge_l1_table() {
|
fn test_huge_l1_table() {
|
||||||
let mut header = valid_header();
|
let mut header = valid_header();
|
||||||
|
|
Loading…
Reference in a new issue