@@ -430,6 +430,26 @@ image). Rather, any changes to the backing chain should be performed
with ``qemu-img rebase -u`` either before or after the remaining
changes being performed by amend, as appropriate.
+qemu-img backing file without format (since 5.1)
+''''''''''''''''''''''''''''''''''''''''''''''''
+
+The use of ``qemu-img create``, ``qemu-img rebase``, or ``qemu-img
+convert`` to create or modify an image that depends on a backing file
+now recommends that an explicit backing format be provided. This is
+for safety: if QEMU probes a different format than what you thought,
+the data presented to the guest will be corrupt; similarly, presenting
+a raw image to a guest allows a potential security exploit if a future
+probe sees a non-raw image based on guest writes.
+
+To avoid the warning message, or even future refusal to create an
+unsafe image, you must pass ``-o backing_fmt=`` (or the shorthand
+``-F`` during create) to specify the intended backing format. You may
+use ``qemu-img rebase -u`` to retroactively add a backing format to an
+existing image. However, be aware that there are already potential
+security risks to blindly using ``qemu-img info`` to probe the format
+of an untrusted backing image, when deciding what format to add into
+an existing image.
+
Backwards compatibility
-----------------------
@@ -6161,6 +6161,26 @@ void bdrv_img_create(const char *filename, const char *fmt,
error_append_hint(&local_err, "Could not open backing image.\n");
goto out;
} else {
+ if (!backing_fmt) {
+ warn_report("Deprecated use of backing file without explicit "
+ "backing format (detected format of %s)",
+ bs->drv->format_name);
+ if (bs->drv != &bdrv_raw) {
+ /*
+ * A probe of raw deserves the most attention:
+ * leaving the backing format out of the image
+ * will ensure bs->probed is set (ensuring we
+ * don't accidentally commit into the backing
+ * file), and allow more spots to warn the users
+ * to fix their toolchain when opening this image
+ * later. For other images, we can safely record
+ * the format that we probed.
+ */
+ backing_fmt = bs->drv->format_name;
+ qemu_opt_set(opts, BLOCK_OPT_BACKING_FMT, backing_fmt,
+ NULL);
+ }
+ }
if (size == -1) {
/* Opened BS, have no size */
size = bdrv_getlength(bs);
@@ -6174,7 +6194,12 @@ void bdrv_img_create(const char *filename, const char *fmt,
}
bdrv_unref(bs);
}
- } /* (backing_file && !(flags & BDRV_O_NO_BACKING)) */
+ /* (backing_file && !(flags & BDRV_O_NO_BACKING)) */
+ } else if (backing_file && !backing_fmt) {
+ warn_report("Deprecated use of unopened backing file without "
+ "explicit backing format, use of this image requires "
+ "potentially unsafe format probing");
+ }
if (size == -1) {
error_setg(errp, "Image creation needs a size parameter");
@@ -2523,6 +2523,13 @@ static int img_convert(int argc, char **argv)
goto out;
}
+ if (out_baseimg_param) {
+ if (!qemu_opt_get(opts, BLOCK_OPT_BACKING_FMT)) {
+ warn_report("Deprecated use of backing file without explicit "
+ "backing format");
+ }
+ }
+
/* Check if compression is supported */
if (s.compressed) {
bool encryption =
@@ -3804,7 +3811,7 @@ static int img_rebase(int argc, char **argv)
* doesn't change when we switch the backing file.
*/
if (out_baseimg && *out_baseimg) {
- ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt, false);
+ ret = bdrv_change_backing_file(bs, out_baseimg, out_basefmt, true);
} else {
ret = bdrv_change_backing_file(bs, NULL, NULL, false);
}
@@ -42,9 +42,16 @@ _unsupported_proto vxhs
# qcow2.py does not work too well with external data files
_unsupported_imgopts data_file
+# Intentionally specify backing file without backing format; demonstrate
+# the difference in warning messages when backing file could be probed.
+# Note that only a non-raw probe result will affect the resulting image.
+truncate --size=64M "$TEST_IMG.orig"
+_make_test_img -b "$TEST_IMG.orig" 64M
TEST_IMG="$TEST_IMG.base" _make_test_img 64M
+$QEMU_IMG convert -O qcow2 -B "$TEST_IMG.orig" "$TEST_IMG.orig" "$TEST_IMG"
_make_test_img -b "$TEST_IMG.base" 64M
+_make_test_img -u -b "$TEST_IMG.base" 64M
# Set an invalid backing file format
$PYTHON qcow2.py "$TEST_IMG" add-header-ext 0xE2792ACA "foo"
@@ -55,6 +62,11 @@ _img_info
$QEMU_IO -c "open $TEST_IMG" -c "read 0 4k" 2>&1 | _filter_qemu_io | _filter_testdir
$QEMU_IO -c "open -o backing.driver=$IMGFMT $TEST_IMG" -c "read 0 4k" | _filter_qemu_io
+# Rebase the image, to show that omitting backing format triggers a warning,
+# but probing now lets us use the backing file.
+$QEMU_IMG rebase -u -b "$TEST_IMG.base" "$TEST_IMG"
+$QEMU_IO -c "open $TEST_IMG" -c "read 0 4k" 2>&1 | _filter_qemu_io | _filter_testdir
+
# success, all done
echo '*** done'
rm -f $seq.full
@@ -1,5 +1,11 @@
QA output created by 114
+qemu-img: warning: Deprecated use of backing file without explicit backing format (detected format of raw)
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.orig
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=67108864
+qemu-img: warning: Deprecated use of backing file without explicit backing format
+qemu-img: warning: Deprecated use of backing file without explicit backing format (detected format of IMGFMT)
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=IMGFMT
+qemu-img: warning: Deprecated use of unopened backing file without explicit backing format, use of this image requires potentially unsafe format probing
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 backing_file=TEST_DIR/t.IMGFMT.base
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
@@ -11,4 +17,7 @@ qemu-io: can't open device TEST_DIR/t.qcow2: Could not open backing file: Unknow
no file open, try 'help open'
read 4096/4096 bytes at offset 0
4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+qemu-img: warning: Deprecated use of backing file without explicit backing format, use of this image requires potentially unsafe format probing
+read 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
*** done
@@ -2,7 +2,8 @@ QA output created by 293
== qcow backed by qcow ==
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=33554432
-Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 backing_file=TEST_DIR/t.IMGFMT.base
+qemu-img: warning: Deprecated use of backing file without explicit backing format (detected format of IMGFMT)
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 backing_file=TEST_DIR/t.IMGFMT.base backing_fmt=IMGFMT
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 32 MiB (33554432 bytes)
@@ -35,6 +36,7 @@ cluster_size: 512
backing file: TEST_DIR/t.IMGFMT.base
== qcow backed by raw ==
+qemu-img: warning: Deprecated use of backing file without explicit backing format (detected format of raw)
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=33554432 backing_file=TEST_DIR/t.IMGFMT.base
image: TEST_DIR/t.IMGFMT
file format: IMGFMT