summary refs log tree commit diff
path: root/qcow
diff options
context:
space:
mode:
authorDaniel Verkamp <dverkamp@chromium.org>2018-08-15 16:53:32 -0700
committerchrome-bot <chrome-bot@chromium.org>2018-08-17 11:18:12 -0700
commit285b682d74f3d1528897e5da6d6be9165c3e6914 (patch)
tree5a478a95ebfba8f6227ee031204a93c8e96d9f3b /qcow
parentd0a0828b2e3a5dde4338f5b58ce355c75a79fa9d (diff)
downloadcrosvm-285b682d74f3d1528897e5da6d6be9165c3e6914.tar
crosvm-285b682d74f3d1528897e5da6d6be9165c3e6914.tar.gz
crosvm-285b682d74f3d1528897e5da6d6be9165c3e6914.tar.bz2
crosvm-285b682d74f3d1528897e5da6d6be9165c3e6914.tar.lz
crosvm-285b682d74f3d1528897e5da6d6be9165c3e6914.tar.xz
crosvm-285b682d74f3d1528897e5da6d6be9165c3e6914.tar.zst
crosvm-285b682d74f3d1528897e5da6d6be9165c3e6914.zip
qcow: fix check for compressed cluster bit
The bit that indicates a compressed cluster in the qcow2 format is
stored in the L2 table entry (cluster descriptor), but the code was
checking for it in the L1 table entry.

Spotted by inspection based on the qcow2 format documentation (QEMU
docs/interop/qcow2.txt).

This has no impact in normal crosvm use cases, since crosvm never writes
compressed clusters; the only case where it could have any effect would
be when using a QEMU-created qcow2 image with compressed clusters, which
would have returned incorrect data from a read instead of failing the
read request as intended.

BUG=chromium:874699

Change-Id: Ic247490dcac5440fab8e4d34d24ffe6fe9ab3110
Signed-off-by: Daniel Verkamp <dverkamp@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/1176733
Reviewed-by: Stephen Barber <smbarber@chromium.org>
Reviewed-by: Dylan Reid <dgreid@chromium.org>
Diffstat (limited to 'qcow')
-rw-r--r--qcow/src/qcow.rs6
1 files changed, 3 insertions, 3 deletions
diff --git a/qcow/src/qcow.rs b/qcow/src/qcow.rs
index 9124ab1..2d49968 100644
--- a/qcow/src/qcow.rs
+++ b/qcow/src/qcow.rs
@@ -401,9 +401,6 @@ impl QcowFile {
             }
         }
         let l2_addr_disk = read_u64_from_offset(&mut self.file, l1_entry_offset)?;
-        if l2_addr_disk & COMPRESSED_FLAG != 0 {
-            return Err(std::io::Error::from_raw_os_error(ENOTSUP));
-        }
         let l2_addr_from_table: u64 = l2_addr_disk & L1_TABLE_OFFSET_MASK;
         let l2_addr = if l2_addr_from_table == 0 {
             if allocate {
@@ -417,6 +414,9 @@ impl QcowFile {
         let l2_entry_addr: u64 = l2_addr.checked_add(self.l2_address_offset(address))
                 .ok_or_else(|| std::io::Error::from_raw_os_error(EINVAL))?;
         let cluster_addr_disk: u64 = read_u64_from_offset(&mut self.file, l2_entry_addr)?;
+        if cluster_addr_disk & COMPRESSED_FLAG != 0 {
+            return Err(std::io::Error::from_raw_os_error(ENOTSUP));
+        }
         let cluster_addr_from_table: u64 = cluster_addr_disk & L2_TABLE_OFFSET_MASK;
         let cluster_addr = if cluster_addr_from_table == 0 {
             if allocate {