@samitouri / QOSamiQemu / commits / 9b899ddb27

hw/ide/core: Fix possible crash via NULL pointer in ide_cancel_dma_sync()

ide_cancel_dma_sync() is called with a "IDEState *s" for one of the two IDE drives on a bus (primary or secondary drive) to cancel all pending DMA transfers on the drive. The code then checks s->bus->dma->aiocb to see whether there is any IO in flight on the *bus* and then calls blk_drain(s->blk) to wait for its completion. However, s->bus->dma->aiocb might belong to the other drive on the bus, and if there is no disk attached to the current drive, s->blk is NULL. Since blk_drain() does not check its parameter for a NULL pointer, QEMU can crash in such a case. To fix the problem, we have to check that "blk" is not NULL before calling blk_drain(). And we have to call blk_drain() for both drives, otherwise the assert(s->bus->dma->aiocb == NULL) statement after the blk_drain() might trigger if the IO in flight belongs to the the other drive. Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/905 Reported-by: Alexander Bulekov <alxndr@bu.edu> Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4052 Reported-by: dong ling Signed-off-by: Thomas Huth <thuth@redhat.com> Message-ID: <20260721070216.82984-1-thuth@redhat.com>

Thomas Huth committed Jul 21, 2026 at 09:02 UTC 9b899ddb2706150ee1e5d0150a11bb021377ecb8
1 file changed +8 -1
hw/ide/core.c
+8 -1
@@ -741,10 +741,17 @@ void ide_cancel_dma_sync(IDEState *s)
741 * In the future we'll be able to safely cancel the I/O if the
742 * whole DMA operation will be submitted to disk with a single
743 * aio operation with preadv/pwritev.
744 + *
745 + * Note: s->bus->dma->aiocb might belong to the adjacent IDEState,
746 + * so we have to drain both drives to get it cleared.
747 */
748 if (s->bus->dma->aiocb) {
749 trace_ide_cancel_dma_sync_remaining();
747 - blk_drain(s->blk);
750 + for (int i = 0; i < 2; i++) {
751 + if (s->bus->ifs[i].blk) {
752 + blk_drain(s->bus->ifs[i].blk);
753 + }
754 + }
755 assert(s->bus->dma->aiocb == NULL);
756 }
757 }