qemu/block
Fiona Ebner 4f617140a4 block/reqlist: allow adding overlapping requests
Allow overlapping request by removing the assert that made it
impossible. There are only two callers:

1. block_copy_task_create()

It already asserts the very same condition before calling
reqlist_init_req().

2. cbw_snapshot_read_lock()

There is no need to have read requests be non-overlapping in
copy-before-write when used for snapshot-access. In fact, there was no
protection against two callers of cbw_snapshot_read_lock() calling
reqlist_init_req() with overlapping ranges and this could lead to an
assertion failure [1].

In particular, with the reproducer script below [0], two
cbw_co_snapshot_block_status() callers could race, with the second
calling reqlist_init_req() before the first one finishes and removes
its conflicting request.

[0]:

> #!/bin/bash -e
> dd if=/dev/urandom of=/tmp/disk.raw bs=1M count=1024
> ./qemu-img create /tmp/fleecing.raw -f raw 1G
> (
> ./qemu-system-x86_64 --qmp stdio \
> --blockdev raw,node-name=node0,file.driver=file,file.filename=/tmp/disk.raw \
> --blockdev raw,node-name=node1,file.driver=file,file.filename=/tmp/fleecing.raw \
> <<EOF
> {"execute": "qmp_capabilities"}
> {"execute": "blockdev-add", "arguments": { "driver": "copy-before-write", "file": "node0", "target": "node1", "node-name": "node3" } }
> {"execute": "blockdev-add", "arguments": { "driver": "snapshot-access", "file": "node3", "node-name": "snap0" } }
> {"execute": "nbd-server-start", "arguments": {"addr": { "type": "unix", "data": { "path": "/tmp/nbd.socket" } } } }
> {"execute": "block-export-add", "arguments": {"id": "exp0", "node-name": "snap0", "type": "nbd", "name": "exp0"}}
> EOF
> ) &
> sleep 5
> while true; do
> ./qemu-nbd -d /dev/nbd0
> ./qemu-nbd -c /dev/nbd0 nbd:unix:/tmp/nbd.socket:exportname=exp0 -f raw -r
> nbdinfo --map 'nbd+unix:///exp0?socket=/tmp/nbd.socket'
> done

[1]:

> #5  0x000071e5f0088eb2 in __GI___assert_fail (...) at ./assert/assert.c:101
> #6  0x0000615285438017 in reqlist_init_req (...) at ../block/reqlist.c:23
> #7  0x00006152853e2d98 in cbw_snapshot_read_lock (...) at ../block/copy-before-write.c:237
> #8  0x00006152853e3068 in cbw_co_snapshot_block_status (...) at ../block/copy-before-write.c:304
> #9  0x00006152853f4d22 in bdrv_co_snapshot_block_status (...) at ../block/io.c:3726
> #10 0x000061528543a63e in snapshot_access_co_block_status (...) at ../block/snapshot-access.c:48
> #11 0x00006152853f1a0a in bdrv_co_do_block_status (...) at ../block/io.c:2474
> #12 0x00006152853f2016 in bdrv_co_common_block_status_above (...) at ../block/io.c:2652
> #13 0x00006152853f22cf in bdrv_co_block_status_above (...) at ../block/io.c:2732
> #14 0x00006152853d9a86 in blk_co_block_status_above (...) at ../block/block-backend.c:1473
> #15 0x000061528538da6c in blockstatus_to_extents (...) at ../nbd/server.c:2374
> #16 0x000061528538deb1 in nbd_co_send_block_status (...) at ../nbd/server.c:2481
> #17 0x000061528538f424 in nbd_handle_request (...) at ../nbd/server.c:2978
> #18 0x000061528538f906 in nbd_trip (...) at ../nbd/server.c:3121
> #19 0x00006152855a7caf in coroutine_trampoline (...) at ../util/coroutine-ucontext.c:175

Cc: qemu-stable@nongnu.org
Suggested-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
Message-Id: <20240712140716.517911-1-f.ebner@proxmox.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@yandex-team.ru>
(cherry picked from commit 6475155d51)
Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
2024-10-01 19:22:07 +03:00
..
export block: remove bdrv_try_set_aio_context and replace it with bdrv_try_change_aio_context 2022-10-27 20:14:11 +02:00
monitor nbd/server: CVE-2024-7409: Cap default max-connections to 100 2024-08-11 11:00:05 +03:00
accounting.c block: add missed block_acct_setup with new block device init procedure 2022-09-30 18:42:34 +02:00
aio_task.c block/aio_task: assert max_busy_tasks is greater than 0 2021-10-05 18:56:41 +02:00
amend.c block/amend: Keep strong reference to BDS 2022-03-04 18:18:26 +01:00
backup.c backup: remove incorrect coroutine_fn annotation 2022-10-27 20:14:11 +02:00
blkdebug.c blkdebug: add missing coroutine_fn annotation for indirect-called functions 2022-10-27 20:14:11 +02:00
blkio.c block/blkio: use FUA flag on write zeroes only if supported 2024-09-12 09:20:33 +03:00
blklogwrites.c block/blklogwrites: Fix a bug when logging "write zeroes" operations. 2024-01-26 18:36:00 +03:00
blkreplay.c block: introduce bdrv_open_file_child() helper 2022-10-27 20:14:11 +02:00
blkverify.c Block layer patches 2022-10-30 15:15:12 -04:00
block-backend.c block-backend: avoid bdrv_unregister_buf() NULL pointer deref 2022-11-29 18:15:26 -05:00
block-copy.c block/block-copy: block_copy(): add timeout_ns parameter 2022-06-29 10:56:12 +03:00
block-gen.h scripts: add block-coroutine-wrapper.py 2020-10-05 10:59:06 +01:00
block-ram-registrar.c block: add BlockRAMRegistrar 2022-10-26 14:56:42 -04:00
bochs.c block: introduce bdrv_open_file_child() helper 2022-10-27 20:14:11 +02:00
cloop.c block: introduce bdrv_open_file_child() helper 2022-10-27 20:14:11 +02:00
commit.c commit: switch to *_co_* functions 2022-10-27 20:14:11 +02:00
copy-before-write.c block/reqlist: allow adding overlapping requests 2024-10-01 19:22:07 +03:00
copy-before-write.h block/copy-before-write.h: global state API + assertions 2022-03-04 18:18:25 +01:00
copy-on-read.c block: introduce bdrv_open_file_child() helper 2022-10-27 20:14:11 +02:00
copy-on-read.h Clean up ill-advised or unusual header guards 2022-05-11 16:50:01 +02:00
coroutines.h block: Remove remaining unused symbols in coroutines.h 2022-07-12 12:14:56 +02:00
create.c block_int-common.h: assertions in the callers of BlockDriver function pointers 2022-03-04 18:18:25 +01:00
crypto.c Block layer patches 2022-10-30 15:15:12 -04:00
crypto.h nomaintainer: Fix Lesser GPL version number 2020-11-15 17:04:40 +01:00
curl.c block: Handle curl 7.55.0, 7.85.0 version changes 2023-03-29 10:20:05 +03:00
dirty-bitmap.c block: simplify handling of try to merge different sized bitmaps 2022-06-24 17:07:06 +02:00
dmg-bz2.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
dmg-lzfse.c block: Remove unused include 2020-11-09 15:44:21 +01:00
dmg.c dmg: warn when opening dmg images containing blocks of unknown type 2022-11-06 09:48:50 +01:00
dmg.h Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
file-posix.c block: add BDRV_REQ_REGISTERED_BUF request flag 2022-10-26 14:56:42 -04:00
file-win32.c block: use int64_t instead of uint64_t in driver write handlers 2021-09-29 13:46:31 -05:00
filter-compress.c block: introduce bdrv_open_file_child() helper 2022-10-27 20:14:11 +02:00
gluster.c block: add BDRV_REQ_REGISTERED_BUF request flag 2022-10-26 14:56:42 -04:00
io_uring.c block/io_uring: revert "Use io_uring_register_ring_fd() to skip fd operations" 2022-10-27 20:14:11 +02:00
io.c block/io: clear BDRV_BLOCK_RECURSE flag after recursing in bdrv_co_block_status 2024-01-25 19:14:18 +03:00
iscsi-opts.c modules: add block module annotations 2021-07-09 18:20:27 +02:00
iscsi.c block/iscsi: fix double-free on BUSY or similar statuses 2023-03-29 10:20:04 +03:00
linux-aio.c misc: fix commonly doubled up words 2022-08-01 11:58:02 +02:00
meson.build block: add BlockRAMRegistrar 2022-10-26 14:56:42 -04:00
mirror.c block/mirror: Fix NULL s->job in active writes 2022-11-10 13:33:55 +01:00
nbd.c block: add BDRV_REQ_REGISTERED_BUF request flag 2022-10-26 14:56:42 -04:00
nfs.c block/nfs: Fix 32-bit Windows build 2022-10-27 20:14:11 +02:00
null.c block: use int64_t instead of uint64_t in driver write handlers 2021-09-29 13:46:31 -05:00
nvme.c block/nvme: nvme_process_completion() fix bound for cid 2023-11-07 19:22:08 +03:00
parallels-ext.c block: Change bdrv_{pread,pwrite,pwrite_sync}() param order 2022-07-12 12:14:55 +02:00
parallels.c Block layer patches 2022-10-30 15:15:12 -04:00
parallels.h parallels: support bitmap extension for read-only mode 2021-03-08 14:56:55 +01:00
preallocate.c block: introduce bdrv_open_file_child() helper 2022-10-27 20:14:11 +02:00
progress_meter.c progressmeter: protect with a mutex 2021-06-25 14:24:24 +03:00
qapi-sysemu.c block: add 'force' parameter to 'blockdev-change-medium' command 2022-04-25 12:02:36 +02:00
qapi.c block: use GDateTime for formatting timestamp when dumping snapshot info 2021-06-14 13:28:50 +01:00
qcow2-bitmap.c qcow2: Fix theoretical corruption in store_bitmap() error path 2023-03-29 10:20:04 +03:00
qcow2-cache.c block: Change bdrv_{pread,pwrite,pwrite_sync}() param order 2022-07-12 12:14:55 +02:00
qcow2-cluster.c qcow2: switch to *_co_* functions 2022-10-27 20:14:11 +02:00
qcow2-refcount.c qcow2: switch to *_co_* functions 2022-10-27 20:14:11 +02:00
qcow2-snapshot.c qcow2: switch to *_co_* functions 2022-10-27 20:14:11 +02:00
qcow2-threads.c qcow2: add zstd cluster compression 2020-05-13 14:20:31 +02:00
qcow2.c qcow2: Don't open data_file with BDRV_O_NO_IO 2024-07-03 23:51:20 +03:00
qcow2.h qcow2: manually add more coroutine_fn annotations 2022-10-27 20:14:11 +02:00
qcow.c Block layer patches 2022-10-30 15:15:12 -04:00
qed-check.c block/qed: add missed coroutine_fn markers 2019-04-30 15:29:00 +02:00
qed-cluster.c qed: protect table cache with CoMutex 2017-07-17 11:34:11 +08:00
qed-l2-cache.c osdep: Move memalign-related functions to their own header 2022-03-07 13:16:49 +00:00
qed-table.c qed: switch to *_co_* functions 2022-10-27 20:14:11 +02:00
qed.c Block layer patches 2022-10-30 15:15:12 -04:00
qed.h qed: Simplify backing reads 2020-07-06 10:34:14 +02:00
quorum.c quorum: Remove unnecessary forward declaration 2022-10-07 12:11:41 +02:00
raw-format.c Block layer patches 2022-10-30 15:15:12 -04:00
rbd.c block/rbd: report a better error when namespace does not exist 2022-06-24 17:07:06 +02:00
replication.c Block layer patches 2022-10-30 15:15:12 -04:00
reqlist.c block/reqlist: allow adding overlapping requests 2024-10-01 19:22:07 +03:00
snapshot-access.c block: Manipulate bs->file / bs->backing pointers in .attach/.detach 2022-10-27 20:14:11 +02:00
snapshot.c block: Fix crash when loading snapshot on inactive node 2023-12-22 22:25:35 +03:00
ssh.c Block layer patches 2022-10-30 15:15:12 -04:00
stream.c block/stream: Drain subtree around graph change 2022-03-29 16:30:55 +02:00
throttle-groups.c block/throttle-groups: throttle_group_co_io_limits_intercept(): 64bit bytes 2021-02-03 08:14:00 -06:00
throttle.c block: introduce bdrv_open_file_child() helper 2022-10-27 20:14:11 +02:00
trace-events nbd: trace long NBD operations 2022-06-29 10:57:02 +03:00
trace.h trace: switch position of headers to what Meson requires 2020-08-21 06:18:24 -04:00
vdi.c vdi: switch to *_co_* functions 2022-10-27 20:14:11 +02:00
vhdx-endian.c Include qemu-common.h exactly where needed 2019-06-12 13:20:20 +02:00
vhdx-log.c block/vhdx: fix dynamic VHDX BAT corruption 2023-04-13 18:31:39 +03:00
vhdx.c Block layer patches 2022-10-30 15:15:12 -04:00
vhdx.h block/vhdx: Use IEC binary prefixes for size constants 2019-04-30 15:29:00 +02:00
vmdk.c vmdk: Don't corrupt desc file in vmdk_write_cid 2023-12-20 19:11:10 +03:00
vpc.c block: introduce bdrv_open_file_child() helper 2022-10-27 20:14:11 +02:00
vvfat.c vvfat: Fix reading files with non-continuous clusters 2024-08-11 10:51:51 +03:00
win32-aio.c osdep: Move memalign-related functions to their own header 2022-03-07 13:16:49 +00:00
write-threshold.c write-threshold: deal with includes 2021-05-14 16:14:10 +02:00