- block: Parse filenames only when explicitly requested (CVE-2024-4467) - block: introduce bdrv_open_file_child() helper - qcow2: Don't open data_file with BDRV_O_NO_IO (CVE-2024-4467) - qcow2: Do not reopen data_file in invalidate_cache Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com>
460 lines
16 KiB
Diff
460 lines
16 KiB
Diff
From 34058a6ad98adeca582ece7ad75b5705931101c0 Mon Sep 17 00:00:00 2001
|
|
From: liuxiangdong <liuxiangdong5@huawei.com>
|
|
Date: Wed, 19 Jun 2024 19:09:26 +0800
|
|
Subject: [PATCH] block: introduce bdrv_open_file_child() helper
|
|
|
|
cherry-pick from: https://github.com/qemu/qemu/commit/83930780325b144a5908c45b3957b9b6457b3831
|
|
|
|
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 | 13 +++++++++++++
|
|
block/blkdebug.c | 7 +++----
|
|
block/blklogwrites.c | 6 ++----
|
|
block/blkreplay.c | 6 ++----
|
|
block/blkverify.c | 7 +++----
|
|
block/bochs.c | 7 +++----
|
|
block/cloop.c | 7 +++----
|
|
block/copy-on-read.c | 8 ++++----
|
|
block/crypto.c | 11 ++++++-----
|
|
block/dmg.c | 7 +++----
|
|
block/parallels.c | 7 +++----
|
|
block/qcow.c | 6 ++----
|
|
block/qcow2.c | 8 ++++----
|
|
block/qed.c | 8 ++++----
|
|
block/replication.c | 7 +++----
|
|
block/throttle.c | 7 +++----
|
|
block/vdi.c | 7 +++----
|
|
block/vhdx.c | 7 +++----
|
|
block/vmdk.c | 7 +++----
|
|
block/vpc.c | 7 +++----
|
|
include/block/block.h | 3 +++
|
|
21 files changed, 76 insertions(+), 77 deletions(-)
|
|
|
|
diff --git a/block.c b/block.c
|
|
index 29e504b86a..0e841dcf09 100644
|
|
--- a/block.c
|
|
+++ b/block.c
|
|
@@ -2761,6 +2761,19 @@ BdrvChild *bdrv_open_child(const char *filename,
|
|
return bdrv_attach_child(parent, bs, bdref_key, child_role, 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)
|
|
+{
|
|
+ parent->file = bdrv_open_child(filename, options, bdref_key, parent,
|
|
+ &child_file, false, errp);
|
|
+
|
|
+ return parent->file ? 0 : -EINVAL;
|
|
+}
|
|
+
|
|
/* TODO Future callers may need to specify parent/child_role in order for
|
|
* option inheritance to work. Existing callers use it for the root node. */
|
|
BlockDriverState *bdrv_open_blockdev_ref(BlockdevRef *ref, Error **errp)
|
|
diff --git a/block/blkdebug.c b/block/blkdebug.c
|
|
index 5ae96c52b0..15210da7dd 100644
|
|
--- a/block/blkdebug.c
|
|
+++ b/block/blkdebug.c
|
|
@@ -420,10 +420,9 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
|
|
s->state = 1;
|
|
|
|
/* Open the image file */
|
|
- bs->file = bdrv_open_child(qemu_opt_get(opts, "x-image"), options, "image",
|
|
- bs, &child_file, false, &local_err);
|
|
- if (local_err) {
|
|
- ret = -EINVAL;
|
|
+ ret = bdrv_open_file_child(qemu_opt_get(opts, "x-image"), options, "image",
|
|
+ bs, &local_err);
|
|
+ if (ret < 0) {
|
|
error_propagate(errp, local_err);
|
|
goto out;
|
|
}
|
|
diff --git a/block/blklogwrites.c b/block/blklogwrites.c
|
|
index 04d8b33607..81149d432d 100644
|
|
--- a/block/blklogwrites.c
|
|
+++ b/block/blklogwrites.c
|
|
@@ -157,10 +157,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_file, false,
|
|
- &local_err);
|
|
- if (local_err) {
|
|
- ret = -EINVAL;
|
|
+ ret = bdrv_open_file_child(NULL, options, "file", bs, &local_err);
|
|
+ if (ret < 0) {
|
|
error_propagate(errp, local_err);
|
|
goto fail;
|
|
}
|
|
diff --git a/block/blkreplay.c b/block/blkreplay.c
|
|
index 2b7931b940..e07d137f31 100644
|
|
--- a/block/blkreplay.c
|
|
+++ b/block/blkreplay.c
|
|
@@ -27,10 +27,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_file, false, &local_err);
|
|
- if (local_err) {
|
|
- ret = -EINVAL;
|
|
+ ret = bdrv_open_file_child(NULL, options, "image", bs, &local_err);
|
|
+ if (ret < 0) {
|
|
error_propagate(errp, local_err);
|
|
goto fail;
|
|
}
|
|
diff --git a/block/blkverify.c b/block/blkverify.c
|
|
index 304b0a1368..65beeff3e5 100644
|
|
--- a/block/blkverify.c
|
|
+++ b/block/blkverify.c
|
|
@@ -124,10 +124,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_file, false, &local_err);
|
|
- if (local_err) {
|
|
- ret = -EINVAL;
|
|
+ ret = bdrv_open_file_child(qemu_opt_get(opts, "x-raw"), options, "raw",
|
|
+ bs, &local_err);
|
|
+ if (ret < 0) {
|
|
error_propagate(errp, local_err);
|
|
goto fail;
|
|
}
|
|
diff --git a/block/bochs.c b/block/bochs.c
|
|
index 962f18592d..d8833a1b94 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_file,
|
|
- 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 384c9735bb..94cfbe93b4 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_file,
|
|
- 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-on-read.c b/block/copy-on-read.c
|
|
index 6631f30205..bc1d83128e 100644
|
|
--- a/block/copy-on-read.c
|
|
+++ b/block/copy-on-read.c
|
|
@@ -28,10 +28,10 @@
|
|
static int cor_open(BlockDriverState *bs, QDict *options, int flags,
|
|
Error **errp)
|
|
{
|
|
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file, false,
|
|
- errp);
|
|
- if (!bs->file) {
|
|
- return -EINVAL;
|
|
+ int ret;
|
|
+ ret = bdrv_open_file_child(NULL, options, "file", bs, errp);
|
|
+ if (ret < 0) {
|
|
+ return ret;
|
|
}
|
|
|
|
bs->supported_write_flags = BDRV_REQ_WRITE_UNCHANGED |
|
|
diff --git a/block/crypto.c b/block/crypto.c
|
|
index 8237424ae6..bb92854cba 100644
|
|
--- a/block/crypto.c
|
|
+++ b/block/crypto.c
|
|
@@ -194,15 +194,14 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
|
|
BlockCrypto *crypto = bs->opaque;
|
|
QemuOpts *opts = NULL;
|
|
Error *local_err = 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_file,
|
|
- 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 &
|
|
@@ -211,6 +210,7 @@ static int block_crypto_open_generic(QCryptoBlockFormat format,
|
|
opts = qemu_opts_create(opts_spec, NULL, 0, &error_abort);
|
|
qemu_opts_absorb_qdict(opts, options, &local_err);
|
|
if (local_err) {
|
|
+ ret = -EINVAL;
|
|
error_propagate(errp, local_err);
|
|
goto cleanup;
|
|
}
|
|
@@ -220,6 +220,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 45f6b28f17..ad4141fbaa 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_file,
|
|
- 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/parallels.c b/block/parallels.c
|
|
index 00fae125d1..721cbcb168 100644
|
|
--- a/block/parallels.c
|
|
+++ b/block/parallels.c
|
|
@@ -728,10 +728,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_file,
|
|
- 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/qcow.c b/block/qcow.c
|
|
index 5bdf72ba33..04776d102f 100644
|
|
--- a/block/qcow.c
|
|
+++ b/block/qcow.c
|
|
@@ -130,10 +130,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_file,
|
|
- 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 c1992c571a..e3331570b2 100644
|
|
--- a/block/qcow2.c
|
|
+++ b/block/qcow2.c
|
|
@@ -1775,11 +1775,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_file,
|
|
- 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 77c7cef175..6948b0c62f 100644
|
|
--- a/block/qed.c
|
|
+++ b/block/qed.c
|
|
@@ -545,11 +545,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_file,
|
|
- 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 23b2993d74..52b40dfb22 100644
|
|
--- a/block/replication.c
|
|
+++ b/block/replication.c
|
|
@@ -90,10 +90,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_file,
|
|
- 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 0349f42257..0b3dd23214 100644
|
|
--- a/block/throttle.c
|
|
+++ b/block/throttle.c
|
|
@@ -81,10 +81,9 @@ static int throttle_open(BlockDriverState *bs, QDict *options,
|
|
char *group;
|
|
int ret;
|
|
|
|
- bs->file = bdrv_open_child(NULL, options, "file", bs,
|
|
- &child_file, 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 b9845a4cbd..fa7d2f41f7 100644
|
|
--- a/block/vdi.c
|
|
+++ b/block/vdi.c
|
|
@@ -378,10 +378,9 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
|
|
Error *local_err = NULL;
|
|
QemuUUID uuid_link, uuid_parent;
|
|
|
|
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
|
|
- 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 d6070b6fa8..7a414de2e4 100644
|
|
--- a/block/vhdx.c
|
|
+++ b/block/vhdx.c
|
|
@@ -904,10 +904,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_file,
|
|
- 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 bd36ece125..d0362b85f5 100644
|
|
--- a/block/vmdk.c
|
|
+++ b/block/vmdk.c
|
|
@@ -1243,10 +1243,9 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
|
|
uint32_t magic;
|
|
Error *local_err = NULL;
|
|
|
|
- bs->file = bdrv_open_child(NULL, options, "file", bs, &child_file,
|
|
- 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 3a88e28e2b..291172707b 100644
|
|
--- a/block/vpc.c
|
|
+++ b/block/vpc.c
|
|
@@ -228,10 +228,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_file,
|
|
- 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 50a07c1c33..e07b0786e2 100644
|
|
--- a/include/block/block.h
|
|
+++ b/include/block/block.h
|
|
@@ -303,6 +303,9 @@ BdrvChild *bdrv_open_child(const char *filename,
|
|
BlockDriverState* parent,
|
|
const 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);
|
|
void bdrv_set_backing_hd(BlockDriverState *bs, BlockDriverState *backing_hd,
|
|
Error **errp);
|
|
--
|
|
2.41.0.windows.1
|
|
|