Skip to content
  • Deepa Srinivasan's avatar
    c060332c
    block: Fix qemu crash when using scsi-block · c060332c
    Deepa Srinivasan authored
    
    
    Starting qemu with the following arguments causes qemu to segfault:
    ... -device lsi,id=lsi0 -drive file=iscsi:<...>,format=raw,if=none,node-name=
    iscsi1 -device scsi-block,bus=lsi0.0,id=<...>,drive=iscsi1
    
    This patch fixes blk_aio_ioctl() so it does not pass stack addresses to
    blk_aio_ioctl_entry() which may be invoked after blk_aio_ioctl() returns. More
    details about the bug follow.
    
    blk_aio_ioctl() invokes blk_aio_prwv() with blk_aio_ioctl_entry as the
    coroutine parameter. blk_aio_prwv() ultimately calls aio_co_enter().
    
    When blk_aio_ioctl() is executed from within a coroutine context (e.g.
    iscsi_bh_cb()), aio_co_enter() adds the coroutine (blk_aio_ioctl_entry) to
    the current coroutine's wakeup queue. blk_aio_ioctl() then returns.
    
    When blk_aio_ioctl_entry() executes later, it accesses an invalid pointer:
    ....
        BlkRwCo *rwco = &acb->rwco;
    
        rwco->ret = blk_co_ioctl(rwco->blk, rwco->offset,
                                 rwco->qiov->iov[0].iov_base);  <--- qiov is
                                                                     invalid here
    ...
    
    In the case when blk_aio_ioctl() is called from a non-coroutine context,
    blk_aio_ioctl_entry() executes immediately. But if bdrv_co_ioctl() calls
    qemu_coroutine_yield(), blk_aio_ioctl() will return. When the coroutine
    execution is complete, control returns to blk_aio_ioctl_entry() after the call
    to blk_co_ioctl(). There is no invalid reference after this point, but the
    function is still holding on to invalid pointers.
    
    The fix is to change blk_aio_prwv() to accept a void pointer for the IO buffer
    rather than a QEMUIOVector. blk_aio_prwv() passes this through in BlkRwCo and the
    coroutine function casts it to QEMUIOVector or uses the void pointer directly.
    
    Signed-off-by: default avatarDeepa Srinivasan <deepa.srinivasan@oracle.com>
    Signed-off-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
    Reviewed-by: default avatarMark Kanda <mark.kanda@oracle.com>
    Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
    c060332c
    block: Fix qemu crash when using scsi-block
    Deepa Srinivasan authored
    
    
    Starting qemu with the following arguments causes qemu to segfault:
    ... -device lsi,id=lsi0 -drive file=iscsi:<...>,format=raw,if=none,node-name=
    iscsi1 -device scsi-block,bus=lsi0.0,id=<...>,drive=iscsi1
    
    This patch fixes blk_aio_ioctl() so it does not pass stack addresses to
    blk_aio_ioctl_entry() which may be invoked after blk_aio_ioctl() returns. More
    details about the bug follow.
    
    blk_aio_ioctl() invokes blk_aio_prwv() with blk_aio_ioctl_entry as the
    coroutine parameter. blk_aio_prwv() ultimately calls aio_co_enter().
    
    When blk_aio_ioctl() is executed from within a coroutine context (e.g.
    iscsi_bh_cb()), aio_co_enter() adds the coroutine (blk_aio_ioctl_entry) to
    the current coroutine's wakeup queue. blk_aio_ioctl() then returns.
    
    When blk_aio_ioctl_entry() executes later, it accesses an invalid pointer:
    ....
        BlkRwCo *rwco = &acb->rwco;
    
        rwco->ret = blk_co_ioctl(rwco->blk, rwco->offset,
                                 rwco->qiov->iov[0].iov_base);  <--- qiov is
                                                                     invalid here
    ...
    
    In the case when blk_aio_ioctl() is called from a non-coroutine context,
    blk_aio_ioctl_entry() executes immediately. But if bdrv_co_ioctl() calls
    qemu_coroutine_yield(), blk_aio_ioctl() will return. When the coroutine
    execution is complete, control returns to blk_aio_ioctl_entry() after the call
    to blk_co_ioctl(). There is no invalid reference after this point, but the
    function is still holding on to invalid pointers.
    
    The fix is to change blk_aio_prwv() to accept a void pointer for the IO buffer
    rather than a QEMUIOVector. blk_aio_prwv() passes this through in BlkRwCo and the
    coroutine function casts it to QEMUIOVector or uses the void pointer directly.
    
    Signed-off-by: default avatarDeepa Srinivasan <deepa.srinivasan@oracle.com>
    Signed-off-by: default avatarKonrad Rzeszutek Wilk <konrad.wilk@oracle.com>
    Reviewed-by: default avatarMark Kanda <mark.kanda@oracle.com>
    Reviewed-by: default avatarPaolo Bonzini <pbonzini@redhat.com>
    Signed-off-by: default avatarStefan Hajnoczi <stefanha@redhat.com>
Loading