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>
This commit is contained in:
Daniel Verkamp 2018-08-15 16:53:32 -07:00 committed by chrome-bot
parent d0a0828b2e
commit 285b682d74

View file

@ -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 {