!980 [sync] PR-972: QEMU update to verssion 6.2.0-96:

From: @openeuler-sync-bot 
Reviewed-by: @imxcc 
Signed-off-by: @imxcc
This commit is contained in:
openeuler-ci-bot 2024-07-12 02:24:24 +00:00 committed by Gitee
commit 8461babc0a
No known key found for this signature in database
GPG Key ID: 173E9B9CA92EEF8F
13 changed files with 1686 additions and 1 deletions

View File

@ -0,0 +1,229 @@
From effc2c56f7b5390fbe6041d3a6ecf4026371bc25 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Thu, 25 Apr 2024 14:56:02 +0200
Subject: [PATCH] block: Parse filenames only when explicitly requested
(CVE-2024-4467)
When handling image filenames from legacy options such as -drive or from
tools, these filenames are parsed for protocol prefixes, including for
the json:{} pseudo-protocol.
This behaviour is intended for filenames that come directly from the
command line and for backing files, which may come from the image file
itself. Higher level management tools generally take care to verify that
untrusted images don't contain a bad (or any) backing file reference;
'qemu-img info' is a suitable tool for this.
However, for other files that can be referenced in images, such as
qcow2 data files or VMDK extents, the string from the image file is
usually not verified by management tools - and 'qemu-img info' wouldn't
be suitable because in contrast to backing files, it already opens these
other referenced files. So here the string should be interpreted as a
literal local filename. More complex configurations need to be specified
explicitly on the command line or in QMP.
This patch changes bdrv_open_inherit() so that it only parses filenames
if a new parameter parse_filename is true. It is set for the top level
in bdrv_open(), for the file child and for the backing file child. All
other callers pass false and disable filename parsing this way.
Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Signed-off-by: liuxiangdong <liuxiangdong5@huawei.com>
---
block.c | 75 ++++++++++++++++++++++++++++++++++++++-------------------
1 file changed, 50 insertions(+), 25 deletions(-)
diff --git a/block.c b/block.c
index 7b58fe57f8..a91117abda 100644
--- a/block.c
+++ b/block.c
@@ -85,6 +85,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
BlockDriverState *parent,
const BdrvChildClass *child_class,
BdrvChildRole child_role,
+ bool parse_filename,
Error **errp);
static bool bdrv_recurse_has_child(BlockDriverState *bs,
@@ -1929,7 +1930,8 @@ static void parse_json_protocol(QDict *options, const char **pfilename,
* block driver has been specified explicitly.
*/
static int bdrv_fill_options(QDict **options, const char *filename,
- int *flags, Error **errp)
+ int *flags, bool allow_parse_filename,
+ Error **errp)
{
const char *drvname;
bool protocol = *flags & BDRV_O_PROTOCOL;
@@ -1969,7 +1971,7 @@ static int bdrv_fill_options(QDict **options, const char *filename,
if (protocol && filename) {
if (!qdict_haskey(*options, "filename")) {
qdict_put_str(*options, "filename", filename);
- parse_filename = true;
+ parse_filename = allow_parse_filename;
} else {
error_setg(errp, "Can't specify 'file' and 'filename' options at "
"the same time");
@@ -3442,7 +3444,8 @@ int bdrv_open_backing_file(BlockDriverState *bs, QDict *parent_options,
}
backing_hd = bdrv_open_inherit(backing_filename, reference, options, 0, bs,
- &child_of_bds, bdrv_backing_role(bs), errp);
+ &child_of_bds, bdrv_backing_role(bs), true,
+ errp);
if (!backing_hd) {
bs->open_flags |= BDRV_O_NO_BACKING;
error_prepend(errp, "Could not open backing file: ");
@@ -3475,7 +3478,8 @@ free_exit:
static BlockDriverState *
bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
BlockDriverState *parent, const BdrvChildClass *child_class,
- BdrvChildRole child_role, bool allow_none, Error **errp)
+ BdrvChildRole child_role, bool allow_none,
+ bool parse_filename, Error **errp)
{
BlockDriverState *bs = NULL;
QDict *image_options;
@@ -3506,7 +3510,8 @@ bdrv_open_child_bs(const char *filename, QDict *options, const char *bdref_key,
}
bs = bdrv_open_inherit(filename, reference, image_options, 0,
- parent, child_class, child_role, errp);
+ parent, child_class, child_role, parse_filename,
+ errp);
if (!bs) {
goto done;
}
@@ -3516,6 +3521,26 @@ done:
return bs;
}
+static BdrvChild *bdrv_open_child_common(const char *filename,
+ QDict *options, const char *bdref_key,
+ BlockDriverState *parent,
+ const BdrvChildClass *child_class,
+ BdrvChildRole child_role,
+ bool allow_none, bool parse_filename,
+ Error **errp)
+{
+ BlockDriverState *bs;
+
+ bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class,
+ child_role, allow_none, parse_filename, errp);
+ if (bs == NULL) {
+ return NULL;
+ }
+
+ return bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
+ errp);
+}
+
/*
* Opens a disk image whose options are given as BlockdevRef in another block
* device's options.
@@ -3537,20 +3562,15 @@ BdrvChild *bdrv_open_child(const char *filename,
BdrvChildRole child_role,
bool allow_none, Error **errp)
{
- BlockDriverState *bs;
-
- bs = bdrv_open_child_bs(filename, options, bdref_key, parent, child_class,
- child_role, allow_none, errp);
- if (bs == NULL) {
- return NULL;
- }
-
- return bdrv_attach_child(parent, bs, bdref_key, child_class, child_role,
- errp);
+ return bdrv_open_child_common(filename, options, bdref_key, parent,
+ child_class, child_role, allow_none, false,
+ errp);
}
/*
- * Wrapper on bdrv_open_child() for most popular case: open primary child of bs.
+ * This does mostly the same as bdrv_open_child(), but for opening the primary
+ * child of a node. A notable difference from bdrv_open_child() is that it
+ * enables filename parsing for protocol names (including json:).
*/
int bdrv_open_file_child(const char *filename,
QDict *options, const char *bdref_key,
@@ -3561,8 +3581,8 @@ int bdrv_open_file_child(const char *filename,
role = parent->drv->is_filter ?
(BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE;
- parent->file = bdrv_open_child(filename, options, bdref_key, parent,
- &child_of_bds, role, false, errp);
+ parent->file = bdrv_open_child_common(filename, options, bdref_key, parent,
+ &child_of_bds, role, false, true, errp);
return parent->file ? 0 : -EINVAL;
}
@@ -3602,7 +3622,8 @@ BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
}
- bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, errp);
+ bs = bdrv_open_inherit(NULL, reference, qdict, 0, NULL, NULL, 0, false,
+ errp);
obj = NULL;
qobject_unref(obj);
visit_free(v);
@@ -3693,6 +3714,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
BlockDriverState *parent,
const BdrvChildClass *child_class,
BdrvChildRole child_role,
+ bool parse_filename,
Error **errp)
{
int ret;
@@ -3736,9 +3758,11 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
}
/* json: syntax counts as explicit options, as if in the QDict */
- parse_json_protocol(options, &filename, &local_err);
- if (local_err) {
- goto fail;
+ if (parse_filename) {
+ parse_json_protocol(options, &filename, &local_err);
+ if (local_err) {
+ goto fail;
+ }
}
bs->explicit_options = qdict_clone_shallow(options);
@@ -3763,7 +3787,8 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
parent->open_flags, parent->options);
}
- ret = bdrv_fill_options(&options, filename, &flags, &local_err);
+ ret = bdrv_fill_options(&options, filename, &flags, parse_filename,
+ &local_err);
if (ret < 0) {
goto fail;
}
@@ -3832,7 +3857,7 @@ static BlockDriverState *bdrv_open_inherit(const char *filename,
file_bs = bdrv_open_child_bs(filename, options, "file", bs,
&child_of_bds, BDRV_CHILD_IMAGE,
- true, &local_err);
+ true, true, &local_err);
if (local_err) {
goto fail;
}
@@ -3977,7 +4002,7 @@ BlockDriverState *bdrv_open(const char *filename, const char *reference,
QDict *options, int flags, Error **errp)
{
return bdrv_open_inherit(filename, reference, options, flags, NULL,
- NULL, 0, errp);
+ NULL, 0, true, errp);
}
/* Return true if the NULL-terminated @list contains @str */
--
2.41.0.windows.1

View File

@ -0,0 +1,542 @@
From 4045020d37da7a7a70b5175b3fb7d022e0bdb47f Mon Sep 17 00:00:00 2001
From: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Date: Tue, 26 Jul 2022 23:11:21 +0300
Subject: [PATCH] block: introduce bdrv_open_file_child() helper
Almost all drivers call bdrv_open_child() similarly. Let's create a
helper for this.
The only not updated drivers that call bdrv_open_child() to set
bs->file are raw-format and snapshot-access:
raw-format sometimes want to have filtered child but
don't set drv->is_filter to true.
snapshot-access wants only DATA | PRIMARY
Possibly we should implement drv->is_filter_func() handler, to consider
raw-format as filter when it works as filter.. But it's another story.
Note also, that we decrease assignments to bs->file in code: it helps
us restrict modifying this field in further commit.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Reviewed-by: Hanna Reitz <hreitz@redhat.com>
Message-Id: <20220726201134.924743-3-vsementsov@yandex-team.ru>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: liuxiangdong <liuxiangdong5@huawei.com>
---
block.c | 18 ++++++++++++++++++
block/blkdebug.c | 9 +++------
block/blklogwrites.c | 7 ++-----
block/blkreplay.c | 7 ++-----
block/blkverify.c | 9 +++------
block/bochs.c | 7 +++----
block/cloop.c | 7 +++----
block/copy-before-write.c | 9 ++++-----
block/copy-on-read.c | 9 ++++-----
block/crypto.c | 11 ++++++-----
block/dmg.c | 7 +++----
block/filter-compress.c | 8 +++-----
block/parallels.c | 7 +++----
block/preallocate.c | 9 ++++-----
block/qcow.c | 6 ++----
block/qcow2.c | 8 ++++----
block/qed.c | 8 ++++----
block/replication.c | 8 +++-----
block/throttle.c | 8 +++-----
block/vdi.c | 7 +++----
block/vhdx.c | 7 +++----
block/vmdk.c | 7 +++----
block/vpc.c | 7 +++----
include/block/block.h | 3 +++
24 files changed, 92 insertions(+), 101 deletions(-)
diff --git a/block.c b/block.c
index 75083139d1..7b58fe57f8 100644
--- a/block.c
+++ b/block.c
@@ -3549,6 +3549,24 @@ BdrvChild *bdrv_open_child(const char *filename,
errp);
}
+/*
+ * Wrapper on bdrv_open_child() for most popular case: open primary child of bs.
+ */
+int bdrv_open_file_child(const char *filename,
+ QDict *options, const char *bdref_key,
+ BlockDriverState *parent, Error **errp)
+{
+ BdrvChildRole role;
+
+ role = parent->drv->is_filter ?
+ (BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY) : BDRV_CHILD_IMAGE;
+
+ parent->file = bdrv_open_child(filename, options, bdref_key, parent,
+ &child_of_bds, role, false, errp);
+
+ return parent->file ? 0 : -EINVAL;
+}
+
/*
* TODO Future callers may need to specify parent/child_class in order for
* option inheritance to work. Existing callers use it for the root node.
diff --git a/block/blkdebug.c b/block/blkdebug.c
index bbf2948703..5fcfc8ac6f 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -503,12 +503,9 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
}
/* Open the image file */
- bs->file = bdrv_open_child(qemu_opt_get(opts, "x-image"), options, "image",
- bs, &child_of_bds,
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
- false, errp);
- if (!bs->file) {
- ret = -EINVAL;
+ ret = bdrv_open_file_child(qemu_opt_get(opts, "x-image"), options, "image",
+ bs, errp);
+ if (ret < 0) {
goto out;
}
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
index f7a251e91f..f66a617eb3 100644
--- a/block/blklogwrites.c
+++ b/block/blklogwrites.c
@@ -155,11 +155,8 @@ static int blk_log_writes_open(BlockDriverState *bs, QDict *options, int flags,
}
/* Open the file */
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY, false,
- errp);
- if (!bs->file) {
- ret = -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
goto fail;
}
diff --git a/block/blkreplay.c b/block/blkreplay.c
index dcbe780ddb..76a0b8d12a 100644
--- a/block/blkreplay.c
+++ b/block/blkreplay.c
@@ -26,11 +26,8 @@ static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags,
int ret;
/* Open the image file */
- bs->file = bdrv_open_child(NULL, options, "image", bs, &child_of_bds,
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
- false, errp);
- if (!bs->file) {
- ret = -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "image", bs, errp);
+ if (ret < 0) {
goto fail;
}
diff --git a/block/blkverify.c b/block/blkverify.c
index d1facf5ba9..920e891684 100644
--- a/block/blkverify.c
+++ b/block/blkverify.c
@@ -121,12 +121,9 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
}
/* Open the raw file */
- bs->file = bdrv_open_child(qemu_opt_get(opts, "x-raw"), options, "raw",
- bs, &child_of_bds,
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
- false, errp);
- if (!bs->file) {
- ret = -EINVAL;
+ ret = bdrv_open_file_child(qemu_opt_get(opts, "x-raw"), options, "raw",
+ bs, errp);
+ if (ret < 0) {
goto fail;
}
diff --git a/block/bochs.c b/block/bochs.c
index 4d68658087..b2dc06bbfd 100644
--- a/block/bochs.c
+++ b/block/bochs.c
@@ -110,10 +110,9 @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
return ret;
}
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_IMAGE, false, errp);
- if (!bs->file) {
- return -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
diff --git a/block/cloop.c b/block/cloop.c
index b8c6d0eccd..bee87da173 100644
--- a/block/cloop.c
+++ b/block/cloop.c
@@ -71,10 +71,9 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
return ret;
}
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_IMAGE, false, errp);
- if (!bs->file) {
- return -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
/* read header */
diff --git a/block/copy-before-write.c b/block/copy-before-write.c
index c30a5ff8de..8aa2cb6a85 100644
--- a/block/copy-before-write.c
+++ b/block/copy-before-write.c
@@ -150,12 +150,11 @@ static int cbw_open(BlockDriverState *bs, QDict *options, int flags,
{
BDRVCopyBeforeWriteState *s = bs->opaque;
BdrvDirtyBitmap *copy_bitmap;
+ int ret;
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
- false, errp);
- if (!bs->file) {
- return -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
s->target = bdrv_open_child(NULL, options, "target", bs, &child_of_bds,
diff --git a/block/copy-on-read.c b/block/copy-on-read.c
index 1fc7fb3333..815ac1d835 100644
--- a/block/copy-on-read.c
+++ b/block/copy-on-read.c
@@ -41,12 +41,11 @@ static int cor_open(BlockDriverState *bs, QDict *options, int flags,
BDRVStateCOR *state = bs->opaque;
/* Find a bottom node name, if any */
const char *bottom_node = qdict_get_try_str(options, "bottom");
+ int ret;
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
- false, errp);
- if (!bs->file) {
- return -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
bs->supported_read_flags = BDRV_REQ_PREFETCH;
diff --git a/block/crypto.c b/block/crypto.c
index c8ba4681e2..abfce39230 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -260,15 +260,14 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
{
BlockCrypto *crypto = bs->opaque;
QemuOpts *opts = NULL;
- int ret = -EINVAL;
+ int ret;
QCryptoBlockOpenOptions *open_opts = NULL;
unsigned int cflags = 0;
QDict *cryptoopts = NULL;
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_IMAGE, false, errp);
- if (!bs->file) {
- return -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
bs->supported_write_flags = BDRV_REQ_FUA &
@@ -276,6 +275,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort);
if (!qemu_opts_absorb_qdict(opts, options, errp)) {
+ ret = -EINVAL;
goto cleanup;
}
@@ -284,6 +284,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
open_opts = block_crypto_open_opts_init(cryptoopts, errp);
if (!open_opts) {
+ ret = -EINVAL;
goto cleanup;
}
diff --git a/block/dmg.c b/block/dmg.c
index 447901fbb8..38c363dd39 100644
--- a/block/dmg.c
+++ b/block/dmg.c
@@ -439,10 +439,9 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
return ret;
}
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_IMAGE, false, errp);
- if (!bs->file) {
- return -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
block_module_load_one("dmg-bz2");
diff --git a/block/filter-compress.c b/block/filter-compress.c
index d5be538619..305716c86c 100644
--- a/block/filter-compress.c
+++ b/block/filter-compress.c
@@ -30,11 +30,9 @@
static int compress_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
- false, errp);
- if (!bs->file) {
- return -EINVAL;
+ int ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
if (!bs->file->bs->drv || !block_driver_can_compress(bs->file->bs->drv)) {
diff --git a/block/parallels.c b/block/parallels.c
index f3352b6aa7..ae3f324bb5 100644
--- a/block/parallels.c
+++ b/block/parallels.c
@@ -735,10 +735,9 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
Error *local_err = NULL;
char *buf;
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_IMAGE, false, errp);
- if (!bs->file) {
- return -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
ret = bdrv_pread(bs->file, 0, &ph, sizeof(ph));
diff --git a/block/preallocate.c b/block/preallocate.c
index 1d4233f730..332408bdc9 100644
--- a/block/preallocate.c
+++ b/block/preallocate.c
@@ -134,6 +134,7 @@ static int preallocate_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp)
{
BDRVPreallocateState *s = bs->opaque;
+ int ret;
/*
* s->data_end and friends should be initialized on permission update.
@@ -141,11 +142,9 @@ static int preallocate_open(BlockDriverState *bs, QDict *options, int flags,
*/
s->file_end = s->zero_start = s->data_end = -EINVAL;
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
- false, errp);
- if (!bs->file) {
- return -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
if (!preallocate_absorb_opts(&s->opts, options, bs->file->bs, errp)) {
diff --git a/block/qcow.c b/block/qcow.c
index c39940f33e..544a17261f 100644
--- a/block/qcow.c
+++ b/block/qcow.c
@@ -120,10 +120,8 @@ static int qcow_open(BlockDriverState *bs, QDict *options, int flags,
qdict_extract_subqdict(options, &encryptopts, "encrypt.");
encryptfmt = qdict_get_try_str(encryptopts, "format");
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_IMAGE, false, errp);
- if (!bs->file) {
- ret = -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
goto fail;
}
diff --git a/block/qcow2.c b/block/qcow2.c
index af1e94f2e2..7b1e870919 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1910,11 +1910,11 @@ static int qcow2_open(BlockDriverState *bs, QDict *options, int flags,
.errp = errp,
.ret = -EINPROGRESS
};
+ int ret;
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_IMAGE, false, errp);
- if (!bs->file) {
- return -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
/* Initialise locks */
diff --git a/block/qed.c b/block/qed.c
index 558d3646c4..e3b06a3d00 100644
--- a/block/qed.c
+++ b/block/qed.c
@@ -558,11 +558,11 @@ static int bdrv_qed_open(BlockDriverState *bs, QDict *options, int flags,
.errp = errp,
.ret = -EINPROGRESS
};
+ int ret;
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_IMAGE, false, errp);
- if (!bs->file) {
- return -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
bdrv_qed_init_state(bs);
diff --git a/block/replication.c b/block/replication.c
index 55c8f894aa..2f17397764 100644
--- a/block/replication.c
+++ b/block/replication.c
@@ -88,11 +88,9 @@ static int replication_open(BlockDriverState *bs, QDict *options,
const char *mode;
const char *top_id;
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
- false, errp);
- if (!bs->file) {
- return -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
ret = -EINVAL;
diff --git a/block/throttle.c b/block/throttle.c
index 6e8d52fa24..4fb5798c27 100644
--- a/block/throttle.c
+++ b/block/throttle.c
@@ -78,11 +78,9 @@ static int throttle_open(BlockDriverState *bs, QDict *options,
char *group;
int ret;
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_FILTERED | BDRV_CHILD_PRIMARY,
- false, errp);
- if (!bs->file) {
- return -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
bs->supported_write_flags = bs->file->bs->supported_write_flags |
BDRV_REQ_WRITE_UNCHANGED;
diff --git a/block/vdi.c b/block/vdi.c
index bdc58d726e..c50c0ed61f 100644
--- a/block/vdi.c
+++ b/block/vdi.c
@@ -376,10 +376,9 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
int ret;
QemuUUID uuid_link, uuid_parent;
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_IMAGE, false, errp);
- if (!bs->file) {
- return -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
logout("\n");
diff --git a/block/vhdx.c b/block/vhdx.c
index 356ec4c455..e7d6d7509a 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -996,10 +996,9 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
uint64_t signature;
Error *local_err = NULL;
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_IMAGE, false, errp);
- if (!bs->file) {
- return -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
s->bat = NULL;
diff --git a/block/vmdk.c b/block/vmdk.c
index 0dfab6e941..7d7e56b36c 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1262,10 +1262,9 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
BDRVVmdkState *s = bs->opaque;
uint32_t magic;
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_IMAGE, false, errp);
- if (!bs->file) {
- return -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
buf = vmdk_read_desc(bs->file, 0, errp);
diff --git a/block/vpc.c b/block/vpc.c
index 297a26262a..430cab1cbb 100644
--- a/block/vpc.c
+++ b/block/vpc.c
@@ -232,10 +232,9 @@ static int vpc_open(BlockDriverState *bs, QDict *options, int flags,
int ret;
int64_t bs_size;
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_of_bds,
- BDRV_CHILD_IMAGE, false, errp);
- if (!bs->file) {
- return -EINVAL;
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
+ if (ret < 0) {
+ return ret;
}
opts = qemu_opts_create(&vpc_runtime_opts, NULL, 0, &error_abort);
diff --git a/include/block/block.h b/include/block/block.h
index e5dd22b034..f885f113ef 100644
--- a/include/block/block.h
+++ b/include/block/block.h
@@ -376,6 +376,9 @@ BdrvChild *bdrv_open_child(const char *filename,
const BdrvChildClass *child_class,
BdrvChildRole child_role,
bool allow_none, Error **errp);
+int bdrv_open_file_child(const char *filename,
+ QDict *options, const char *bdref_key,
+ BlockDriverState *parent, Error **errp);
BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp);
int bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
Error **errp);
--
2.41.0.windows.1

View File

@ -0,0 +1,62 @@
From 1a52d742851a68772aeb1d6d18bb57e58d78b2d2 Mon Sep 17 00:00:00 2001
From: guping <guping_yewu@cmss.chinamobile.com>
Date: Tue, 25 Jun 2024 11:33:54 +0000
Subject: [PATCH] hw/intc/arm_gic: Fix deactivation of SPI lines chery-pick
from 7175a562f157d39725ab396e39c1e8e410d206b3
Julien reported that he has seen strange behaviour when running
Xen on QEMU using GICv2. When Xen migrates a guest's vCPU from
one pCPU to another while the vCPU is handling an interrupt, the
guest is unable to properly deactivate interrupts.
Looking at it a little closer, our GICv2 model treats
deactivation of SPI lines as if they were PPI's, i.e banked per
CPU core. The state for active interrupts should only be banked
for PPI lines, not for SPI lines.
Make deactivation of SPI lines unbanked, similar to how we
handle writes to GICD_ICACTIVER.
Reported-by: default avatarJulien Grall <julien@xen.org>
Signed-off-by: default avatarEdgar E. Iglesias <edgar.iglesias@amd.com>
Message-id: 20240605143044.2029444-2-edgar.iglesias@gmail.com
Reviewed-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: default avatarPeter Maydell <peter.maydell@linaro.org>
Signed-off-by: guping <guping_yewu@cmss.chinamobile.com>
---
hw/intc/gic_internal.h | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/hw/intc/gic_internal.h b/hw/intc/gic_internal.h
index 8d29b40ca1..8ddbf554c6 100644
--- a/hw/intc/gic_internal.h
+++ b/hw/intc/gic_internal.h
@@ -280,6 +280,8 @@ static inline void gic_set_active(GICState *s, int irq, int cpu)
static inline void gic_clear_active(GICState *s, int irq, int cpu)
{
+ unsigned int cm;
+
if (gic_is_vcpu(cpu)) {
uint32_t *entry = gic_get_lr_entry(s, irq, cpu);
GICH_LR_CLEAR_ACTIVE(*entry);
@@ -301,11 +303,13 @@ static inline void gic_clear_active(GICState *s, int irq, int cpu)
* the GIC is secure.
*/
if (!s->security_extn || GIC_DIST_TEST_GROUP(phys_irq, 1 << rcpu)) {
- GIC_DIST_CLEAR_ACTIVE(phys_irq, 1 << rcpu);
+ cm = phys_irq < GIC_INTERNAL ? 1 << rcpu : ALL_CPU_MASK;
+ GIC_DIST_CLEAR_ACTIVE(phys_irq, cm);
}
}
} else {
- GIC_DIST_CLEAR_ACTIVE(irq, 1 << cpu);
+ cm = irq < GIC_INTERNAL ? 1 << cpu : ALL_CPU_MASK;
+ GIC_DIST_CLEAR_ACTIVE(irq, cm);
}
}
--
2.41.0.windows.1

View File

@ -0,0 +1,64 @@
From 38c0538c8d847a2e39a9bae19f5b204abcf46b3b Mon Sep 17 00:00:00 2001
From: Yanan Wang <wangyanan55@huawei.com>
Date: Mon, 17 Jun 2024 20:42:22 +0800
Subject: [PATCH] hw/virtio/virtio-pci:Support shadow device for
virtio-net/blk/scsi devices
Currently we only support shadow device for "virtio-net", now let's
extend this feature to support "virtio-blk" and "virtio-scsi" devices.
Signed-off-by: Yanan Wang <wangyanan55@huawei.com>
---
hw/virtio/virtio-pci.c | 15 ++++++++++++---
1 file changed, 12 insertions(+), 3 deletions(-)
diff --git a/hw/virtio/virtio-pci.c b/hw/virtio/virtio-pci.c
index 389a8db0ec..d675526016 100644
--- a/hw/virtio/virtio-pci.c
+++ b/hw/virtio/virtio-pci.c
@@ -886,6 +886,15 @@ int __attribute__((weak)) kvm_delete_shadow_device(PCIDevice *dev)
}
#endif
+#ifdef __aarch64__
+static bool shadow_device_supported(VirtIODevice *vdev)
+{
+ return !strcmp(vdev->name, "virtio-net") ||
+ !strcmp(vdev->name, "virtio-blk") ||
+ !strcmp(vdev->name, "virtio-scsi");
+}
+#endif
+
static int kvm_virtio_pci_vector_vq_use(VirtIOPCIProxy *proxy, int nvqs)
{
int queue_no;
@@ -893,7 +902,7 @@ static int kvm_virtio_pci_vector_vq_use(VirtIOPCIProxy *proxy, int nvqs)
VirtIODevice *vdev = virtio_bus_get_device(&proxy->bus);
#ifdef __aarch64__
- if (!strcmp(vdev->name, "virtio-net")) {
+ if (shadow_device_supported(vdev)) {
kvm_create_shadow_device(&proxy->pci_dev);
}
#endif
@@ -906,7 +915,7 @@ static int kvm_virtio_pci_vector_vq_use(VirtIOPCIProxy *proxy, int nvqs)
}
#ifdef __aarch64__
- if (!strcmp(vdev->name, "virtio-net") && ret != 0) {
+ if (shadow_device_supported(vdev) && ret != 0) {
kvm_delete_shadow_device(&proxy->pci_dev);
}
#endif
@@ -955,7 +964,7 @@ static void kvm_virtio_pci_vector_vq_release(VirtIOPCIProxy *proxy, int nvqs)
}
#ifdef __aarch64__
- if (!strcmp(vdev->name, "virtio-net")) {
+ if (shadow_device_supported(vdev)) {
kvm_delete_shadow_device(&proxy->pci_dev);
}
#endif
--
2.41.0.windows.1

View File

@ -0,0 +1,52 @@
From e3feddf508a6c118e321b3a1c761068772487225 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Thu, 25 Apr 2024 14:49:40 +0200
Subject: [PATCH] iotests/244: Don't store data-file with protocol in image
(CVE-2024-4467)
We want to disable filename parsing for data files because it's too easy
to abuse in malicious image files. Make the test ready for the change by
passing the data file explicitly in command line options.
Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
---
tests/qemu-iotests/244 | 19 ++++++++++++++++---
1 file changed, 16 insertions(+), 3 deletions(-)
diff --git a/tests/qemu-iotests/244 b/tests/qemu-iotests/244
index 3e61fa25bb..bb9cc6512f 100755
--- a/tests/qemu-iotests/244
+++ b/tests/qemu-iotests/244
@@ -215,9 +215,22 @@ $QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG"
$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG"
# blkdebug doesn't support copy offloading, so this tests the error path
-$QEMU_IMG amend -f $IMGFMT -o "data_file=blkdebug::$TEST_IMG.data" "$TEST_IMG"
-$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$TEST_IMG"
-$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$TEST_IMG"
+test_img_with_blkdebug="json:{
+ 'driver': 'qcow2',
+ 'file': {
+ 'driver': 'file',
+ 'filename': '$TEST_IMG'
+ },
+ 'data-file': {
+ 'driver': 'blkdebug',
+ 'image': {
+ 'driver': 'file',
+ 'filename': '$TEST_IMG.data'
+ }
+ }
+}"
+$QEMU_IMG convert -f $IMGFMT -O $IMGFMT -n -C "$TEST_IMG.src" "$test_img_with_blkdebug"
+$QEMU_IMG compare -f $IMGFMT -F $IMGFMT "$TEST_IMG.src" "$test_img_with_blkdebug"
echo
echo "=== Flushing should flush the data file ==="
--
2.41.0.windows.1

View File

@ -0,0 +1,54 @@
From 7ee281f59878c1f7a95e0a2a3f674c252d0c9f92 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Thu, 25 Apr 2024 14:49:40 +0200
Subject: [PATCH] iotests/270: Don't store data-file with json: prefix in image
(CVE-2024-4467)
We want to disable filename parsing for data files because it's too easy
to abuse in malicious image files. Make the test ready for the change by
passing the data file explicitly in command line options.
Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
---
tests/qemu-iotests/270 | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/tests/qemu-iotests/270 b/tests/qemu-iotests/270
index 74352342db..c37b674aa2 100755
--- a/tests/qemu-iotests/270
+++ b/tests/qemu-iotests/270
@@ -60,8 +60,16 @@ _make_test_img -o cluster_size=2M,data_file="$TEST_IMG.orig" \
# "write" 2G of data without using any space.
# (qemu-img create does not like it, though, because null-co does not
# support image creation.)
-$QEMU_IMG amend -o data_file="json:{'driver':'null-co',,'size':'4294967296'}" \
- "$TEST_IMG"
+test_img_with_null_data="json:{
+ 'driver': '$IMGFMT',
+ 'file': {
+ 'filename': '$TEST_IMG'
+ },
+ 'data-file': {
+ 'driver': 'null-co',
+ 'size':'4294967296'
+ }
+}"
# This gives us a range of:
# 2^31 - 512 + 768 - 1 = 2^31 + 255 > 2^31
@@ -74,7 +82,7 @@ $QEMU_IMG amend -o data_file="json:{'driver':'null-co',,'size':'4294967296'}" \
# on L2 boundaries, we need large L2 tables; hence the cluster size of
# 2 MB. (Anything from 256 kB should work, though, because then one L2
# table covers 8 GB.)
-$QEMU_IO -c "write 768 $((2 ** 31 - 512))" "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c "write 768 $((2 ** 31 - 512))" "$test_img_with_null_data" | _filter_qemu_io
_check_test_img
--
2.41.0.windows.1

View File

@ -0,0 +1,221 @@
From d21b395997737618116926cb2680e85d79e14d19 Mon Sep 17 00:00:00 2001
From: Hanna Reitz <hreitz@redhat.com>
Date: Wed, 27 Apr 2022 13:40:55 +0200
Subject: [PATCH] qcow2: Do not reopen data_file in invalidate_cache
qcow2_co_invalidate_cache() closes and opens the qcow2 file, by calling
qcow2_close() and qcow2_do_open(). These two functions must thus be
usable from both a global-state and an I/O context.
As they are, they are not safe to call in an I/O context, because they
use bdrv_unref_child() and bdrv_open_child() to close/open the data_file
child, respectively, both of which are global-state functions. When
used from qcow2_co_invalidate_cache(), we do not need to close/open the
data_file child, though (we do not do this for bs->file or bs->backing
either), and so we should skip it in the qcow2_co_invalidate_cache()
path.
To do so, add a parameter to qcow2_do_open() and qcow2_close() to make
them skip handling s->data_file, and have qcow2_co_invalidate_cache()
exempt it from the memset() on the BDRVQcow2State.
(Note that the QED driver similarly closes/opens the QED image by
invoking bdrv_qed_close()+bdrv_qed_do_open(), but both functions seem
safe to use in an I/O context.)
Fixes: https://gitlab.com/qemu-project/qemu/-/issues/945
Signed-off-by: Hanna Reitz <hreitz@redhat.com>
Message-Id: <20220427114057.36651-3-hreitz@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/qcow2.c | 104 ++++++++++++++++++++++++++++++--------------------
1 file changed, 62 insertions(+), 42 deletions(-)
diff --git a/block/qcow2.c b/block/qcow2.c
index be90a898e3..4a6b0a3ea9 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1296,7 +1296,8 @@ static int validate_compression_type(BDRVQcow2State *s, Error **errp)
/* Called with s->lock held. */
static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
- int flags, Error **errp)
+ int flags, bool open_data_file,
+ Error **errp)
{
ERRP_GUARD();
BDRVQcow2State *s = bs->opaque;
@@ -1614,50 +1615,52 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
goto fail;
}
- /* Open external data file */
- s->data_file = bdrv_open_child(NULL, options, "data-file", bs,
- &child_of_bds, BDRV_CHILD_DATA,
- true, errp);
- if (*errp) {
- ret = -EINVAL;
- goto fail;
- }
+ if (open_data_file) {
+ /* Open external data file */
+ s->data_file = bdrv_open_child(NULL, options, "data-file", bs,
+ &child_of_bds, BDRV_CHILD_DATA,
+ true, errp);
+ if (*errp) {
+ ret = -EINVAL;
+ goto fail;
+ }
- if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) {
- if (!s->data_file && s->image_data_file) {
- s->data_file = bdrv_open_child(s->image_data_file, options,
- "data-file", bs, &child_of_bds,
- BDRV_CHILD_DATA, false, errp);
+ if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) {
+ if (!s->data_file && s->image_data_file) {
+ s->data_file = bdrv_open_child(s->image_data_file, options,
+ "data-file", bs, &child_of_bds,
+ BDRV_CHILD_DATA, false, errp);
+ if (!s->data_file) {
+ ret = -EINVAL;
+ goto fail;
+ }
+ }
if (!s->data_file) {
+ error_setg(errp, "'data-file' is required for this image");
ret = -EINVAL;
goto fail;
}
- }
- if (!s->data_file) {
- error_setg(errp, "'data-file' is required for this image");
- ret = -EINVAL;
- goto fail;
- }
- /* No data here */
- bs->file->role &= ~BDRV_CHILD_DATA;
+ /* No data here */
+ bs->file->role &= ~BDRV_CHILD_DATA;
- /* Must succeed because we have given up permissions if anything */
- bdrv_child_refresh_perms(bs, bs->file, &error_abort);
- } else {
- if (s->data_file) {
- error_setg(errp, "'data-file' can only be set for images with an "
- "external data file");
- ret = -EINVAL;
- goto fail;
- }
+ /* Must succeed because we have given up permissions if anything */
+ bdrv_child_refresh_perms(bs, bs->file, &error_abort);
+ } else {
+ if (s->data_file) {
+ error_setg(errp, "'data-file' can only be set for images with "
+ "an external data file");
+ ret = -EINVAL;
+ goto fail;
+ }
- s->data_file = bs->file;
+ s->data_file = bs->file;
- if (data_file_is_raw(bs)) {
- error_setg(errp, "data-file-raw requires a data file");
- ret = -EINVAL;
- goto fail;
+ if (data_file_is_raw(bs)) {
+ error_setg(errp, "data-file-raw requires a data file");
+ ret = -EINVAL;
+ goto fail;
+ }
}
}
@@ -1839,7 +1842,7 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
fail:
g_free(s->image_data_file);
- if (has_data_file(bs)) {
+ if (open_data_file && has_data_file(bs)) {
bdrv_unref_child(bs, s->data_file);
s->data_file = NULL;
}
@@ -1876,7 +1879,8 @@ static void coroutine_fn qcow2_open_entry(void *opaque)
BDRVQcow2State *s = qoc->bs->opaque;
qemu_co_mutex_lock(&s->lock);
- qoc->ret = qcow2_do_open(qoc->bs, qoc->options, qoc->flags, qoc->errp);
+ qoc->ret = qcow2_do_open(qoc->bs, qoc->options, qoc->flags, true,
+ qoc->errp);
qemu_co_mutex_unlock(&s->lock);
}
@@ -2714,7 +2718,7 @@ static int qcow2_inactivate(BlockDriverState *bs)
return result;
}
-static void qcow2_close(BlockDriverState *bs)
+static void qcow2_do_close(BlockDriverState *bs, bool close_data_file)
{
BDRVQcow2State *s = bs->opaque;
qemu_vfree(s->l1_table);
@@ -2740,7 +2744,7 @@ static void qcow2_close(BlockDriverState *bs)
g_free(s->image_backing_file);
g_free(s->image_backing_format);
- if (has_data_file(bs)) {
+ if (close_data_file && has_data_file(bs)) {
bdrv_unref_child(bs, s->data_file);
s->data_file = NULL;
}
@@ -2749,11 +2753,17 @@ static void qcow2_close(BlockDriverState *bs)
qcow2_free_snapshots(bs);
}
+static void qcow2_close(BlockDriverState *bs)
+{
+ qcow2_do_close(bs, true);
+}
+
static void coroutine_fn qcow2_co_invalidate_cache(BlockDriverState *bs,
Error **errp)
{
ERRP_GUARD();
BDRVQcow2State *s = bs->opaque;
+ BdrvChild *data_file;
int flags = s->flags;
QCryptoBlock *crypto = NULL;
QDict *options;
@@ -2767,14 +2777,24 @@ static void coroutine_fn qcow2_co_invalidate_cache(BlockDriverState *bs,
crypto = s->crypto;
s->crypto = NULL;
- qcow2_close(bs);
+ /*
+ * Do not reopen s->data_file (i.e., have qcow2_do_close() not close it,
+ * and then prevent qcow2_do_open() from opening it), because this function
+ * runs in the I/O path and as such we must not invoke global-state
+ * functions like bdrv_unref_child() and bdrv_open_child().
+ */
+ qcow2_do_close(bs, false);
+
+ data_file = s->data_file;
memset(s, 0, sizeof(BDRVQcow2State));
+ s->data_file = data_file;
+
options = qdict_clone_shallow(bs->options);
flags &= ~BDRV_O_INACTIVE;
qemu_co_mutex_lock(&s->lock);
- ret = qcow2_do_open(bs, options, flags, errp);
+ ret = qcow2_do_open(bs, options, flags, false, errp);
qemu_co_mutex_unlock(&s->lock);
qobject_unref(options);
if (ret < 0) {
--
2.41.0.windows.1

View File

@ -0,0 +1,108 @@
From 6dc46edd6ebe051b181e04aa6929d46b8cbc70ba Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Thu, 11 Apr 2024 15:06:01 +0200
Subject: [PATCH] qcow2: Don't open data_file with BDRV_O_NO_IO (CVE-2024-4467)
One use case for 'qemu-img info' is verifying that untrusted images
don't reference an unwanted external file, be it as a backing file or an
external data file. To make sure that calling 'qemu-img info' can't
already have undesired side effects with a malicious image, just don't
open the data file at all with BDRV_O_NO_IO. If nothing ever tries to do
I/O, we don't need to have it open.
This changes the output of iotests case 061, which used 'qemu-img info'
to show that opening an image with an invalid data file fails. After
this patch, it succeeds. Replace this part of the test with a qemu-io
call, but keep the final 'qemu-img info' to show that the invalid data
file is correctly displayed in the output.
Fixes: CVE-2024-4467
Cc: qemu-stable@nongnu.org
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
---
block/qcow2.c | 17 ++++++++++++++++-
tests/qemu-iotests/061 | 6 ++++--
tests/qemu-iotests/061.out | 8 ++++++--
3 files changed, 26 insertions(+), 5 deletions(-)
diff --git a/block/qcow2.c b/block/qcow2.c
index 4a6b0a3ea9..af1e94f2e2 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1615,7 +1615,22 @@ static int coroutine_fn qcow2_do_open(BlockDriverState *bs, QDict *options,
goto fail;
}
- if (open_data_file) {
+ if (open_data_file && (flags & BDRV_O_NO_IO)) {
+ /*
+ * Don't open the data file for 'qemu-img info' so that it can be used
+ * to verify that an untrusted qcow2 image doesn't refer to external
+ * files.
+ *
+ * Note: This still makes has_data_file() return true.
+ */
+ if (s->incompatible_features & QCOW2_INCOMPAT_DATA_FILE) {
+ s->data_file = NULL;
+ } else {
+ s->data_file = bs->file;
+ }
+ qdict_extract_subqdict(options, NULL, "data-file.");
+ qdict_del(options, "data-file");
+ } else if (open_data_file) {
/* Open external data file */
s->data_file = bdrv_open_child(NULL, options, "data-file", bs,
&child_of_bds, BDRV_CHILD_DATA,
diff --git a/tests/qemu-iotests/061 b/tests/qemu-iotests/061
index 9507c223bd..6a5bd47efc 100755
--- a/tests/qemu-iotests/061
+++ b/tests/qemu-iotests/061
@@ -322,12 +322,14 @@ $QEMU_IMG amend -o "data_file=foo" "$TEST_IMG"
echo
_make_test_img -o "compat=1.1,data_file=$TEST_IMG.data" 64M
$QEMU_IMG amend -o "data_file=foo" "$TEST_IMG"
-_img_info --format-specific
+$QEMU_IO -c "read 0 4k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt
+$QEMU_IO -c "open -o data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" -c "read 0 4k" | _filter_qemu_io
TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts
echo
$QEMU_IMG amend -o "data_file=" --image-opts "data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG"
-_img_info --format-specific
+$QEMU_IO -c "read 0 4k" "$TEST_IMG" 2>&1 | _filter_testdir | _filter_imgfmt
+$QEMU_IO -c "open -o data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" -c "read 0 4k" | _filter_qemu_io
TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts
echo
diff --git a/tests/qemu-iotests/061.out b/tests/qemu-iotests/061.out
index 7ecbd4dea8..99b2307a23 100644
--- a/tests/qemu-iotests/061.out
+++ b/tests/qemu-iotests/061.out
@@ -545,7 +545,9 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-img: data-file can only be set for images that use an external data file
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data
-qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Could not open 'foo': No such file or directory
+qemu-io: can't open device TEST_DIR/t.IMGFMT: Could not open 'foo': No such file or directory
+read 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 64 MiB (67108864 bytes)
@@ -560,7 +562,9 @@ Format specific information:
corrupt: false
extended l2: false
-qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image
+qemu-io: can't open device TEST_DIR/t.IMGFMT: 'data-file' is required for this image
+read 4096/4096 bytes at offset 0
+4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 64 MiB (67108864 bytes)
--
2.41.0.windows.1

View File

@ -3,7 +3,7 @@
Name: qemu
Version: 6.2.0
Release: 95
Release: 96
Epoch: 10
Summary: QEMU is a generic and open source machine emulator and virtualizer
License: GPLv2 and BSD and MIT and CC-BY-SA-4.0
@ -970,6 +970,18 @@ Patch0955: tests-qtest-ahci-test-add-test-exposing-reset-issue-.patch
Patch0956: cvm-bug-fix-for-macro-isolation.patch
Patch0957: hw-arm-virt-Disable-DTB-randomness-for-confidential-.patch
Patch0958: cvm-bug-fix-for-disable-DTB-randomness-for-confident.patch
Patch0959: hw-virtio-virtio-pci-Support-shadow-device-for-virti.patch
Patch0960: vdpa-fix-vdpa-device-migrate-rollback-wrong-when-sus.patch
Patch0961: target-ppc-Split-off-common-embedded-TLB-init.patch
Patch0962: vhost-user-Skip-unnecessary-duplicated-VHOST_USER_SE.patch
Patch0963: hw-intc-arm_gic-Fix-deactivation-of-SPI-lines.patch
Patch0964: qcow2-Do-not-reopen-data_file-in-invalidate_cache.patch
Patch0965: qcow2-Don-t-open-data_file-with-BDRV_O_NO_IO-CVE-202.patch
Patch0966: iotests-244-Don-t-store-data-file-with-protocol-in-i.patch
Patch0967: iotests-270-Don-t-store-data-file-with-json-prefix-i.patch
Patch0968: block-introduce-bdrv_open_file_child-helper.patch
Patch0969: block-Parse-filenames-only-when-explicitly-requested.patch
Patch0970: vdpa-Fix-bug-where-vdpa-appliance-migration-does-not.patch
BuildRequires: flex
BuildRequires: gcc
@ -1568,6 +1580,20 @@ getent passwd qemu >/dev/null || \
%endif
%changelog
* Thu Jul 11 2024 <fengjiabo1@huawei.com> - 10:6.2.0-96
- vdpa: Fix bug where vdpa appliance migration does not resume after rollback
- block: Parse filenames only when explicitly requested (CVE-2024-4467)
- block: introduce bdrv_open_file_child() helper
- iotests/270: Don't store data-file with json: prefix in image (CVE-2024-4467)
- iotests/244: Don't store data-file with protocol in image (CVE-2024-4467)
- qcow2: Don't open data_file with BDRV_O_NO_IO (CVE-2024-4467)
- qcow2: Do not reopen data_file in invalidate_cache
- hw/intc/arm_gic: Fix deactivation of SPI lines chery-pick from 7175a562f157d39725ab396e39c1e8e410d206b3
- vhost-user: Skip unnecessary duplicated VHOST_USER_SET_LOG_BASE requests
- target/ppc: Split off common embedded TLB init cheery-pick from 581eea5d656b73c6532109f4ced4c73fd4e5fd47`
- vdpa: fix vdpa device migrate rollback wrong when suspend device failed 1.
- hw/virtio/virtio-pci:Support shadow device for virtio-net/blk/scsi devices
* Fri Jun 21 2024 <liupingwei@huawei.com> - 10:6.2.0-95
- cvm: bug-fix for disable DTB randomness for confidential VMs

View File

@ -0,0 +1,118 @@
From 9f45d0ded0694739898e2fbbb6fa08891a7de280 Mon Sep 17 00:00:00 2001
From: dinglimin <dinglimin@cmss.chinamobile.com>
Date: Mon, 10 Jun 2024 15:52:59 +0800
Subject: [PATCH] target/ppc: Split off common embedded TLB init cheery-pick
from 581eea5d656b73c6532109f4ced4c73fd4e5fd47`
Several 4xx CPUs and e200 share the same TLB settings enclosed in an
ifdef. Split it off in a common function to reduce code duplication
and the number of ifdefs.
Reviewed-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: BALATON Zoltan <balaton@eik.bme.hu>
Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Signed-off-by: dinglimin <dinglimin@cmss.chinamobile.com>
---
target/ppc/cpu_init.c | 50 +++++++++++++------------------------------
1 file changed, 15 insertions(+), 35 deletions(-)
diff --git a/target/ppc/cpu_init.c b/target/ppc/cpu_init.c
index 986d16a24d..d0dfa1aeaf 100644
--- a/target/ppc/cpu_init.c
+++ b/target/ppc/cpu_init.c
@@ -3018,7 +3018,15 @@ POWERPC_FAMILY(403GCX)(ObjectClass *oc, void *data)
pcc->flags = POWERPC_FLAG_CE | POWERPC_FLAG_PX |
POWERPC_FLAG_BUS_CLK;
}
-
+static void init_tlbs_emb(CPUPPCState *env)
+{
+#if !defined(CONFIG_USER_ONLY)
+ env->nb_tlb = 64;
+ env->nb_ways = 1;
+ env->id_tlbs = 0;
+ env->tlb_type = TLB_EMB;
+#endif
+}
static void init_proc_405(CPUPPCState *env)
{
/* Time base */
@@ -3036,13 +3044,7 @@ static void init_proc_405(CPUPPCState *env)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->id_tlbs = 0;
- env->tlb_type = TLB_EMB;
-#endif
+ init_tlbs_emb(env);
init_excp_4xx_softmmu(env);
env->dcache_line_size = 32;
env->icache_line_size = 32;
@@ -3135,13 +3137,7 @@ static void init_proc_440EP(CPUPPCState *env)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->id_tlbs = 0;
- env->tlb_type = TLB_EMB;
-#endif
+ init_tlbs_emb(env);
init_excp_BookE(env);
env->dcache_line_size = 32;
env->icache_line_size = 32;
@@ -3259,13 +3255,7 @@ static void init_proc_440GP(CPUPPCState *env)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->id_tlbs = 0;
- env->tlb_type = TLB_EMB;
-#endif
+ init_tlbs_emb(env);
init_excp_BookE(env);
env->dcache_line_size = 32;
env->icache_line_size = 32;
@@ -3443,13 +3433,7 @@ static void init_proc_440x5(CPUPPCState *env)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
- /* Memory management */
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->id_tlbs = 0;
- env->tlb_type = TLB_EMB;
-#endif
+ init_tlbs_emb(env);
init_excp_BookE(env);
env->dcache_line_size = 32;
env->icache_line_size = 32;
@@ -3877,12 +3861,8 @@ static void init_proc_e200(CPUPPCState *env)
SPR_NOACCESS, SPR_NOACCESS,
&spr_read_generic, &spr_write_generic,
0x00000000);
-#if !defined(CONFIG_USER_ONLY)
- env->nb_tlb = 64;
- env->nb_ways = 1;
- env->id_tlbs = 0;
- env->tlb_type = TLB_EMB;
-#endif
+
+ init_tlbs_emb(env);
init_excp_e200(env, 0xFFFF0000UL);
env->dcache_line_size = 32;
env->icache_line_size = 32;
--
2.41.0.windows.1

View File

@ -0,0 +1,38 @@
From 2713ad857506ce338472e19706fbbab4ee4ba662 Mon Sep 17 00:00:00 2001
From: Adttil <2429917001@qq.com>
Date: Mon, 8 Jul 2024 14:45:18 +0800
Subject: [PATCH] vdpa: Fix bug where vdpa appliance migration does not resume
after rollback
using vdpa->started to judge device started instead of vdev->vhost_started
Signed-off-by: Adttil <2429917001@qq.com>
---
hw/virtio/vdpa-dev-mig.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/virtio/vdpa-dev-mig.c b/hw/virtio/vdpa-dev-mig.c
index 23238c9f19..c080f9d89b 100644
--- a/hw/virtio/vdpa-dev-mig.c
+++ b/hw/virtio/vdpa-dev-mig.c
@@ -137,7 +137,7 @@ static int vhost_vdpa_device_suspend(VhostVdpaDevice *vdpa)
{
VirtIODevice *vdev = VIRTIO_DEVICE(vdpa);
- if (!vdev->vhost_started || vdpa->suspended) {
+ if (!vdpa->started || vdpa->suspended) {
return 0;
}
@@ -152,7 +152,7 @@ static int vhost_vdpa_device_resume(VhostVdpaDevice *vdpa)
MigrationIncomingState *mis = migration_incoming_get_current();
int ret;
- if (!vdev->vhost_started ||
+ if (!vdpa->started ||
(!vdpa->suspended && mis->state != RUN_STATE_RESTORE_VM)) {
return 0;
}
--
2.41.0.windows.1

View File

@ -0,0 +1,140 @@
From 493ef78aebf2aac04e9dbf5d1f21eb0c18763917 Mon Sep 17 00:00:00 2001
From: jiangdongxu <jiangdongxu1@huawei.com>
Date: Sat, 22 Jun 2024 07:02:48 +0000
Subject: [PATCH] vdpa: fix vdpa device migrate rollback wrong when suspend
device failed 1. set vdpa->suspended before call vhost_dev_suspend to make
sure vdpa device will resume when suspend failed. 2. using
vdpa->vhost_started to judge device started instead of vdev->started 3. using
state == RUN_STATE_FINISH_MIGRATE instead of ms->state ==
MIGRATION_STATUS_ACTIVE to judge vm in migration. As migrate_fd_cancel will
change ms->state, which will result in some vdpa devices not being suspended.
Signed-off-by: jiangdongxu <jiangdongxu1@huawei.com>
---
hw/virtio/vdpa-dev-mig.c | 83 ++++------------------------------------
1 file changed, 8 insertions(+), 75 deletions(-)
diff --git a/hw/virtio/vdpa-dev-mig.c b/hw/virtio/vdpa-dev-mig.c
index 679d37b182..23238c9f19 100644
--- a/hw/virtio/vdpa-dev-mig.c
+++ b/hw/virtio/vdpa-dev-mig.c
@@ -136,100 +136,33 @@ free:
static int vhost_vdpa_device_suspend(VhostVdpaDevice *vdpa)
{
VirtIODevice *vdev = VIRTIO_DEVICE(vdpa);
- BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
- VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
- int ret;
- if (!vdpa->started || vdpa->suspended) {
+ if (!vdev->vhost_started || vdpa->suspended) {
return 0;
}
- if (!k->set_guest_notifiers) {
- return -EFAULT;
- }
-
- vdpa->started = false;
vdpa->suspended = true;
- ret = vhost_dev_suspend(&vdpa->dev, vdev, false);
- if (ret) {
- goto suspend_fail;
- }
-
- ret = k->set_guest_notifiers(qbus->parent, vdpa->dev.nvqs, false);
- if (ret < 0) {
- error_report("vhost guest notifier cleanup failed: %d\n", ret);
- goto set_guest_notifiers_fail;
- }
-
- vhost_dev_disable_notifiers(&vdpa->dev, vdev);
- return ret;
-
-set_guest_notifiers_fail:
- ret = k->set_guest_notifiers(qbus->parent, vdpa->dev.nvqs, true);
- if (ret) {
- error_report("vhost guest notifier restore failed: %d\n", ret);
- }
-
-suspend_fail:
- vdpa->suspended = false;
- vdpa->started = true;
- return ret;
+ return vhost_dev_suspend(&vdpa->dev, vdev, false);
}
static int vhost_vdpa_device_resume(VhostVdpaDevice *vdpa)
{
VirtIODevice *vdev = VIRTIO_DEVICE(vdpa);
- BusState *qbus = BUS(qdev_get_parent_bus(DEVICE(vdev)));
- VirtioBusClass *k = VIRTIO_BUS_GET_CLASS(qbus);
- int i, ret;
+ MigrationIncomingState *mis = migration_incoming_get_current();
+ int ret;
- if (vdpa->started || !vdpa->suspended) {
+ if (!vdev->vhost_started ||
+ (!vdpa->suspended && mis->state != RUN_STATE_RESTORE_VM)) {
return 0;
}
- if (!k->set_guest_notifiers) {
- error_report("binding does not support guest notifiers\n");
- return -ENOSYS;
- }
-
- ret = vhost_dev_enable_notifiers(&vdpa->dev, vdev);
+ ret = vhost_dev_resume(&vdpa->dev, vdev, false);
if (ret < 0) {
- error_report("Error enabling host notifiers: %d\n", ret);
return ret;
}
- ret = k->set_guest_notifiers(qbus->parent, vdpa->dev.nvqs, true);
- if (ret < 0) {
- error_report("Error binding guest notifier: %d\n", ret);
- goto err_host_notifiers;
- }
-
- vdpa->dev.acked_features = vdev->guest_features;
-
- ret = vhost_dev_resume(&vdpa->dev, vdev, false);
- if (ret < 0) {
- error_report("Error starting vhost: %d\n", ret);
- goto err_guest_notifiers;
- }
- vdpa->started = true;
vdpa->suspended = false;
-
- /*
- * guest_notifier_mask/pending not used yet, so just unmask
- * everything here. virtio-pci will do the right thing by
- * enabling/disabling irqfd.
- */
- for (i = 0; i < vdpa->dev.nvqs; i++) {
- vhost_virtqueue_mask(&vdpa->dev, vdev, i, false);
- }
-
- return ret;
-
-err_guest_notifiers:
- k->set_guest_notifiers(qbus->parent, vdpa->dev.nvqs, false);
-err_host_notifiers:
- vhost_dev_disable_notifiers(&vdpa->dev, vdev);
return ret;
}
@@ -254,7 +187,7 @@ static void vdpa_dev_vmstate_change(void *opaque, bool running, RunState state)
MigrationIncomingState *mis = migration_incoming_get_current();
if (!running) {
- if (ms->state == MIGRATION_STATUS_ACTIVE || state == RUN_STATE_PAUSED) {
+ if (state == RUN_STATE_FINISH_MIGRATE || state == RUN_STATE_PAUSED) {
ret = vhost_vdpa_device_suspend(vdpa);
if (ret) {
error_report("suspend vdpa device failed: %d\n", ret);
--
2.41.0.windows.1

View File

@ -0,0 +1,31 @@
From 24e57d8013b2d039ed917676b7fb34d3736c9d8d Mon Sep 17 00:00:00 2001
From: BillXiang <1373760142@qq.com>
Date: Wed, 19 Jun 2024 09:24:05 +0800
Subject: [PATCH] vhost-user: Skip unnecessary duplicated
VHOST_USER_SET_LOG_BASE requests
The VHOST_USER_SET_LOG_BASE requests should be categorized into
non-vring specific messages, and should be sent only once.
If send more than once, dpdk will munmap old log_addr which may has been used
and cause segmentation fault.
Signed-off-by: BillXiang <1373760142@qq.com>
---
hw/virtio/vhost-user.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/virtio/vhost-user.c b/hw/virtio/vhost-user.c
index 937b3021e9..c97ea2544d 100644
--- a/hw/virtio/vhost-user.c
+++ b/hw/virtio/vhost-user.c
@@ -456,6 +456,7 @@ static bool vhost_user_one_time_request(VhostUserRequest request)
case VHOST_USER_SET_MEM_TABLE:
case VHOST_USER_GET_QUEUE_NUM:
case VHOST_USER_NET_SET_MTU:
+ case VHOST_USER_SET_LOG_BASE:
return true;
default:
return false;
--
2.41.0.windows.1