diff --git a/qcow/src/qcow.rs b/qcow/src/qcow.rs index 8bdd8e636..fc6b73575 100755 --- a/qcow/src/qcow.rs +++ b/qcow/src/qcow.rs @@ -38,6 +38,7 @@ pub enum Error { InvalidClusterSize, InvalidIndex, InvalidL1TableOffset, + InvalidL1TableSize(u32), InvalidMagic, InvalidOffset(u64), InvalidRefcountTableOffset, @@ -83,6 +84,7 @@ impl Display for Error { InvalidClusterSize => write!(f, "invalid cluster size"), InvalidIndex => write!(f, "invalid index"), InvalidL1TableOffset => write!(f, "invalid L1 table offset"), + InvalidL1TableSize(size) => write!(f, "invalid L1 table size {}", size), InvalidMagic => write!(f, "invalid magic"), InvalidOffset(_) => write!(f, "invalid offset"), InvalidRefcountTableOffset => write!(f, "invalid refcount table offset"), @@ -387,6 +389,11 @@ impl QcowFile { 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; if cluster_bits < MIN_CLUSTER_BITS || cluster_bits > MAX_CLUSTER_BITS { 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] fn test_header_1_tb_file_min_cluster() { let mut header = test_huge_header();