mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-05 21:15:45 +00:00
qcow: disallow crazy l1 table sizes
Before this change, a corrupt or malicious qcow file could cause crosvm to allocate absurd amounts of memory. The fuzzer found this case, limit the L1 table size so it can't cause issues. BUG=chromium:974123 TEST=run fuzzer locally, add unit test Change-Id: Ieb6db6c87f71df726b3cc9a98404581fe32fb1ce Signed-off-by: Dylan Reid <dgreid@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/1660890 Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Tested-by: kokoro <noreply+kokoro@google.com> (cherry picked from crosvm commit 70d7bad28414e4b0d8bdf2d5eb85618a3b1e83c6) Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
parent
bd612b6e53
commit
4ba1d2274e
@ -38,6 +38,7 @@ pub enum Error {
|
|||||||
InvalidClusterSize,
|
InvalidClusterSize,
|
||||||
InvalidIndex,
|
InvalidIndex,
|
||||||
InvalidL1TableOffset,
|
InvalidL1TableOffset,
|
||||||
|
InvalidL1TableSize(u32),
|
||||||
InvalidMagic,
|
InvalidMagic,
|
||||||
InvalidOffset(u64),
|
InvalidOffset(u64),
|
||||||
InvalidRefcountTableOffset,
|
InvalidRefcountTableOffset,
|
||||||
@ -83,6 +84,7 @@ impl Display for Error {
|
|||||||
InvalidClusterSize => write!(f, "invalid cluster size"),
|
InvalidClusterSize => write!(f, "invalid cluster size"),
|
||||||
InvalidIndex => write!(f, "invalid index"),
|
InvalidIndex => write!(f, "invalid index"),
|
||||||
InvalidL1TableOffset => write!(f, "invalid L1 table offset"),
|
InvalidL1TableOffset => write!(f, "invalid L1 table offset"),
|
||||||
|
InvalidL1TableSize(size) => write!(f, "invalid L1 table size {}", size),
|
||||||
InvalidMagic => write!(f, "invalid magic"),
|
InvalidMagic => write!(f, "invalid magic"),
|
||||||
InvalidOffset(_) => write!(f, "invalid offset"),
|
InvalidOffset(_) => write!(f, "invalid offset"),
|
||||||
InvalidRefcountTableOffset => write!(f, "invalid refcount table offset"),
|
InvalidRefcountTableOffset => write!(f, "invalid refcount table offset"),
|
||||||
@ -387,6 +389,11 @@ impl QcowFile {
|
|||||||
return Err(Error::UnsupportedVersion(header.version));
|
return Err(Error::UnsupportedVersion(header.version));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure that the L1 table fits in RAM.
|
||||||
|
if u64::from(header.l1_size) > MAX_RAM_POINTER_TABLE_SIZE {
|
||||||
|
return Err(Error::InvalidL1TableSize(header.l1_size));
|
||||||
|
}
|
||||||
|
|
||||||
let cluster_bits: u32 = header.cluster_bits;
|
let cluster_bits: u32 = header.cluster_bits;
|
||||||
if cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS {
|
if cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS {
|
||||||
return Err(Error::InvalidClusterSize);
|
return Err(Error::InvalidClusterSize);
|
||||||
@ -1832,6 +1839,15 @@ mod tests {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_huge_l1_table() {
|
||||||
|
let mut header = valid_header_v3();
|
||||||
|
header[36] = 0x12;
|
||||||
|
with_basic_file(&header, |disk_file: File| {
|
||||||
|
QcowFile::from(disk_file).expect_err("Failed to create file.");
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_header_1_tb_file_min_cluster() {
|
fn test_header_1_tb_file_min_cluster() {
|
||||||
let mut header = test_huge_header();
|
let mut header = test_huge_header();
|
||||||
|
Loading…
Reference in New Issue
Block a user