From: Stefan Hajnoczi <stefanha@redhat.com>
To: Kevin Wolf <kwolf@redhat.com>
Cc: Deepa Srinivasan <deepa.srinivasan@oracle.com>,
mreitz@redhat.com, pbonzini@redhat.com, qemu-block@nongnu.org,
qemu-devel@nongnu.org, mark.kanda@oracle.com,
Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Subject: Re: [Qemu-devel] [PATCH] block: Fix qemu crash when using scsi-block
Date: Thu, 23 Nov 2017 10:23:25 +0000 [thread overview]
Message-ID: <20171123102325.GA26022@stefanha-x1.localdomain> (raw)
In-Reply-To: <20171122180426.GC10954@localhost.localdomain>
[-- Attachment #1: Type: text/plain, Size: 3422 bytes --]
On Wed, Nov 22, 2017 at 07:04:26PM +0100, Kevin Wolf wrote:
> Am 22.11.2017 um 18:06 hat Stefan Hajnoczi geschrieben:
> > On Wed, Nov 22, 2017 at 07:33:28AM -0800, Deepa Srinivasan wrote:
> > > 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 allocate memory for the QEMUIOVector and struct iovec as part of
> > > the request struct which the IO buffer is part of. The memory for this struct is
> > > guaranteed to be valid till the AIO is completed.
> >
> > Thanks for the patch!
> >
> > AIO APIs currently don't require the caller to match qiov's lifetime to
> > the I/O request lifetime. This patch changes that for blk_aio_ioctl()
> > only. If we want to do this consistently then all aio callers need to
> > be audited and fixed.
> >
> > The alternative is to make the API copy qiov when necessary. That is
> > less efficient but avoids modifying all callers.
> >
> > Either way, the lifetime of qiov must be consistent across all aio APIs,
> > not just blk_aio_ioctl().
>
> Don't all blk_aio_*() APIs that take a qiov pointer require that it
> remains valid until the request completes? I don't think they are copied
> anywhere for blk_aio_preadv/pwritev() before being passed to the block
> driver.
>
> So this does look consistent with the existing functions to me.
You are right. I audited the blk_aio_preadv() callers and they all keep
qiov around until the request is complete.
Actually this makes sense because even in the simple non-coroutine case
with aio=threads the qiov hasn't necessarily been read yet when the
function returns. The aio_worker() function executes later and only
then is qiov handed to the host kernel.
So this is a one-off bug in blk_aio_ioctl() callers.
Stefan
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 455 bytes --]
next prev parent reply other threads:[~2017-11-23 10:23 UTC|newest]
Thread overview: 18+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-11-22 15:33 [Qemu-devel] [PATCH] block: Fix qemu crash when using scsi-block Deepa Srinivasan
2017-11-22 16:34 ` Paolo Bonzini
2017-11-22 18:06 ` Kevin Wolf
2017-11-22 19:24 ` [Qemu-devel] [Qemu-block] " Paolo Bonzini
2017-11-23 2:55 ` Deepa Srinivasan
2017-11-23 9:18 ` Paolo Bonzini
2017-11-23 16:55 ` [Qemu-devel] " Deepa Srinivasan
2017-11-23 17:05 ` Deepa Srinivasan
2017-11-23 17:17 ` Paolo Bonzini
2017-11-23 17:29 ` Kevin Wolf
2017-11-23 17:31 ` Paolo Bonzini
2017-11-23 17:34 ` Kevin Wolf
2017-11-27 18:45 ` Deepa Srinivasan
2017-12-01 17:27 ` Deepa Srinivasan
2017-11-22 17:06 ` Stefan Hajnoczi
2017-11-22 18:04 ` Kevin Wolf
2017-11-23 10:23 ` Stefan Hajnoczi [this message]
2017-11-23 10:42 ` Paolo Bonzini
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20171123102325.GA26022@stefanha-x1.localdomain \
--to=stefanha@redhat.com \
--cc=deepa.srinivasan@oracle.com \
--cc=konrad.wilk@oracle.com \
--cc=kwolf@redhat.com \
--cc=mark.kanda@oracle.com \
--cc=mreitz@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).