* [PULL 00/11] Block layer patches
@ 2026-11-09 16:45 Kevin Wolf
2026-11-09 16:45 ` [PULL 01/11] iotests: add --quiet arg to hide env variable dump Kevin Wolf
` (11 more replies)
0 siblings, 12 replies; 13+ messages in thread
From: Kevin Wolf @ 2026-11-09 16:45 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, richard.henderson, qemu-devel
The following changes since commit 71f25c75417d31c214ba2cd26b273c114fc99987:
Merge tag 'pbouvier/pr/multi_target-20261106' of https://gitlab.com/p-b-o/qemu into staging (2026-11-06 12:28:21 -0800)
are available in the Git repository at:
https://repo.or.cz/qemu/kevin.git tags/for-upstream
for you to fetch changes up to 67198583a1ef3432c784f2802c5cda914bc14ca8:
block/vhdx: Prevent out-of-bounds BAT accesses with malicious vhdx files (2026-11-09 16:32:35 +0100)
----------------------------------------------------------------
Block layer patches
- qcow2: fix snapshot data corruption with discard-no-unref=on
- vmdk: Fix various bugs in handling malicious image files
- vhdx: Prevent out-of-bounds BAT accesses with malicious vhdx files
- iotests: add --quiet arg to hide env variable dump
----------------------------------------------------------------
Andrey Drobyshev (3):
iotests/290: add test case to check 'discard-no-unref' option behavior
qcow2: fix snapshot data corruption with discard-no-unref=on
iotests/290: add 'discard' and 'write -z -u' case with a snapshot
Daniel P. Berrangé (1):
iotests: add --quiet arg to hide env variable dump
Marc-André Lureau (1):
block: add missing coroutine_fn annotations
Peter Maydell (5):
block/vmdk: Avoid assertion if image file has no extents
block/vmdk: Avoid reading off the end of descriptor memory
block/vmdk: Use larger types for byte counts in vmdk_read_extent()
block/vmdk: Reject a zero cluster_sectors parameter
block/vmdk: Avoid overflowing multiplication in vmdk_open_vmdk4()
Thomas Huth (1):
block/vhdx: Prevent out-of-bounds BAT accesses with malicious vhdx files
include/block/blockjob_int.h | 2 +-
block/crypto.c | 13 +++++-----
block/io.c | 8 +++---
block/qcow2-cluster.c | 6 +++--
block/qcow2.c | 9 ++++---
block/vhdx.c | 6 +++++
block/vmdk.c | 26 +++++++++++++++++--
blockjob.c | 3 ++-
tests/qemu-iotests/testrunner.py | 8 +++---
tests/qemu-iotests/290 | 54 ++++++++++++++++++++++++++++++++++++++++
tests/qemu-iotests/290.out | 33 ++++++++++++++++++++++++
tests/qemu-iotests/check | 4 ++-
12 files changed, 150 insertions(+), 22 deletions(-)
^ permalink raw reply [flat|nested] 13+ messages in thread
* [PULL 01/11] iotests: add --quiet arg to hide env variable dump
2026-11-09 16:45 [PULL 00/11] Block layer patches Kevin Wolf
@ 2026-11-09 16:45 ` Kevin Wolf
2026-11-09 16:45 ` [PULL 02/11] block/vmdk: Avoid assertion if image file has no extents Kevin Wolf
` (10 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Kevin Wolf @ 2026-11-09 16:45 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, richard.henderson, qemu-devel
From: Daniel P. Berrangé <berrange@redhat.com>
Every test run dumps a long list of environment variable settings.
While this is often useful, if you are trying to reproduce a bug
while repeatedly running a single test it can be quite noisy. Add
a --quiet flag to 'check' which allows the env variable dump to
be hidden. With this is only prints out the tests being run and
the overall status on completion.
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Message-ID: <20261102163447.3613901-1-berrange@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
tests/qemu-iotests/testrunner.py | 8 +++++---
tests/qemu-iotests/check | 4 +++-
2 files changed, 8 insertions(+), 4 deletions(-)
diff --git a/tests/qemu-iotests/testrunner.py b/tests/qemu-iotests/testrunner.py
index 729680da4aa..f35e65f805f 100644
--- a/tests/qemu-iotests/testrunner.py
+++ b/tests/qemu-iotests/testrunner.py
@@ -376,7 +376,8 @@ def run_test(self, test: str,
sys.stdout.flush()
return res
- def run_tests(self, tests: List[str], jobs: int = 1) -> bool:
+ def run_tests(self, tests: List[str], jobs: int = 1,
+ quiet: bool = False) -> bool:
n_run = 0
failed = []
notrun = []
@@ -384,9 +385,10 @@ def run_tests(self, tests: List[str], jobs: int = 1) -> bool:
if self.tap:
print('TAP version 13')
- self.env.print_env('# ')
+ if not quiet:
+ self.env.print_env('# ')
print('1..%d' % len(tests))
- else:
+ elif not quiet:
self.env.print_env()
test_field_width = max(len(os.path.basename(t)) for t in tests) + 2
diff --git a/tests/qemu-iotests/check b/tests/qemu-iotests/check
index 3941eac8e21..c8ba536970c 100755
--- a/tests/qemu-iotests/check
+++ b/tests/qemu-iotests/check
@@ -46,6 +46,8 @@ def make_argparser() -> argparse.ArgumentParser:
description="Test run options",
formatter_class=argparse.ArgumentDefaultsHelpFormatter)
+ p.add_argument('-q', '--quiet', action='store_true',
+ help='reduce output verbosity to only test results')
p.add_argument('-n', '--dry-run', action='store_true',
help='show me, do not run tests')
p.add_argument('-j', dest='jobs', type=int, default=1,
@@ -230,6 +232,6 @@ if __name__ == '__main__':
with TestRunner(env, tap=args.tap,
color=args.color) as tr:
paths = [os.path.join(env.source_iotests, t) for t in tests]
- ok = tr.run_tests(paths, args.jobs)
+ ok = tr.run_tests(paths, args.jobs, args.quiet)
if not ok:
sys.exit(1)
--
2.56.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PULL 02/11] block/vmdk: Avoid assertion if image file has no extents
2026-11-09 16:45 [PULL 00/11] Block layer patches Kevin Wolf
2026-11-09 16:45 ` [PULL 01/11] iotests: add --quiet arg to hide env variable dump Kevin Wolf
@ 2026-11-09 16:45 ` Kevin Wolf
2026-11-09 16:45 ` [PULL 03/11] block/vmdk: Avoid reading off the end of descriptor memory Kevin Wolf
` (9 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Kevin Wolf @ 2026-11-09 16:45 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, richard.henderson, qemu-devel
From: Peter Maydell <peter.maydell@linaro.org>
On a malformed image file which has no extents in it, we will open the file
but then fall over on an assertion in vmdk_co_get_info():
$ cat bad.vmdk
# Disk DescriptorFile
version=1
CID=fffffffe
parentCID=ffffffff
createType="vmfs"
$ qemu-img info -f vmdk /tmp/zz9
qemu-img: ../../block/vmdk.c:3104: int vmdk_co_get_info(BlockDriverState *, BlockDriverInfo *): Assertion `s->num_extents' failed.
Aborted (core dumped)
(This was noted in passing in the report of #4571.)
Cc: qemu-stable@nongnu.org
Fixes: 7fa60fa3778f1c7336 ("VMDK: open/read/write for monolithicFlat image")
Reported-by: router0mail <https://gitlab.com/router0mail>
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-ID: <20261103143516.2182626-2-peter.maydell@linaro.org>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/block/vmdk.c b/block/vmdk.c
index b6e78a2b5d9..86059e1fa08 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1301,6 +1301,12 @@ vmdk_parse_extents(const char *desc, BlockDriverState *bs, QDict *options,
extent->type = g_strdup(type);
}
+ if (s->num_extents == 0) {
+ error_setg(errp, "Invalid file: no extent lines present");
+ ret = -EINVAL;
+ goto out;
+ }
+
ret = 0;
goto out;
--
2.56.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PULL 03/11] block/vmdk: Avoid reading off the end of descriptor memory
2026-11-09 16:45 [PULL 00/11] Block layer patches Kevin Wolf
2026-11-09 16:45 ` [PULL 01/11] iotests: add --quiet arg to hide env variable dump Kevin Wolf
2026-11-09 16:45 ` [PULL 02/11] block/vmdk: Avoid assertion if image file has no extents Kevin Wolf
@ 2026-11-09 16:45 ` Kevin Wolf
2026-11-09 16:45 ` [PULL 04/11] block/vmdk: Use larger types for byte counts in vmdk_read_extent() Kevin Wolf
` (8 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Kevin Wolf @ 2026-11-09 16:45 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, richard.henderson, qemu-devel
From: Peter Maydell <peter.maydell@linaro.org>
In vmdk_parent_open() and vmdk_read_cid(), we read DESC_SIZE bytes
from the image file into a malloc'd buffer, and then look through it
for a keyword using strstr(). If found, we skip past the keyword and
attempt to parse a value from the next part of the buffer. However,
we failed to check whether the end of the keyword is right at the end
of the buffer, and so a malicious image can cause us to read off the
end when parsing the value part.
Check for this condition before attempting to parse the value.
The worst case here is that the image causes us to read some junk
from the heap into the BlockDriverState backing_file and
auto_backing_file fields; the image could control those anyway, and
it's unlikely that this heap data could e.g. be leaked to the guest.
Cc: qemu-stable@nongnu.org
Reported-by: router0mail <https://gitlab.com/router0mail>
Fixes: 5f4da8c0f3736b2 ("New multiple snapshot support for VMDK")
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4571
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-ID: <20261103143516.2182626-3-peter.maydell@linaro.org>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/block/vmdk.c b/block/vmdk.c
index 86059e1fa08..6e4e0423dc9 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -337,6 +337,10 @@ vmdk_read_cid(BlockDriverState *bs, int parent, uint32_t *pcid)
goto out;
}
p_name += cid_str_size;
+ if (p_name >= desc + DESC_SIZE) {
+ ret = -EINVAL;
+ goto out;
+ }
if (sscanf(p_name, "%" SCNx32, &cid) != 1) {
ret = -EINVAL;
goto out;
@@ -508,6 +512,10 @@ static int GRAPH_RDLOCK vmdk_parent_open(BlockDriverState *bs)
char *end_name;
p_name += sizeof("parentFileNameHint") + 1;
+ if (p_name >= desc + DESC_SIZE + 1) {
+ ret = -EINVAL;
+ goto out;
+ }
end_name = strchr(p_name, '\"');
if (end_name == NULL) {
ret = -EINVAL;
--
2.56.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PULL 04/11] block/vmdk: Use larger types for byte counts in vmdk_read_extent()
2026-11-09 16:45 [PULL 00/11] Block layer patches Kevin Wolf
` (2 preceding siblings ...)
2026-11-09 16:45 ` [PULL 03/11] block/vmdk: Avoid reading off the end of descriptor memory Kevin Wolf
@ 2026-11-09 16:45 ` Kevin Wolf
2026-11-09 16:45 ` [PULL 05/11] block/vmdk: Reject a zero cluster_sectors parameter Kevin Wolf
` (7 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Kevin Wolf @ 2026-11-09 16:45 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, richard.henderson, qemu-devel
From: Peter Maydell <peter.maydell@linaro.org>
In vmdk_read_extent() we use 'int' for cluster_bytes and buf_bytes.
However, cluster_bytes is extent->cluster_sectors * 512 and buf_bytes
is cluster_bytes * 2. The maximum value for extent->cluster_sectors
(enforced in vmdk_add_extent()) is 0x20_0000, and so the worst case
for buf_bytes is 0x8000_0000, which overflows a signed int.
Make the variable types here int64_t, which matches the type used by
bdrv_co_pread()'s bytes argument and by extent->cluster_sectors.
The worst case thing that a malicious VMDK image could do is cause us
to try to g_malloc() 0xffffffff80000000, which will cause QEMU to
abort(), so this is a self-denial-of-service only, and so a hardening
bug rather than a security issue.
Cc: qemu-stable@nongnu.org
Fixes: 2b2c8c5dec6ba ("VMDK: read/write compressed extent")
Reported-by: boy juju <agx1657748706@gmail.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3843
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-ID: <20261103143516.2182626-4-peter.maydell@linaro.org>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/block/vmdk.c b/block/vmdk.c
index 6e4e0423dc9..bd18d32085f 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1940,7 +1940,7 @@ vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
int64_t offset_in_cluster, QEMUIOVector *qiov, int bytes)
{
int ret;
- int cluster_bytes, buf_bytes;
+ int64_t cluster_bytes, buf_bytes;
uint8_t *cluster_buf, *compressed_data;
uint8_t *uncomp_buf;
uint32_t data_len;
--
2.56.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PULL 05/11] block/vmdk: Reject a zero cluster_sectors parameter
2026-11-09 16:45 [PULL 00/11] Block layer patches Kevin Wolf
` (3 preceding siblings ...)
2026-11-09 16:45 ` [PULL 04/11] block/vmdk: Use larger types for byte counts in vmdk_read_extent() Kevin Wolf
@ 2026-11-09 16:45 ` Kevin Wolf
2026-11-09 16:45 ` [PULL 06/11] block/vmdk: Avoid overflowing multiplication in vmdk_open_vmdk4() Kevin Wolf
` (6 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Kevin Wolf @ 2026-11-09 16:45 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, richard.henderson, qemu-devel
From: Peter Maydell <peter.maydell@linaro.org>
In vmdk_add_extent() we reject image files with an excessively large
cluster_sectors parameter, but have no lower bound. In particular,
if the cluster_sectors is 0 then we will set l1_entry_sectors also to
0, and later crash with a SIGFPE for division by zero.
Reject a zero cluster_sectors value, unless this is a flat extent (in
which case cluster_sectors isn't relevant and the callsite always
passes us zero).
The worst case here is a self-denial-of-service with a QEMU crash,
so this is a hardening bug.
Cc: qemu-stable@nongnu.org
Fixes: b3976d3c8b89 ("VMDK: introduce VmdkExtent")
Reported-by: Tristan <https://gitlab.com/TristanInSec>
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4017
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-ID: <20261103143516.2182626-5-peter.maydell@linaro.org>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/block/vmdk.c b/block/vmdk.c
index bd18d32085f..d7e23ae8098 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -552,6 +552,11 @@ static int vmdk_add_extent(BlockDriverState *bs,
BDRVVmdkState *s = bs->opaque;
int64_t nb_sectors;
+ if (!flat && cluster_sectors == 0) {
+ error_setg(errp, "Invalid zero granularity, image may be corrupt");
+ return -EINVAL;
+ }
+
if (cluster_sectors > 0x200000) {
/* 0x200000 * 512Bytes = 1GB for one cluster is unrealistic */
error_setg(errp, "Invalid granularity, image may be corrupt");
--
2.56.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PULL 06/11] block/vmdk: Avoid overflowing multiplication in vmdk_open_vmdk4()
2026-11-09 16:45 [PULL 00/11] Block layer patches Kevin Wolf
` (4 preceding siblings ...)
2026-11-09 16:45 ` [PULL 05/11] block/vmdk: Reject a zero cluster_sectors parameter Kevin Wolf
@ 2026-11-09 16:45 ` Kevin Wolf
2026-11-09 16:45 ` [PULL 07/11] block: add missing coroutine_fn annotations Kevin Wolf
` (5 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Kevin Wolf @ 2026-11-09 16:45 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, richard.henderson, qemu-devel
From: Peter Maydell <peter.maydell@linaro.org>
In vmdk_open_vmdk4() we set the uint32_t l1_entry_sectors with:
l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gt)
* le64_to_cpu(header.granularity);
We have checked that num_gtes_per_gt is at most 512, but the
header.granularity has not been checked at this point, and so the
multiply can overflow the 32-bit variable. This overflow is harmless
beacuse we're about to call vmdk_add_extent(), which will fail if the
header.granularity (cluster_sectors) is more than 0x20_0000, but it's
a potential trap for the future if code that relies on the
l1_entry_sectors value gets added between where we set it and where
we make that check.
Check for overlarge granularity at the point of multiplication so
it's clear we can't overflow.
Cc: qemu-stable@nongnu.org
Reported-by: Tristan <https://gitlab.com/TristanInSec>
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4029
Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Message-ID: <20261103143516.2182626-6-peter.maydell@linaro.org>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vmdk.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/block/vmdk.c b/block/vmdk.c
index d7e23ae8098..a9bd8a4245f 100644
--- a/block/vmdk.c
+++ b/block/vmdk.c
@@ -1052,7 +1052,10 @@ vmdk_open_vmdk4(BlockDriverState *bs, BdrvChild *file, int flags,
error_setg(errp, "L2 table size too big");
return -EINVAL;
}
-
+ if (le64_to_cpu(header.granularity) > 0x200000) {
+ error_setg(errp, "Invalid granularity, image may be corrupt");
+ return -EFBIG;
+ }
l1_entry_sectors = le32_to_cpu(header.num_gtes_per_gt)
* le64_to_cpu(header.granularity);
if (l1_entry_sectors == 0) {
--
2.56.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PULL 07/11] block: add missing coroutine_fn annotations
2026-11-09 16:45 [PULL 00/11] Block layer patches Kevin Wolf
` (5 preceding siblings ...)
2026-11-09 16:45 ` [PULL 06/11] block/vmdk: Avoid overflowing multiplication in vmdk_open_vmdk4() Kevin Wolf
@ 2026-11-09 16:45 ` Kevin Wolf
2026-11-09 16:45 ` [PULL 08/11] iotests/290: add test case to check 'discard-no-unref' option behavior Kevin Wolf
` (4 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Kevin Wolf @ 2026-11-09 16:45 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, richard.henderson, qemu-devel
From: Marc-André Lureau <marcandre.lureau@redhat.com>
The functions call coroutine functions or are called by coroutine.
Add an assert() in qcow2_do_close() code path which calls a
no_coroutine_fn bdrv_graph_wrlock_drained().
Add an assert() in qcow2_update_options_commit() in the coroutine
path.
Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-ID: <20260730171027.1023696-1-marcandre.lureau@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
include/block/blockjob_int.h | 2 +-
block/crypto.c | 13 +++++++------
block/io.c | 8 +++++---
block/qcow2.c | 9 ++++++---
blockjob.c | 3 ++-
5 files changed, 21 insertions(+), 14 deletions(-)
diff --git a/include/block/blockjob_int.h b/include/block/blockjob_int.h
index 4c3d2e25a20..34e172874fa 100644
--- a/include/block/blockjob_int.h
+++ b/include/block/blockjob_int.h
@@ -150,7 +150,7 @@ void block_job_ratelimit_processed_bytes(BlockJob *job, uint64_t n);
* Put the job to sleep (assuming that it wasn't canceled) to throttle it to the
* right speed according to its rate limiting.
*/
-void block_job_ratelimit_sleep(BlockJob *job);
+void coroutine_fn block_job_ratelimit_sleep(BlockJob *job);
/**
* block_job_error_action:
diff --git a/block/crypto.c b/block/crypto.c
index 36abb7af468..8a34d92fded 100644
--- a/block/crypto.c
+++ b/block/crypto.c
@@ -56,12 +56,13 @@ static int block_crypto_probe_generic(QCryptoBlockFormat format,
}
-static int block_crypto_read_func(QCryptoBlock *block,
- size_t offset,
- uint8_t *buf,
- size_t buflen,
- void *opaque,
- Error **errp)
+static int coroutine_mixed_fn
+block_crypto_read_func(QCryptoBlock *block,
+ size_t offset,
+ uint8_t *buf,
+ size_t buflen,
+ void *opaque,
+ Error **errp)
{
BlockDriverState *bs = opaque;
BlockCrypto *crypto = bs->opaque;
diff --git a/block/io.c b/block/io.c
index 06b1fc13b9f..0f81b7e6bb9 100644
--- a/block/io.c
+++ b/block/io.c
@@ -354,8 +354,9 @@ static void coroutine_fn bdrv_co_yield_to_drain(BlockDriverState *bs,
assert(data.done);
}
-static void bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent,
- bool poll)
+static void coroutine_mixed_fn
+bdrv_do_drained_begin(BlockDriverState *bs, BdrvChild *parent,
+ bool poll)
{
IO_OR_GS_CODE();
@@ -405,7 +406,8 @@ bdrv_drained_begin(BlockDriverState *bs)
* This function does not poll, nor must any of its recursively called
* functions.
*/
-static void bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent)
+static void coroutine_mixed_fn
+bdrv_do_drained_end(BlockDriverState *bs, BdrvChild *parent)
{
IO_OR_GS_CODE();
diff --git a/block/qcow2.c b/block/qcow2.c
index 0358bc04f33..59cc93ba746 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1287,9 +1287,10 @@ fail:
}
/* s_locked specifies whether s->lock is held or not */
-static void qcow2_update_options_commit(BlockDriverState *bs,
- Qcow2ReopenState *r,
- bool s_locked)
+static coroutine_mixed_fn void
+qcow2_update_options_commit(BlockDriverState *bs,
+ Qcow2ReopenState *r,
+ bool s_locked)
{
BDRVQcow2State *s = bs->opaque;
int i;
@@ -1299,6 +1300,7 @@ static void qcow2_update_options_commit(BlockDriverState *bs,
* table caches
*/
if (s_locked) {
+ assert(qemu_in_coroutine());
cache_clean_timer_co_locked_del_and_wait(bs);
} else {
cache_clean_timer_del_and_wait(bs);
@@ -2919,6 +2921,7 @@ qcow2_do_close(BlockDriverState *bs, bool close_data_file)
g_free(s->image_backing_format);
if (close_data_file && has_data_file(bs)) {
+ assert(!qemu_in_coroutine());
GLOBAL_STATE_CODE();
bdrv_graph_rdunlock_main_loop();
bdrv_graph_wrlock_drained();
diff --git a/blockjob.c b/blockjob.c
index f3b11cc7a19..f3ad6a93125 100644
--- a/blockjob.c
+++ b/blockjob.c
@@ -338,7 +338,8 @@ void block_job_ratelimit_processed_bytes(BlockJob *job, uint64_t n)
ratelimit_calculate_delay(&job->limit, n);
}
-void block_job_ratelimit_sleep(BlockJob *job)
+void coroutine_fn
+block_job_ratelimit_sleep(BlockJob *job)
{
uint64_t delay_ns;
--
2.56.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PULL 08/11] iotests/290: add test case to check 'discard-no-unref' option behavior
2026-11-09 16:45 [PULL 00/11] Block layer patches Kevin Wolf
` (6 preceding siblings ...)
2026-11-09 16:45 ` [PULL 07/11] block: add missing coroutine_fn annotations Kevin Wolf
@ 2026-11-09 16:45 ` Kevin Wolf
2026-11-09 16:45 ` [PULL 09/11] qcow2: fix snapshot data corruption with discard-no-unref=on Kevin Wolf
` (3 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Kevin Wolf @ 2026-11-09 16:45 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, richard.henderson, qemu-devel
From: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
We basically fill 2 images with identical data and perform discard
operations with and without 'discard-no-unref' enabled. Then we check
that images still read identically, that their disk usage is the same
(i.e. fallocate(FALLOC_FL_PUNCH_HOLE|FALLOC_FL_KEEP_SIZE) is called for
both) and that with the option enabled cluster is still marked as
allocated in "qemu-img map" output. We also check that the option
doesn't work with qcow2 v2 images.
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Message-ID: <20261105161515.794213-2-andrey.drobyshev@virtuozzo.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
tests/qemu-iotests/290 | 38 ++++++++++++++++++++++++++++++++++++++
tests/qemu-iotests/290.out | 28 ++++++++++++++++++++++++++++
2 files changed, 66 insertions(+)
diff --git a/tests/qemu-iotests/290 b/tests/qemu-iotests/290
index 341a25f96b5..cf4ff6c2bac 100755
--- a/tests/qemu-iotests/290
+++ b/tests/qemu-iotests/290
@@ -29,6 +29,7 @@ status=1 # failure is the default!
_cleanup()
{
_cleanup_test_img
+ _rm_test_img "$TEST_IMG.nounref"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
@@ -40,6 +41,7 @@ _supported_fmt qcow2
_supported_proto file fuse
_supported_os Linux
_unsupported_imgopts 'compat=0.10' refcount_bits data_file compression_type
+_require_disk_usage
echo
echo "### Test 'qemu-io -c discard' on a QCOW2 image without a backing file"
@@ -90,6 +92,42 @@ for qcow2_compat in 0.10 1.1; do
$QEMU_IMG map "$TEST_IMG" | _filter_testdir
done
+echo
+echo "### Test 'qemu-io -c discard' with 'discard-no-unref' option enabled"
+echo
+
+echo "# Check that qcow2 v2 images don't support 'discard-no-unref' option"
+NOUNREF_IMG="$TEST_IMG.nounref"
+TEST_IMG="$NOUNREF_IMG" _make_test_img -o "compat=0.10" 128k
+# This should immediately fail with an error
+$QEMU_IO -c 'reopen -o discard-no-unref=on' "$NOUNREF_IMG" | _filter_qemu_io
+
+echo "# Create two compat=1.1 images and fill them with identical data"
+_make_test_img -o "compat=1.1" 128k
+TEST_IMG="$NOUNREF_IMG" _make_test_img -o "compat=1.1" 128k
+$QEMU_IO -c 'write -P 0xaa 0 128k' "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c 'write -P 0xaa 0 128k' "$NOUNREF_IMG" | _filter_qemu_io
+
+echo "# Enable 'discard-no-unref' in one of them, discard 2nd cluster in both"
+$QEMU_IO -c 'discard 64k 64k' "$TEST_IMG" | _filter_qemu_io
+$QEMU_IO -c 'reopen -o discard-no-unref=on' \
+ -c 'discard 64k 64k' "$NOUNREF_IMG" | _filter_qemu_io
+
+echo "# Compare disk usage of the 2 images"
+# Don't check the exact disk usage values but rather that they're equal
+usage1=$(disk_usage "$TEST_IMG")
+usage2=$(disk_usage "$NOUNREF_IMG")
+echo "disk_usage($TEST_IMG) - disk_usage($NOUNREF_IMG) = $((usage1 - usage2))" \
+ | _filter_testdir | _filter_imgfmt
+
+echo "# Check that images are still identical"
+$QEMU_IMG compare "$TEST_IMG" "$NOUNREF_IMG"
+
+echo "# Output of qemu-img map for the image with dropped reference"
+$QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
+echo "# Output of qemu-img map for the image with kept reference"
+$QEMU_IMG map --output=json "$NOUNREF_IMG" | _filter_qemu_img_map
+
# success, all done
echo "*** done"
rm -f $seq.full
diff --git a/tests/qemu-iotests/290.out b/tests/qemu-iotests/290.out
index 22b476594fb..d8f8d5ff493 100644
--- a/tests/qemu-iotests/290.out
+++ b/tests/qemu-iotests/290.out
@@ -58,4 +58,32 @@ read 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
# Output of qemu-img map
Offset Length Mapped to File
+
+### Test 'qemu-io -c discard' with 'discard-no-unref' option enabled
+
+# Check that qcow2 v2 images don't support 'discard-no-unref' option
+Formatting 'TEST_DIR/t.IMGFMT.nounref', fmt=IMGFMT size=131072
+qemu-io: discard-no-unref is only supported since qcow2 version 3
+# Create two compat=1.1 images and fill them with identical data
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072
+Formatting 'TEST_DIR/t.IMGFMT.nounref', fmt=IMGFMT size=131072
+wrote 131072/131072 bytes at offset 0
+128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+wrote 131072/131072 bytes at offset 0
+128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+# Enable 'discard-no-unref' in one of them, discard 2nd cluster in both
+discard 65536/65536 bytes at offset 65536
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+discard 65536/65536 bytes at offset 65536
+64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
+# Compare disk usage of the 2 images
+disk_usage(TEST_DIR/t.IMGFMT) - disk_usage(TEST_DIR/t.IMGFMT.nounref) = 0
+# Check that images are still identical
+Images are identical.
+# Output of qemu-img map for the image with dropped reference
+[{ "start": 0, "length": 65536, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET},
+{ "start": 65536, "length": 65536, "depth": 0, "present": true, "zero": true, "data": false, "compressed": false}]
+# Output of qemu-img map for the image with kept reference
+[{ "start": 0, "length": 65536, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET},
+{ "start": 65536, "length": 65536, "depth": 0, "present": true, "zero": true, "data": false, "compressed": false, "offset": OFFSET}]
*** done
--
2.56.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PULL 09/11] qcow2: fix snapshot data corruption with discard-no-unref=on
2026-11-09 16:45 [PULL 00/11] Block layer patches Kevin Wolf
` (7 preceding siblings ...)
2026-11-09 16:45 ` [PULL 08/11] iotests/290: add test case to check 'discard-no-unref' option behavior Kevin Wolf
@ 2026-11-09 16:45 ` Kevin Wolf
2026-11-09 16:45 ` [PULL 10/11] iotests/290: add 'discard' and 'write -z -u' case with a snapshot Kevin Wolf
` (2 subsequent siblings)
11 siblings, 0 replies; 13+ messages in thread
From: Kevin Wolf @ 2026-11-09 16:45 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, richard.henderson, qemu-devel
From: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Whenever option discard-no-unref=on is enabled, we bypass refcount
machinery and unconditionally punch hole in the data on 'discard' and
'write -z -u' paths. However, when this same cluster is also referenced
by an internal snapshot, such operations lead to problems. The active L2
table is copied before it is changed, so the snapshot metadata stays
correct, but the host range under it is punched out and the snapshot reads
zeroes there afterwards. qemu-img check finds nothing wrong.
Fix this by guarding the 'keep_reference' flag by the presence of the
QCOW_OFLAG_COPIED bit. I.e. only proceed with unconditional data
punching if we own this cluster exclusively.
Cc: qemu-stable@nongnu.org
Fixes: 42a2890a76f4 ("qcow2: add discard-no-unref option")
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20261105161515.794213-3-andrey.drobyshev@virtuozzo.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/qcow2-cluster.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
index e02fae6a0c6..cc473c7c796 100644
--- a/block/qcow2-cluster.c
+++ b/block/qcow2-cluster.c
@@ -1953,6 +1953,7 @@ discard_in_l2_slice(BlockDriverState *bs, uint64_t offset, uint64_t nb_clusters,
QCow2ClusterType cluster_type =
qcow2_get_cluster_type(bs, old_l2_entry);
bool keep_reference = (cluster_type != QCOW2_CLUSTER_COMPRESSED) &&
+ (old_l2_entry & QCOW_OFLAG_COPIED) &&
!full_discard &&
(s->discard_no_unref &&
type == QCOW2_DISCARD_REQUEST);
@@ -2097,8 +2098,9 @@ zero_in_l2_slice(BlockDriverState *bs, uint64_t offset,
QCow2ClusterType type = qcow2_get_cluster_type(bs, old_l2_entry);
bool unmap = (type == QCOW2_CLUSTER_COMPRESSED) ||
((flags & BDRV_REQ_MAY_UNMAP) && qcow2_cluster_is_allocated(type));
- bool keep_reference =
- (s->discard_no_unref && type != QCOW2_CLUSTER_COMPRESSED);
+ bool keep_reference = s->discard_no_unref &&
+ type != QCOW2_CLUSTER_COMPRESSED &&
+ (old_l2_entry & QCOW_OFLAG_COPIED);
uint64_t new_l2_entry = old_l2_entry;
uint64_t new_l2_bitmap = old_l2_bitmap;
--
2.56.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PULL 10/11] iotests/290: add 'discard' and 'write -z -u' case with a snapshot
2026-11-09 16:45 [PULL 00/11] Block layer patches Kevin Wolf
` (8 preceding siblings ...)
2026-11-09 16:45 ` [PULL 09/11] qcow2: fix snapshot data corruption with discard-no-unref=on Kevin Wolf
@ 2026-11-09 16:45 ` Kevin Wolf
2026-11-09 16:45 ` [PULL 11/11] block/vhdx: Prevent out-of-bounds BAT accesses with malicious vhdx files Kevin Wolf
2026-11-09 20:53 ` [PULL 00/11] Block layer patches Richard Henderson
11 siblings, 0 replies; 13+ messages in thread
From: Kevin Wolf @ 2026-11-09 16:45 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, richard.henderson, qemu-devel
From: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Before the previous commit, issuing 'discard' and 'write -z -u'
operations with discard-no-unref=on option enabled led to data
corruption. Add a test to cover this case.
Signed-off-by: Andrey Drobyshev <andrey.drobyshev@virtuozzo.com>
Reviewed-by: Denis V. Lunev <den@openvz.org>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Message-ID: <20261105161515.794213-4-andrey.drobyshev@virtuozzo.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
tests/qemu-iotests/290 | 16 ++++++++++++++++
tests/qemu-iotests/290.out | 5 +++++
2 files changed, 21 insertions(+)
diff --git a/tests/qemu-iotests/290 b/tests/qemu-iotests/290
index cf4ff6c2bac..b9a71b0cee4 100755
--- a/tests/qemu-iotests/290
+++ b/tests/qemu-iotests/290
@@ -128,6 +128,22 @@ $QEMU_IMG map --output=json "$TEST_IMG" | _filter_qemu_img_map
echo "# Output of qemu-img map for the image with kept reference"
$QEMU_IMG map --output=json "$NOUNREF_IMG" | _filter_qemu_img_map
+echo
+echo "### Discard with 'discard-no-unref' on a cluster shared with a snapshot"
+echo
+
+_make_test_img 128k
+$QEMU_IO -c 'write -q -P 0xaa 0 128k' "$TEST_IMG" | _filter_qemu_io
+$QEMU_IMG snapshot -c snap "$TEST_IMG"
+QEMU_IO_OPTIONS=$QEMU_IO_OPTIONS_NO_FMT \
+$QEMU_IO -c 'discard -q 0 64k' -c 'write -q -z -u 64k 64k' --image-opts \
+ "driver=$IMGFMT,file.filename=$TEST_IMG,discard-no-unref=on" \
+ | _filter_qemu_io
+$QEMU_IO -c 'read -q -P 0 0 128k' "$TEST_IMG" | _filter_qemu_io
+$QEMU_IMG snapshot -a snap "$TEST_IMG"
+$QEMU_IO -c 'read -q -P 0xaa 0 128k' "$TEST_IMG" | _filter_qemu_io
+_check_test_img
+
# success, all done
echo "*** done"
rm -f $seq.full
diff --git a/tests/qemu-iotests/290.out b/tests/qemu-iotests/290.out
index d8f8d5ff493..264fbcb28ca 100644
--- a/tests/qemu-iotests/290.out
+++ b/tests/qemu-iotests/290.out
@@ -86,4 +86,9 @@ Images are identical.
# Output of qemu-img map for the image with kept reference
[{ "start": 0, "length": 65536, "depth": 0, "present": true, "zero": false, "data": true, "compressed": false, "offset": OFFSET},
{ "start": 65536, "length": 65536, "depth": 0, "present": true, "zero": true, "data": false, "compressed": false, "offset": OFFSET}]
+
+### Discard with 'discard-no-unref' on a cluster shared with a snapshot
+
+Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=131072
+No errors were found on the image.
*** done
--
2.56.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* [PULL 11/11] block/vhdx: Prevent out-of-bounds BAT accesses with malicious vhdx files
2026-11-09 16:45 [PULL 00/11] Block layer patches Kevin Wolf
` (9 preceding siblings ...)
2026-11-09 16:45 ` [PULL 10/11] iotests/290: add 'discard' and 'write -z -u' case with a snapshot Kevin Wolf
@ 2026-11-09 16:45 ` Kevin Wolf
2026-11-09 20:53 ` [PULL 00/11] Block layer patches Richard Henderson
11 siblings, 0 replies; 13+ messages in thread
From: Kevin Wolf @ 2026-11-09 16:45 UTC (permalink / raw)
To: qemu-block; +Cc: kwolf, richard.henderson, qemu-devel
From: Thomas Huth <thuth@redhat.com>
virtual_disk_size is read directly from a VHDX image's metadata region
and never checked for sane sizes. The 64 TiB limit (VHDX_MAX_IMAGE_SIZE)
is only enforced in vhdx_co_create(), so it limits images QEMU creates
but never images QEMU opens.
Without the bound, vhdx_calc_bat_entries() computes the block count
into a uint32_t, so a huge image size gets truncated and the BAT is
undersized relative to total_sectors.
vhdx_block_translate() then converts sector numbers into BAT indices
with no bounds check, allowing out-of-bounds access on the BAT array
from both the read and write paths.
To fix the problem, add a VHDX_MAX_IMAGE_SIZE check to vhdx_parse_metadata()
so images opened for reading are subject to the same limit as images
created by QEMU.
With this limit, the calculation in vhdx_calc_bat_entries() cannot get
truncated anymore (block_size is at least 1 MiB):
VHDX_MAX_IMAGE_SIZE / block_size = 64 TiB / 1 MiB = 64 MiB
... and 64 MiB fit nicely into 32 bits.
To be really on the safe side, let's also add an assertion in
vhdx_block_translate() to catch accesses that exceeds the allocated
entry count.
Buglink: https://gitlab.com/qemu-project/qemu/-/work_items/3762
Reported-by: Daniel Wade <danjwade95@gmail.com>
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4470
Reported-by: Mayank Jangid (OpenSec)
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4487
Reported-by: Ken Hsu, Royce Lu, and Bo Qu of Palo Alto Networks
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4638
Reported-by: Thai Duong (Calif.io)
Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4733
Reported-by: Xiang Chen
Signed-off-by: Thomas Huth <thuth@redhat.com>
Message-ID: <20261023130023.539252-1-thuth@redhat.com>
Reviewed-by: Kevin Wolf <kwolf@redhat.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
block/vhdx.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/block/vhdx.c b/block/vhdx.c
index c16e4a00c8d..8013a90a1a4 100644
--- a/block/vhdx.c
+++ b/block/vhdx.c
@@ -815,6 +815,11 @@ vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
}
s->virtual_disk_size = le64_to_cpu(s->virtual_disk_size);
+ if (s->virtual_disk_size > VHDX_MAX_IMAGE_SIZE) {
+ ret = -EFBIG;
+ goto exit;
+ }
+
s->logical_sector_size = le32_to_cpu(s->logical_sector_size);
s->physical_sector_size = le32_to_cpu(s->physical_sector_size);
@@ -1149,6 +1154,7 @@ static void vhdx_block_translate(BDRVVHDXState *s, int64_t sector_num,
sinfo->bytes_avail = sinfo->sectors_avail << s->logical_sector_size_bits;
+ assert(sinfo->bat_idx < s->bat_entries);
sinfo->file_offset = s->bat[sinfo->bat_idx] & VHDX_BAT_FILE_OFF_MASK;
sinfo->block_offset = block_offset << s->logical_sector_size_bits;
--
2.56.0
^ permalink raw reply related [flat|nested] 13+ messages in thread
* Re: [PULL 00/11] Block layer patches
2026-11-09 16:45 [PULL 00/11] Block layer patches Kevin Wolf
` (10 preceding siblings ...)
2026-11-09 16:45 ` [PULL 11/11] block/vhdx: Prevent out-of-bounds BAT accesses with malicious vhdx files Kevin Wolf
@ 2026-11-09 20:53 ` Richard Henderson
11 siblings, 0 replies; 13+ messages in thread
From: Richard Henderson @ 2026-11-09 20:53 UTC (permalink / raw)
To: Kevin Wolf, qemu-block; +Cc: qemu-devel
On 11/9/26 08:45, Kevin Wolf wrote:
> The following changes since commit 71f25c75417d31c214ba2cd26b273c114fc99987:
>
> Merge tag 'pbouvier/pr/multi_target-20261106' ofhttps://gitlab.com/p-b-o/qemu into staging (2026-11-06 12:28:21 -0800)
>
> are available in the Git repository at:
>
> https://repo.or.cz/qemu/kevin.git tags/for-upstream
>
> for you to fetch changes up to 67198583a1ef3432c784f2802c5cda914bc14ca8:
>
> block/vhdx: Prevent out-of-bounds BAT accesses with malicious vhdx files (2026-11-09 16:32:35 +0100)
>
> ----------------------------------------------------------------
> Block layer patches
>
> - qcow2: fix snapshot data corruption with discard-no-unref=on
> - vmdk: Fix various bugs in handling malicious image files
> - vhdx: Prevent out-of-bounds BAT accesses with malicious vhdx files
> - iotests: add --quiet arg to hide env variable dump
Applied, thanks.
r~
^ permalink raw reply [flat|nested] 13+ messages in thread
end of thread, other threads:[~2026-11-10 15:32 UTC | newest]
Thread overview: 13+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-11-09 16:45 [PULL 00/11] Block layer patches Kevin Wolf
2026-11-09 16:45 ` [PULL 01/11] iotests: add --quiet arg to hide env variable dump Kevin Wolf
2026-11-09 16:45 ` [PULL 02/11] block/vmdk: Avoid assertion if image file has no extents Kevin Wolf
2026-11-09 16:45 ` [PULL 03/11] block/vmdk: Avoid reading off the end of descriptor memory Kevin Wolf
2026-11-09 16:45 ` [PULL 04/11] block/vmdk: Use larger types for byte counts in vmdk_read_extent() Kevin Wolf
2026-11-09 16:45 ` [PULL 05/11] block/vmdk: Reject a zero cluster_sectors parameter Kevin Wolf
2026-11-09 16:45 ` [PULL 06/11] block/vmdk: Avoid overflowing multiplication in vmdk_open_vmdk4() Kevin Wolf
2026-11-09 16:45 ` [PULL 07/11] block: add missing coroutine_fn annotations Kevin Wolf
2026-11-09 16:45 ` [PULL 08/11] iotests/290: add test case to check 'discard-no-unref' option behavior Kevin Wolf
2026-11-09 16:45 ` [PULL 09/11] qcow2: fix snapshot data corruption with discard-no-unref=on Kevin Wolf
2026-11-09 16:45 ` [PULL 10/11] iotests/290: add 'discard' and 'write -z -u' case with a snapshot Kevin Wolf
2026-11-09 16:45 ` [PULL 11/11] block/vhdx: Prevent out-of-bounds BAT accesses with malicious vhdx files Kevin Wolf
2026-11-09 20:53 ` [PULL 00/11] Block layer patches Richard Henderson
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.