qemu with hax to log dma reads & writes jcs.org/2018/11/12/vfio

block/vvfat: Do not unref qcow on closing backing bdrv

Before this commit, BDRVVVFATState.qcow is unrefed in write_target_close
on closing backing bdrv of vvfat. However, qcow bdrv is opend as a child
of vvfat in enable_write_target() so it will be also unrefed on closing
vvfat itself. This causes use-after-free of qcow on freeing vvfat which
has backing bdrv and qcow bdrv as children in this order because
bdrv_close(vvfat) tries to free qcow bdrv after freeing backing bdrv
as QLIST_FOREACH_SAFE() loop keeps next pointer, but BdrvChild of qcow
is already freed in bdrv_close(backing bdrv).

Signed-off-by: Hikaru Nishida <hikarupsp@gmail.com>
Message-Id: <20200209175156.85748-1-hikarupsp@gmail.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>

authored by

Hikaru Nishida and committed by
Kevin Wolf
8475ea48 2d4b5256

-7
-7
block/vvfat.c
··· 3124 3124 return ret; 3125 3125 } 3126 3126 3127 - static void write_target_close(BlockDriverState *bs) { 3128 - BDRVVVFATState* s = *((BDRVVVFATState**) bs->opaque); 3129 - bdrv_unref_child(s->bs, s->qcow); 3130 - g_free(s->qcow_filename); 3131 - } 3132 - 3133 3127 static BlockDriver vvfat_write_target = { 3134 3128 .format_name = "vvfat_write_target", 3135 3129 .instance_size = sizeof(void*), 3136 3130 .bdrv_co_pwritev = write_target_commit, 3137 - .bdrv_close = write_target_close, 3138 3131 }; 3139 3132 3140 3133 static void vvfat_qcow_options(int *child_flags, QDict *child_options,