Kevin Wolf <[email protected]> writes:

> During shutdown, blockdev_close_all_bdrv_states() drops any block node
> references that are still owned by the monitor (i.e. the user). However,
> in doing so, it forgot to also remove the node from monitor_bdrv_states
> (which qmp_blockdev_del() correctly does), which means that later calls
> of bdrv_first()/bdrv_next() will still return the (now stale) pointer to
> the node.
>
> Usually there is no such call after this point, but in some cases it can
> happen. In the reported case, there was an ongoing migration, and the
> migration thread wasn't shut down yet: migration_shutdown() called by
> qemu_cleanup() doesn't actually wait for the migration to be shut down,
> but may just move it to MIGRATION_STATUS_CANCELLING. The next time
> migration_iteration_finish() runs, it sees the status and tries to
> re-activate all block devices that migration may have previously
> inactivated. This is where bdrv_first()/bdrv_next() get called and the
> access to the already freed node happens.
>
> It is debatable if migration_shutdown() should really return before
> migration has settled, but leaving a dangling pointer in the list of
> monitor-owned block nodes is clearly a bug either way and fixing it
> solves the immediate problem, so fix it.
>
> Cc: [email protected]
> Reported-by: Thomas Huth <[email protected]>
> Signed-off-by: Kevin Wolf <[email protected]>

Reviewed-by: Fabiano Rosas <[email protected]>

Reply via email to