qcow2/qcow: protect against uninitialized encryption key
commit8336aafae1451d54c81dd2b187b45f7c45d2428e
authorDaniel P. Berrange <berrange@redhat.com>
Tue, 12 May 2015 16:09:18 +0000 (12 17:09 +0100)
committerKevin Wolf <kwolf@redhat.com>
Fri, 22 May 2015 15:08:01 +0000 (22 17:08 +0200)
tree9522e81e80c456021576ad40e1e96b49d9284303
parentaa4f592a1dd9aea5f5c36f6ff4b22b5bd208162a
qcow2/qcow: protect against uninitialized encryption key

When a qcow[2] file is opened, if the header reports an
encryption method, this is used to set the 'crypt_method_header'
field on the BDRVQcow[2]State struct, and the 'encrypted' flag
in the BDRVState struct.

When doing I/O operations, the 'crypt_method' field on the
BDRVQcow[2]State struct is checked to determine if encryption
needs to be applied.

The crypt_method_header value is copied into crypt_method when
the bdrv_set_key() method is called.

The QEMU code which opens a block device is expected to always
do a check

   if (bdrv_is_encrypted(bs)) {
       bdrv_set_key(bs, ....key...);
   }

If code forgets to do this, then 'crypt_method' is never set
and so when I/O is performed, QEMU writes plain text data
into a sector which is expected to contain cipher text, or
when reading, will return cipher text instead of plain
text.

Change the qcow[2] code to consult bs->encrypted when deciding
whether encryption is required, and assert(s->crypt_method)
to protect against cases where the caller forgets to set the
encryption key.

Also put an assert in the set_key methods to protect against
the case where the caller sets an encryption key on a block
device that does not have encryption

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
block/qcow.c
block/qcow2-cluster.c
block/qcow2.c