ddde5ee769
When an NBD block driver state is moved from one aio_context to another (e.g. when doing a drain in a migration thread), nbd_client_attach_aio_context_bh is executed that enters the connection coroutine. However, the assumption that ->connection_co is always present here appears incorrect: the connection may have encountered an error other than -EIO in the underlying transport, and thus may have decided to quit rather than keep trying to reconnect, and therefore it may have terminated the connection coroutine. As a result an attempt to reassign the client in this state (NBD_CLIENT_QUIT) to a different aio_context leads to a null pointer dereference: #0 qio_channel_detach_aio_context (ioc=0x0) at /build/qemu-gYtjVn/qemu-5.0.1/io/channel.c:452 #1 0x0000562a242824b3 in bdrv_detach_aio_context (bs=0x562a268d6a00) at /build/qemu-gYtjVn/qemu-5.0.1/block.c:6151 #2 bdrv_set_aio_context_ignore (bs=bs@entry=0x562a268d6a00, new_context=new_context@entry=0x562a260c9580, ignore=ignore@entry=0x7feeadc9b780) at /build/qemu-gYtjVn/qemu-5.0.1/block.c:6230 #3 0x0000562a24282969 in bdrv_child_try_set_aio_context (bs=bs@entry=0x562a268d6a00, ctx=0x562a260c9580, ignore_child=<optimized out>, errp=<optimized out>) at /build/qemu-gYtjVn/qemu-5.0.1/block.c:6332 #4 0x0000562a242bb7db in blk_do_set_aio_context (blk=0x562a2735d0d0, new_context=0x562a260c9580, update_root_node=update_root_node@entry=true, errp=errp@entry=0x0) at /build/qemu-gYtjVn/qemu-5.0.1/block/block-backend.c:1989 #5 0x0000562a242be0bd in blk_set_aio_context (blk=<optimized out>, new_context=<optimized out>, errp=errp@entry=0x0) at /build/qemu-gYtjVn/qemu-5.0.1/block/block-backend.c:2010 #6 0x0000562a23fbd953 in virtio_blk_data_plane_stop (vdev=<optimized out>) at /build/qemu-gYtjVn/qemu-5.0.1/hw/block/dataplane/virtio-blk.c:292 #7 0x0000562a241fc7bf in virtio_bus_stop_ioeventfd (bus=0x562a260dbf08) at /build/qemu-gYtjVn/qemu-5.0.1/hw/virtio/virtio-bus.c:245 #8 0x0000562a23fefb2e in virtio_vmstate_change (opaque=0x562a260dbf90, running=0, state=<optimized out>) at /build/qemu-gYtjVn/qemu-5.0.1/hw/virtio/virtio.c:3220 #9 0x0000562a2402ebfd in vm_state_notify (running=running@entry=0, state=state@entry=RUN_STATE_FINISH_MIGRATE) at /build/qemu-gYtjVn/qemu-5.0.1/softmmu/vl.c:1275 #10 0x0000562a23f7bc02 in do_vm_stop (state=RUN_STATE_FINISH_MIGRATE, send_stop=<optimized out>) at /build/qemu-gYtjVn/qemu-5.0.1/cpus.c:1032 #11 0x0000562a24209765 in migration_completion (s=0x562a260e83a0) at /build/qemu-gYtjVn/qemu-5.0.1/migration/migration.c:2914 #12 migration_iteration_run (s=0x562a260e83a0) at /build/qemu-gYtjVn/qemu-5.0.1/migration/migration.c:3275 #13 migration_thread (opaque=opaque@entry=0x562a260e83a0) at /build/qemu-gYtjVn/qemu-5.0.1/migration/migration.c:3439 #14 0x0000562a2435ca96 in qemu_thread_start (args=<optimized out>) at /build/qemu-gYtjVn/qemu-5.0.1/util/qemu-thread-posix.c:519 #15 0x00007feed31466ba in start_thread (arg=0x7feeadc9c700) at pthread_create.c:333 #16 0x00007feed2e7c41d in __GI___sysctl (name=0x0, nlen=608471908, oldval=0x562a2452b138, oldlenp=0x0, newval=0x562a2452c5e0 <__func__.28102>, newlen=0) at ../sysdeps/unix/sysv/linux/sysctl.c:30 #17 0x0000000000000000 in ?? () Fix it by checking that the connection coroutine is non-null before trying to enter it. If it is null, no entering is needed, as the connection is probably going down anyway. Signed-off-by: Roman Kagan <rvkagan@yandex-team.ru> Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> Message-Id: <20210129073859.683063-3-rvkagan@yandex-team.ru> Signed-off-by: Eric Blake <eblake@redhat.com> |
||
---|---|---|
.. | ||
export | ||
monitor | ||
accounting.c | ||
aio_task.c | ||
amend.c | ||
backup-top.c | ||
backup-top.h | ||
backup.c | ||
blkdebug.c | ||
blklogwrites.c | ||
blkreplay.c | ||
blkverify.c | ||
block-backend.c | ||
block-copy.c | ||
block-gen.h | ||
bochs.c | ||
cloop.c | ||
commit.c | ||
copy-on-read.c | ||
copy-on-read.h | ||
coroutines.h | ||
create.c | ||
crypto.c | ||
crypto.h | ||
curl.c | ||
dirty-bitmap.c | ||
dmg-bz2.c | ||
dmg-lzfse.c | ||
dmg.c | ||
dmg.h | ||
file-posix.c | ||
file-win32.c | ||
filter-compress.c | ||
gluster.c | ||
io_uring.c | ||
io.c | ||
iscsi-opts.c | ||
iscsi.c | ||
linux-aio.c | ||
meson.build | ||
mirror.c | ||
nbd.c | ||
nfs.c | ||
null.c | ||
nvme.c | ||
parallels.c | ||
parallels.h | ||
preallocate.c | ||
qapi-sysemu.c | ||
qapi.c | ||
qcow2-bitmap.c | ||
qcow2-cache.c | ||
qcow2-cluster.c | ||
qcow2-refcount.c | ||
qcow2-snapshot.c | ||
qcow2-threads.c | ||
qcow2.c | ||
qcow2.h | ||
qcow.c | ||
qed-check.c | ||
qed-cluster.c | ||
qed-l2-cache.c | ||
qed-table.c | ||
qed.c | ||
qed.h | ||
quorum.c | ||
raw-format.c | ||
rbd.c | ||
replication.c | ||
sheepdog.c | ||
snapshot.c | ||
ssh.c | ||
stream.c | ||
throttle-groups.c | ||
throttle.c | ||
trace-events | ||
trace.h | ||
vdi.c | ||
vhdx-endian.c | ||
vhdx-log.c | ||
vhdx.c | ||
vhdx.h | ||
vmdk.c | ||
vpc.c | ||
vvfat.c | ||
win32-aio.c | ||
write-threshold.c |