Bug 1044063

Summary: libvirt should reject qcow2v3 files
Product: Red Hat Enterprise Linux 6 Reporter: Eric Blake <eblake>
Component: libvirtAssignee: Eric Blake <eblake>
Status: CLOSED WONTFIX QA Contact: Virtualization Bugs <virt-bugs>
Severity: unspecified Docs Contact:
Priority: unspecified    
Version: 6.5CC: acathrow, bili, dyuan, eblake, mzhan, shyu, yanyang
Target Milestone: rc   
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: Doc Type: Bug Fix
Doc Text:
Story Points: ---
Clone Of: Environment:
Last Closed: 2014-04-04 21:27:01 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:

Description Eric Blake 2013-12-17 17:43:44 UTC
Description of problem:
Even though the qemu in RHEL 6 currently accepts only qcow2 v2 files (-o compat=0.10), upstream qemu is producing qcow2v3 files by default (-o compat=1.1).  While it is unlikely that someone will be creating a v3 file via Red Hat supported means, it is more likely that someone will try to reuse a qcow2 file created externally on a RHEL 6 box.  And while the image will be rejected by qemu, it would be nicer to detect the image as unsupported within libvirt for purposes of better error message quality.  Besides, I found an issue where the stock behavior of libvirt 0.10.2 (parsing a v3 file as though it were in v2 format) could cause libvirt to misbehave if upstream v3 ever adds more than 32 incompatible feature bits.

Of course, if we change our minds and teach qemu to support v3 files, then libvirt MUST support v3 files to match.

Version-Release number of selected component (if applicable):
libvirt-0.10.2-29.el6

How reproducible:
100%

Steps to Reproduce:
1. Externally create a qcow2v3 file with a backing format (qemu-img create -f qcow2 -o backing_file=path,backing_fmt=raw,compat=1.1 file), and copy it over to RHEL
2. Use libvirt APIs to inspect the file; I suspect that virStorageVolGetXMLDesc is the best bet, although I haven't actually tested it (I first found the problem by a failure in virstoragetest in the testsuite, but that calls into internal API rather than using libvirt API).  It may require creating a chain of several files to get the behavior, such as:
raw <- qcow2v3 file <- qcow2v2 file
with both qcow2 files correctly designating the backing format.
3.

Actual results:
If told that an image is qcow2, libvirt blindly attempts to parse the file as if it is a v2 file, rather than validating that it is actually a v2 file.  In doing so, it fails to find the backing format attribute; if probing is enabled, this means it will probe the backing file even though it shouldn't.  While probing incorrectly is a CVE if done automatically, I don't think this is a new security issue, if only because a user already has to manually enable libvirt probing and should already be aware of the consequences of a probe gone wrong.

Expected results:
Either we backport the upstream commit to learn v3 parsing, or we use a stable-branch downstream patch that flat out refuses to handle v3 files as unknown.  I'm working on a patch for the upstream v0.10.2-maint branch along the latter approach.

Additional info:
Here's the upstream commit for v3 parsing; but I think it is a bit invasive if we decide that a simpler solution of just rejecting v3 files is better (since that matches qemu's behavior).
commit a1ee8e18c91ed5c0fda23ec4e677b3ac62890250
Author: Ján Tomko <jtomko>
Date:   Tue May 7 17:27:43 2013 +0200

    util: add support for qcow2v3 image detection
    
    Detect qcow2 images with version 3 in the image header as
    VIR_STORAGE_FILE_QCOW2.
    
    These images have a feature bitfield, with just one feature supported
    so far: lazy_refcounts.
    
    The header length changed too, moving the location of the backing
    format name.

Comment 1 Eric Blake 2013-12-18 03:20:48 UTC
For my own reference: upstream v0.10.2-maint (F18) does not contain the virstoragetest.c (right now, that was a RHEL-only backport for bug 903248).  Upstream 1.0.3 was the first to contain the test to expose the misbehavior on v3 images (although the misbehavior is latent and existed before the test).  Meanwhile, 1.1.0 was the first to support qcow2v3.  Which means that upstream v1.0.5-maint (F19) has the same problem as RHEL 6.  Even though F20 and rawhide are new enough to not have the problem, I would like to at least get the F19 situation working so that the RHEL solution will backport from v1.0.5-maint rather than being a RHEL-only patch.

Comment 2 Yang Yang 2014-02-26 06:31:57 UTC
Reproduced on 
kenerl: 2.6.32-431.7.1.el6.x86_64
libvirt-0.10.2-29.el6_5.4.x86_64

Steps:

On RHEL7

1. Create a raw img test.img

# qemu-img create /var/lib/libvirt/images/test.img 1G

2. Create a qcow2v3 file

#qemu-img create -f qcow2 -o backing_file=test.img,backing_fmt=raw,compat=1.1 file

3. # qemu-img info file
image: file
file format: qcow2
virtual size: 1.0G (1073741824 bytes)
disk size: 196K
cluster_size: 65536
backing file: test.img
backing file format: raw
Format specific information:
    compat: 1.1
    lazy refcounts: false

4. Copy the qcow2v3 file to a RHEL6.5 box

# scp file 10.66.4.201:/var/lib/libvirt/images

On RHEL6.5

5.  Refresh the default pool

# virsh pool-refresh default

6. check the qcow2v3 file's xml

# virsh vol-dumpxml file default

7. attach the qcow2v3 to guest
# virsh attach-disk guest file vdb

Actual result:
6. 
# virsh vol-dumpxml file default
 <volume>
  <name>file</name>
  <key>/var/lib/libvirt/images/file</key>
  <source>
  </source>
  <capacity unit='bytes'>197120</capacity>
  <allocation unit='bytes'>200704</allocation>
  <target>
    <path>/var/lib/libvirt/images/file</path>
    <format type='raw'/>
    <permissions>
      <mode>0644</mode>
      <owner>0</owner>
      <group>0</group>
      <label>unconfined_u:object_r:virt_image_t:s0</label>
    </permissions>
    <timestamps>
      <atime>1393394606.514868671</atime>
      <mtime>1393394596.798868684</mtime>
      <ctime>1393394596.798868684</ctime>
    </timestamps>
  </target>
</volume>

7. # virsh attach-disk guest file vdb
Disk attached successfully

Expected results:
libvirt should reject qcow version 3 file.
step 6 and 7 should output some error message like:
'image' uses a qcow2 feature which is not supported by this libvirt version: QCOW version 3

Comment 4 RHEL Program Management 2014-04-04 21:27:01 UTC
Development Management has reviewed and declined this request.
You may appeal this decision by reopening this request.