summary refs log tree commit diff
path: root/qcow
diff options
context:
space:
mode:
authorDylan Reid <dgreid@chromium.org>2018-02-22 12:58:18 -0800
committerchrome-bot <chrome-bot@chromium.org>2018-02-23 03:37:10 -0800
commit328bfd29592461ded96d42556c3141100348ea1c (patch)
tree4c68046982661928da8dca68d65d3e5660ca0044 /qcow
parentc79de2d0b2b75c18adf1b9f1779a6b482247531e (diff)
downloadcrosvm-328bfd29592461ded96d42556c3141100348ea1c.tar
crosvm-328bfd29592461ded96d42556c3141100348ea1c.tar.gz
crosvm-328bfd29592461ded96d42556c3141100348ea1c.tar.bz2
crosvm-328bfd29592461ded96d42556c3141100348ea1c.tar.lz
crosvm-328bfd29592461ded96d42556c3141100348ea1c.tar.xz
crosvm-328bfd29592461ded96d42556c3141100348ea1c.tar.zst
crosvm-328bfd29592461ded96d42556c3141100348ea1c.zip
qcow: check more address addition for overflow
Check that two address calculations don't overflow. Return an error if
they do. Thanks cargo fuzz.

Change-Id: I9dd301c4e08516cea8456f1ea313d62582979da0
Signed-off-by: Dylan Reid <dgreid@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/932646
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Diffstat (limited to 'qcow')
-rw-r--r--qcow/src/qcow.rs8
1 files changed, 5 insertions, 3 deletions
diff --git a/qcow/src/qcow.rs b/qcow/src/qcow.rs
index 08a295c..261c737 100644
--- a/qcow/src/qcow.rs
+++ b/qcow/src/qcow.rs
@@ -369,7 +369,8 @@ impl QcowFile {
         } else {
             l2_addr_from_table
         };
-        let l2_entry_addr: u64 = l2_addr + self.l2_address_offset(address);
+        let l2_entry_addr: u64 = l2_addr.checked_add(self.l2_address_offset(address))
+                .ok_or(std::io::Error::from_raw_os_error(EINVAL))?;
         let cluster_addr_disk: u64 = read_u64_from_offset(&mut self.file, l2_entry_addr)?;
         let cluster_addr_from_table: u64 = cluster_addr_disk & L2_TABLE_OFFSET_MASK;
         let cluster_addr = if cluster_addr_from_table == 0 {
@@ -414,8 +415,9 @@ impl QcowFile {
         let refcount_block_entries = cluster_size * size_of::<u64>() as u64 / self.refcount_bits;
         let refcount_block_index = (address / cluster_size) % refcount_block_entries;
         let refcount_table_index = (address / cluster_size) / refcount_block_entries;
-        let refcount_block_entry_addr =
-            self.header.refcount_table_offset + refcount_table_index * size_of::<u64>() as u64;
+        let refcount_block_entry_addr = self.header.refcount_table_offset
+                .checked_add(refcount_table_index * size_of::<u64>() as u64)
+                .ok_or(std::io::Error::from_raw_os_error(EINVAL))?;
         let refcount_block_address_from_file =
             read_u64_from_offset(&mut self.file, refcount_block_entry_addr)?;
         let refcount_block_address = if refcount_block_address_from_file == 0 {