All of lore.kernel.org
 help / color / mirror / Atom feed
From: Paolo Bonzini <pbonzini@redhat.com>
To: Ladi Prosek <lprosek@redhat.com>, qemu-devel@nongnu.org
Cc: den@openvz.org, vsementsov@virtuozzo.com, mst@redhat.com
Subject: Re: [Qemu-devel] [PATCH] balloon: fix segfault and harden the stats queue
Date: Tue, 1 Mar 2016 13:50:51 +0100	[thread overview]
Message-ID: <56D5902B.9050705@redhat.com> (raw)
In-Reply-To: <1456830843-24835-1-git-send-email-lprosek@redhat.com>

On 01/03/2016 12:14, Ladi Prosek wrote:
> The segfault here is triggered by the driver notifying the stats queue
> twice after adding a buffer to it. This effectively resets stats_vq_elem
> back to NULL and QEMU crashes on the next stats timer tick in
> balloon_stats_poll_cb.
> 
> This is a regression introduced in 51b19ebe4320f3dc, although admittedly
> the device assumed too much about the stats queue protocol even before
> that commit. This commit adds a few more checks and ensures that the one
> stats buffer gets deallocated on device reset.
> 
> Signed-off-by: Ladi Prosek <lprosek@redhat.com>
> ---
>  hw/virtio/virtio-balloon.c | 24 ++++++++++++++++++++++--
>  1 file changed, 22 insertions(+), 2 deletions(-)
> 
> diff --git a/hw/virtio/virtio-balloon.c b/hw/virtio/virtio-balloon.c
> index e9c30e9..e97d403 100644
> --- a/hw/virtio/virtio-balloon.c
> +++ b/hw/virtio/virtio-balloon.c
> @@ -101,7 +101,7 @@ static void balloon_stats_poll_cb(void *opaque)
>      VirtIOBalloon *s = opaque;
>      VirtIODevice *vdev = VIRTIO_DEVICE(s);
>  
> -    if (!balloon_stats_supported(s)) {
> +    if (s->stats_vq_elem == NULL || !balloon_stats_supported(s)) {
>          /* re-schedule */
>          balloon_stats_change_timer(s, s->stats_poll_interval);
>          return;
> @@ -258,11 +258,20 @@ static void virtio_balloon_receive_stats(VirtIODevice *vdev, VirtQueue *vq)
>      size_t offset = 0;
>      qemu_timeval tv;
>  
> -    s->stats_vq_elem = elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
> +    elem = virtqueue_pop(vq, sizeof(VirtQueueElement));
>      if (!elem) {
>          goto out;
>      }
>  
> +    if (s->stats_vq_elem != NULL) {
> +        /* This should never happen if the driver follows the spec. */
> +        virtqueue_push(vq, s->stats_vq_elem, 0);
> +        virtio_notify(vdev, vq);
> +        g_free(s->stats_vq_elem);
> +    }
> +
> +    s->stats_vq_elem = elem;
> +
>      /* Initialize the stats to get rid of any stale values.  This is only
>       * needed to handle the case where a guest supports fewer stats than it
>       * used to (ie. it has booted into an old kernel).
> @@ -458,6 +467,16 @@ static void virtio_balloon_device_unrealize(DeviceState *dev, Error **errp)
>      virtio_cleanup(vdev);
>  }
>  
> +static void virtio_balloon_device_reset(VirtIODevice *vdev)
> +{
> +    VirtIOBalloon *s = VIRTIO_BALLOON(vdev);
> +
> +    if (s->stats_vq_elem != NULL) {
> +        g_free(s->stats_vq_elem);
> +        s->stats_vq_elem = NULL;
> +    }
> +}
> +
>  static void virtio_balloon_instance_init(Object *obj)
>  {
>      VirtIOBalloon *s = VIRTIO_BALLOON(obj);
> @@ -486,6 +505,7 @@ static void virtio_balloon_class_init(ObjectClass *klass, void *data)
>      set_bit(DEVICE_CATEGORY_MISC, dc->categories);
>      vdc->realize = virtio_balloon_device_realize;
>      vdc->unrealize = virtio_balloon_device_unrealize;
> +    vdc->reset = virtio_balloon_device_reset;
>      vdc->get_config = virtio_balloon_get_config;
>      vdc->set_config = virtio_balloon_set_config;
>      vdc->get_features = virtio_balloon_get_features;
> 

Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>

There seem to be no other instances of the bug.

Paolo

      reply	other threads:[~2016-03-01 12:51 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2016-03-01 11:14 [Qemu-devel] [PATCH] balloon: fix segfault and harden the stats queue Ladi Prosek
2016-03-01 12:50 ` Paolo Bonzini [this message]

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=56D5902B.9050705@redhat.com \
    --to=pbonzini@redhat.com \
    --cc=den@openvz.org \
    --cc=lprosek@redhat.com \
    --cc=mst@redhat.com \
    --cc=qemu-devel@nongnu.org \
    --cc=vsementsov@virtuozzo.com \
    /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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.