[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[qemu-xen staging] block: fix bdrv_aio_cancel() for ENOMEDIUM requests



commit 1d719ddc35e9827b6e5df771555874df34301a0d
Author:     Stefan Hajnoczi <stefanha@xxxxxxxxxx>
AuthorDate: Mon Jul 20 11:01:41 2020 +0100
Commit:     Max Reitz <mreitz@xxxxxxxxxx>
CommitDate: Tue Jul 21 12:00:38 2020 +0200

    block: fix bdrv_aio_cancel() for ENOMEDIUM requests
    
    bdrv_aio_cancel() calls aio_poll() on the AioContext for the given I/O
    request until it has completed. ENOMEDIUM requests are special because
    there is no BlockDriverState when the drive has no medium!
    
    Define a .get_aio_context() function for BlkAioEmAIOCB requests so that
    bdrv_aio_cancel() can find the AioContext where the completion BH is
    pending. Without this function bdrv_aio_cancel() aborts on ENOMEDIUM
    requests!
    
    libFuzzer triggered the following assertion:
    
      cat << EOF | qemu-system-i386 -M pc-q35-5.0 \
        -nographic -monitor none -serial none \
        -qtest stdio -trace ide\*
      outl 0xcf8 0x8000fa24
      outl 0xcfc 0xe106c000
      outl 0xcf8 0x8000fa04
      outw 0xcfc 0x7
      outl 0xcf8 0x8000fb20
      write 0x0 0x3 0x2780e7
      write 0xe106c22c 0xd 0x1130c218021130c218021130c2
      write 0xe106c218 0x15 0x110010110010110010110010110010110010110010
      EOF
      ide_exec_cmd IDE exec cmd: bus 0x56170a77a2b8; state 0x56170a77a340; cmd 
0xe7
      ide_reset IDEstate 0x56170a77a340
      Aborted (core dumped)
    
      (gdb) bt
      #1  0x00007ffff4f93895 in abort () at /lib64/libc.so.6
      #2  0x0000555555dc6c00 in bdrv_aio_cancel (acb=0x555556765550) at 
block/io.c:2745
      #3  0x0000555555dac202 in blk_aio_cancel (acb=0x555556765550) at 
block/block-backend.c:1546
      #4  0x0000555555b1bd74 in ide_reset (s=0x555557213340) at 
hw/ide/core.c:1318
      #5  0x0000555555b1e3a1 in ide_bus_reset (bus=0x5555572132b8) at 
hw/ide/core.c:2422
      #6  0x0000555555b2aa27 in ahci_reset_port (s=0x55555720eb50, port=2) at 
hw/ide/ahci.c:650
      #7  0x0000555555b29fd7 in ahci_port_write (s=0x55555720eb50, port=2, 
offset=44, val=16) at hw/ide/ahci.c:360
      #8  0x0000555555b2a564 in ahci_mem_write (opaque=0x55555720eb50, 
addr=556, val=16, size=1) at hw/ide/ahci.c:513
      #9  0x000055555598415b in memory_region_write_accessor 
(mr=0x55555720eb80, addr=556, value=0x7fffffffb838, size=1, shift=0, mask=255, 
attrs=...) at softmmu/memory.c:483
    
    Looking at bdrv_aio_cancel:
    
    2728 /* async I/Os */
    2729
    2730 void bdrv_aio_cancel(BlockAIOCB *acb)
    2731 {
    2732     qemu_aio_ref(acb);
    2733     bdrv_aio_cancel_async(acb);
    2734     while (acb->refcnt > 1) {
    2735         if (acb->aiocb_info->get_aio_context) {
    2736             aio_poll(acb->aiocb_info->get_aio_context(acb), true);
    2737         } else if (acb->bs) {
    2738             /* qemu_aio_ref and qemu_aio_unref are not thread-safe, so
    2739              * assert that we're not using an I/O thread.  Thread-safe
    2740              * code should use bdrv_aio_cancel_async exclusively.
    2741              */
    2742             assert(bdrv_get_aio_context(acb->bs) == 
qemu_get_aio_context());
    2743             aio_poll(bdrv_get_aio_context(acb->bs), true);
    2744         } else {
    2745             abort();     <===============
    2746         }
    2747     }
    2748     qemu_aio_unref(acb);
    2749 }
    
    Fixes: 02c50efe08736116048d5fc355043080f4d5859c ("block: Add 
bdrv_aio_cancel_async")
    Reported-by: Alexander Bulekov <alxndr@xxxxxx>
    Buglink: https://bugs.launchpad.net/qemu/+bug/1878255
    Originally-by: Philippe Mathieu-Daudé <f4bug@xxxxxxxxx>
    Signed-off-by: Stefan Hajnoczi <stefanha@xxxxxxxxxx>
    Message-Id: <20200720100141.129739-1-stefanha@xxxxxxxxxx>
    Signed-off-by: Max Reitz <mreitz@xxxxxxxxxx>
---
 block/block-backend.c | 8 ++++++++
 1 file changed, 8 insertions(+)

diff --git a/block/block-backend.c b/block/block-backend.c
index 0bf0188133..3a13cb5f0b 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -1394,8 +1394,16 @@ typedef struct BlkAioEmAIOCB {
     bool has_returned;
 } BlkAioEmAIOCB;
 
+static AioContext *blk_aio_em_aiocb_get_aio_context(BlockAIOCB *acb_)
+{
+    BlkAioEmAIOCB *acb = container_of(acb_, BlkAioEmAIOCB, common);
+
+    return blk_get_aio_context(acb->rwco.blk);
+}
+
 static const AIOCBInfo blk_aio_em_aiocb_info = {
     .aiocb_size         = sizeof(BlkAioEmAIOCB),
+    .get_aio_context    = blk_aio_em_aiocb_get_aio_context,
 };
 
 static void blk_aio_complete(BlkAioEmAIOCB *acb)
--
generated by git-patchbot for /home/xen/git/qemu-xen.git#staging



 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.