mirror of
https://github.com/qemu/qemu.git
synced 2025-08-14 20:31:47 +00:00
mirror: Do not dereference invalid pointers
mirror_exit_common() may be called twice (if it is called from
mirror_prepare() and fails, it will be called from mirror_abort()
again).
In such a case, many of the pointers in the MirrorBlockJob object will
already be freed. This can be seen most reliably for s->target, which
is set to NULL (and then dereferenced by blk_bs()).
Cc: qemu-stable@nongnu.org
Fixes: 737efc1eda
Signed-off-by: Max Reitz <mreitz@redhat.com>
Reviewed-by: John Snow <jsnow@redhat.com>
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Message-id: 20191014153931.20699-2-mreitz@redhat.com
Signed-off-by: Max Reitz <mreitz@redhat.com>
This commit is contained in:
parent
e87a09d625
commit
f93c3add3a
@ -620,11 +620,11 @@ static int mirror_exit_common(Job *job)
|
|||||||
{
|
{
|
||||||
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);
|
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common.job);
|
||||||
BlockJob *bjob = &s->common;
|
BlockJob *bjob = &s->common;
|
||||||
MirrorBDSOpaque *bs_opaque = s->mirror_top_bs->opaque;
|
MirrorBDSOpaque *bs_opaque;
|
||||||
AioContext *replace_aio_context = NULL;
|
AioContext *replace_aio_context = NULL;
|
||||||
BlockDriverState *src = s->mirror_top_bs->backing->bs;
|
BlockDriverState *src;
|
||||||
BlockDriverState *target_bs = blk_bs(s->target);
|
BlockDriverState *target_bs;
|
||||||
BlockDriverState *mirror_top_bs = s->mirror_top_bs;
|
BlockDriverState *mirror_top_bs;
|
||||||
Error *local_err = NULL;
|
Error *local_err = NULL;
|
||||||
bool abort = job->ret < 0;
|
bool abort = job->ret < 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
@ -634,6 +634,11 @@ static int mirror_exit_common(Job *job)
|
|||||||
}
|
}
|
||||||
s->prepared = true;
|
s->prepared = true;
|
||||||
|
|
||||||
|
mirror_top_bs = s->mirror_top_bs;
|
||||||
|
bs_opaque = mirror_top_bs->opaque;
|
||||||
|
src = mirror_top_bs->backing->bs;
|
||||||
|
target_bs = blk_bs(s->target);
|
||||||
|
|
||||||
if (bdrv_chain_contains(src, target_bs)) {
|
if (bdrv_chain_contains(src, target_bs)) {
|
||||||
bdrv_unfreeze_backing_chain(mirror_top_bs, target_bs);
|
bdrv_unfreeze_backing_chain(mirror_top_bs, target_bs);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user