]> git.proxmox.com Git - pve-qemu.git/commitdiff
merge various stable fixes
authorWolfgang Bumiller <w.bumiller@proxmox.com>
Tue, 6 Jun 2017 11:22:50 +0000 (13:22 +0200)
committerWolfgang Bumiller <w.bumiller@proxmox.com>
Tue, 6 Jun 2017 11:27:30 +0000 (13:27 +0200)
16 files changed:
debian/patches/extra/0001-Revert-target-i386-disable-LINT0-after-reset.patch [new file with mode: 0644]
debian/patches/extra/0002-qemu-img-wait-for-convert-coroutines-to-complete.patch [new file with mode: 0644]
debian/patches/extra/0003-block-Do-not-unref-bs-file-on-error-in-BD-s-open.patch [new file with mode: 0644]
debian/patches/extra/0004-9pfs-local-fix-unlink-of-alien-files-in-mapped-file-.patch [new file with mode: 0644]
debian/patches/extra/0005-blockdev-use-drained_begin-end-for-qmp_block_resize.patch [new file with mode: 0644]
debian/patches/extra/0006-aio-add-missing-aio_notify-to-aio_enable_external.patch [new file with mode: 0644]
debian/patches/extra/0007-virtio-serial-bus-Unset-hotplug-handler-when-unreali.patch [new file with mode: 0644]
debian/patches/extra/0008-virtio-serial-fix-segfault-on-disconnect.patch [new file with mode: 0644]
debian/patches/extra/0009-e1000e-Fix-ICR-Other-causes-clear-logic.patch [new file with mode: 0644]
debian/patches/extra/0010-mirror-Drop-permissions-on-s-target-on-completion.patch [new file with mode: 0644]
debian/patches/extra/0011-vmw_pvscsi-check-message-ring-page-count-at-initiali.patch [new file with mode: 0644]
debian/patches/extra/0012-audio-release-capture-buffers.patch [new file with mode: 0644]
debian/patches/extra/0013-input-limit-kbd-queue-depth.patch [new file with mode: 0644]
debian/patches/extra/0014-scsi-avoid-an-off-by-one-error-in-megasas_mmio_write.patch [new file with mode: 0644]
debian/patches/extra/0015-9pfs-local-forbid-client-access-to-metadata-CVE-2017.patch [new file with mode: 0644]
debian/patches/series

diff --git a/debian/patches/extra/0001-Revert-target-i386-disable-LINT0-after-reset.patch b/debian/patches/extra/0001-Revert-target-i386-disable-LINT0-after-reset.patch
new file mode 100644 (file)
index 0000000..1a11c4a
--- /dev/null
@@ -0,0 +1,33 @@
+From 12949af5b296e6a5717df5189647559cc35677a4 Mon Sep 17 00:00:00 2001
+From: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Date: Mon, 4 Jul 2016 15:02:26 +0200
+Subject: [PATCH 01/15] Revert "target-i386: disable LINT0 after reset"
+
+This reverts commit b8eb5512fd8a115f164edbbe897cdf8884920ccb.
+---
+ hw/intc/apic_common.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+diff --git a/hw/intc/apic_common.c b/hw/intc/apic_common.c
+index c3829e31b5..d4411a2fd4 100644
+--- a/hw/intc/apic_common.c
++++ b/hw/intc/apic_common.c
+@@ -257,6 +257,15 @@ static void apic_reset_common(DeviceState *dev)
+     info->vapic_base_update(s);
+     apic_init_reset(dev);
++
++    if (bsp) {
++        /*
++         * LINT0 delivery mode on CPU #0 is set to ExtInt at initialization
++         * time typically by BIOS, so PIC interrupt can be delivered to the
++         * processor when local APIC is enabled.
++         */
++        s->lvt[APIC_LVT_LINT0] = 0x700;
++    }
+ }
+ /* This function is only used for old state version 1 and 2 */
+-- 
+2.11.0
+
diff --git a/debian/patches/extra/0002-qemu-img-wait-for-convert-coroutines-to-complete.patch b/debian/patches/extra/0002-qemu-img-wait-for-convert-coroutines-to-complete.patch
new file mode 100644 (file)
index 0000000..ecb3a3b
--- /dev/null
@@ -0,0 +1,98 @@
+From 40bb673c38565bb8660f15f088a85bb0fd12ab82 Mon Sep 17 00:00:00 2001
+From: Anton Nefedov <anton.nefedov@virtuozzo.com>
+Date: Wed, 26 Apr 2017 11:33:15 +0300
+Subject: [PATCH 02/15] qemu-img: wait for convert coroutines to complete
+
+On error path (like i/o error in one of the coroutines), it's required to
+  - wait for coroutines completion before cleaning the common structures
+  - reenter dependent coroutines so they ever finish
+
+Introduced in 2d9187bc65.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Anton Nefedov <anton.nefedov@virtuozzo.com>
+Reviewed-by: Peter Lieven <pl@kamp.de>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+---
+ qemu-img.c | 26 +++++++++++---------------
+ 1 file changed, 11 insertions(+), 15 deletions(-)
+
+diff --git a/qemu-img.c b/qemu-img.c
+index 4f7f458dd2..cf9885b75b 100644
+--- a/qemu-img.c
++++ b/qemu-img.c
+@@ -1761,13 +1761,13 @@ static void coroutine_fn convert_co_do_copy(void *opaque)
+         qemu_co_mutex_lock(&s->lock);
+         if (s->ret != -EINPROGRESS || s->sector_num >= s->total_sectors) {
+             qemu_co_mutex_unlock(&s->lock);
+-            goto out;
++            break;
+         }
+         n = convert_iteration_sectors(s, s->sector_num);
+         if (n < 0) {
+             qemu_co_mutex_unlock(&s->lock);
+             s->ret = n;
+-            goto out;
++            break;
+         }
+         /* save current sector and allocation status to local variables */
+         sector_num = s->sector_num;
+@@ -1792,7 +1792,6 @@ static void coroutine_fn convert_co_do_copy(void *opaque)
+                 error_report("error while reading sector %" PRId64
+                              ": %s", sector_num, strerror(-ret));
+                 s->ret = ret;
+-                goto out;
+             }
+         } else if (!s->min_sparse && status == BLK_ZERO) {
+             status = BLK_DATA;
+@@ -1801,22 +1800,20 @@ static void coroutine_fn convert_co_do_copy(void *opaque)
+         if (s->wr_in_order) {
+             /* keep writes in order */
+-            while (s->wr_offs != sector_num) {
+-                if (s->ret != -EINPROGRESS) {
+-                    goto out;
+-                }
++            while (s->wr_offs != sector_num && s->ret == -EINPROGRESS) {
+                 s->wait_sector_num[index] = sector_num;
+                 qemu_coroutine_yield();
+             }
+             s->wait_sector_num[index] = -1;
+         }
+-        ret = convert_co_write(s, sector_num, n, buf, status);
+-        if (ret < 0) {
+-            error_report("error while writing sector %" PRId64
+-                         ": %s", sector_num, strerror(-ret));
+-            s->ret = ret;
+-            goto out;
++        if (s->ret == -EINPROGRESS) {
++            ret = convert_co_write(s, sector_num, n, buf, status);
++            if (ret < 0) {
++                error_report("error while writing sector %" PRId64
++                             ": %s", sector_num, strerror(-ret));
++                s->ret = ret;
++            }
+         }
+         if (s->wr_in_order) {
+@@ -1837,7 +1834,6 @@ static void coroutine_fn convert_co_do_copy(void *opaque)
+         }
+     }
+-out:
+     qemu_vfree(buf);
+     s->co[index] = NULL;
+     s->running_coroutines--;
+@@ -1899,7 +1895,7 @@ static int convert_do_copy(ImgConvertState *s)
+         qemu_coroutine_enter(s->co[i]);
+     }
+-    while (s->ret == -EINPROGRESS) {
++    while (s->running_coroutines) {
+         main_loop_wait(false);
+     }
+-- 
+2.11.0
+
diff --git a/debian/patches/extra/0003-block-Do-not-unref-bs-file-on-error-in-BD-s-open.patch b/debian/patches/extra/0003-block-Do-not-unref-bs-file-on-error-in-BD-s-open.patch
new file mode 100644 (file)
index 0000000..5ed70b6
--- /dev/null
@@ -0,0 +1,78 @@
+From 7abd8d3ceb29140469c3662fb53de6a4dfe4623e Mon Sep 17 00:00:00 2001
+From: Max Reitz <mreitz@redhat.com>
+Date: Thu, 13 Apr 2017 17:43:34 +0200
+Subject: [PATCH 03/15] block: Do not unref bs->file on error in BD's open
+
+The block layer takes care of removing the bs->file child if the block
+driver's bdrv_open()/bdrv_file_open() implementation fails. The block
+driver therefore does not need to do so, and indeed should not unless it
+sets bs->file to NULL afterwards -- because if this is not done, the
+bdrv_unref_child() in bdrv_open_inherit() will dereference the freed
+memory block at bs->file afterwards, which is not good.
+
+We can now decide whether to add a "bs->file = NULL;" after each of the
+offending bdrv_unref_child() invocations, or just drop them altogether.
+The latter is simpler, so let's do that.
+
+Cc: qemu-stable <qemu-stable@nongnu.org>
+Signed-off-by: Max Reitz <mreitz@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+---
+ block/blkdebug.c  | 4 +---
+ block/blkreplay.c | 3 ---
+ block/blkverify.c | 3 ---
+ 3 files changed, 1 insertion(+), 9 deletions(-)
+
+diff --git a/block/blkdebug.c b/block/blkdebug.c
+index 67e8024e36..cc4a146e84 100644
+--- a/block/blkdebug.c
++++ b/block/blkdebug.c
+@@ -389,14 +389,12 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
+     } else if (align) {
+         error_setg(errp, "Invalid alignment");
+         ret = -EINVAL;
+-        goto fail_unref;
++        goto out;
+     }
+     ret = 0;
+     goto out;
+-fail_unref:
+-    bdrv_unref_child(bs, bs->file);
+ out:
+     if (ret < 0) {
+         g_free(s->config_file);
+diff --git a/block/blkreplay.c b/block/blkreplay.c
+index e1102119fb..6aa5fd4156 100755
+--- a/block/blkreplay.c
++++ b/block/blkreplay.c
+@@ -37,9 +37,6 @@ static int blkreplay_open(BlockDriverState *bs, QDict *options, int flags,
+     ret = 0;
+ fail:
+-    if (ret < 0) {
+-        bdrv_unref_child(bs, bs->file);
+-    }
+     return ret;
+ }
+diff --git a/block/blkverify.c b/block/blkverify.c
+index 9a1e21c6ad..af23281669 100644
+--- a/block/blkverify.c
++++ b/block/blkverify.c
+@@ -142,9 +142,6 @@ static int blkverify_open(BlockDriverState *bs, QDict *options, int flags,
+     ret = 0;
+ fail:
+-    if (ret < 0) {
+-        bdrv_unref_child(bs, bs->file);
+-    }
+     qemu_opts_del(opts);
+     return ret;
+ }
+-- 
+2.11.0
+
diff --git a/debian/patches/extra/0004-9pfs-local-fix-unlink-of-alien-files-in-mapped-file-.patch b/debian/patches/extra/0004-9pfs-local-fix-unlink-of-alien-files-in-mapped-file-.patch
new file mode 100644 (file)
index 0000000..1d1a4dd
--- /dev/null
@@ -0,0 +1,103 @@
+From 575b9657b84e7c35d4a378448cdb43939fb5e730 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Thu, 25 May 2017 10:30:13 +0200
+Subject: [PATCH 04/15] 9pfs: local: fix unlink of alien files in mapped-file
+ mode
+
+When trying to remove a file from a directory, both created in non-mapped
+mode, the file remains and EBADF is returned to the guest.
+
+This is a regression introduced by commit "df4938a6651b 9pfs: local:
+unlinkat: don't follow symlinks" when fixing CVE-2016-9602. It changed the
+way we unlink the metadata file from
+
+    ret = remove("$dir/.virtfs_metadata/$name");
+    if (ret < 0 && errno != ENOENT) {
+         /* Error out */
+    }
+    /* Ignore absence of metadata */
+
+to
+
+    fd = openat("$dir/.virtfs_metadata")
+    unlinkat(fd, "$name")
+    if (ret < 0 && errno != ENOENT) {
+         /* Error out */
+    }
+    /* Ignore absence of metadata */
+
+If $dir was created in non-mapped mode, openat() fails with ENOENT and
+we pass -1 to unlinkat(), which fails in turn with EBADF.
+
+We just need to check the return of openat() and ignore ENOENT, in order
+to restore the behaviour we had with remove().
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+[groug: rewrote the comments as suggested by Eric]
+---
+ hw/9pfs/9p-local.c | 34 +++++++++++++++-------------------
+ 1 file changed, 15 insertions(+), 19 deletions(-)
+
+diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
+index f3ebca4f7a..7a0c383e7e 100644
+--- a/hw/9pfs/9p-local.c
++++ b/hw/9pfs/9p-local.c
+@@ -957,6 +957,14 @@ static int local_unlinkat_common(FsContext *ctx, int dirfd, const char *name,
+     if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+         int map_dirfd;
++        /* We need to remove the metadata as well:
++         * - the metadata directory if we're removing a directory
++         * - the metadata file in the parent's metadata directory
++         *
++         * If any of these are missing (ie, ENOENT) then we're probably
++         * trying to remove something that wasn't created in mapped-file
++         * mode. We just ignore the error.
++         */
+         if (flags == AT_REMOVEDIR) {
+             int fd;
+@@ -964,32 +972,20 @@ static int local_unlinkat_common(FsContext *ctx, int dirfd, const char *name,
+             if (fd == -1) {
+                 goto err_out;
+             }
+-            /*
+-             * If directory remove .virtfs_metadata contained in the
+-             * directory
+-             */
+             ret = unlinkat(fd, VIRTFS_META_DIR, AT_REMOVEDIR);
+             close_preserve_errno(fd);
+             if (ret < 0 && errno != ENOENT) {
+-                /*
+-                 * We didn't had the .virtfs_metadata file. May be file created
+-                 * in non-mapped mode ?. Ignore ENOENT.
+-                 */
+                 goto err_out;
+             }
+         }
+-        /*
+-         * Now remove the name from parent directory
+-         * .virtfs_metadata directory.
+-         */
+         map_dirfd = openat_dir(dirfd, VIRTFS_META_DIR);
+-        ret = unlinkat(map_dirfd, name, 0);
+-        close_preserve_errno(map_dirfd);
+-        if (ret < 0 && errno != ENOENT) {
+-            /*
+-             * We didn't had the .virtfs_metadata file. May be file created
+-             * in non-mapped mode ?. Ignore ENOENT.
+-             */
++        if (map_dirfd != -1) {
++            ret = unlinkat(map_dirfd, name, 0);
++            close_preserve_errno(map_dirfd);
++            if (ret < 0 && errno != ENOENT) {
++                goto err_out;
++            }
++        } else if (errno != ENOENT) {
+             goto err_out;
+         }
+     }
+-- 
+2.11.0
+
diff --git a/debian/patches/extra/0005-blockdev-use-drained_begin-end-for-qmp_block_resize.patch b/debian/patches/extra/0005-blockdev-use-drained_begin-end-for-qmp_block_resize.patch
new file mode 100644 (file)
index 0000000..eca386c
--- /dev/null
@@ -0,0 +1,44 @@
+From a2486a266d8df715349ec0e325d0bedc0bdc0557 Mon Sep 17 00:00:00 2001
+From: John Snow <jsnow@redhat.com>
+Date: Wed, 10 May 2017 13:39:45 -0400
+Subject: [PATCH 05/15] blockdev: use drained_begin/end for qmp_block_resize
+
+Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1447551
+
+If one tries to issue a block_resize while a guest is busy
+accessing the disk, it is possible that qemu may deadlock
+when invoking aio_poll from both the main loop and the iothread.
+
+Replace another instance of bdrv_drain_all that doesn't
+quite belong.
+
+Cc: qemu-stable@nongnu.org
+Suggested-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: John Snow <jsnow@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+---
+ blockdev.c | 5 ++---
+ 1 file changed, 2 insertions(+), 3 deletions(-)
+
+diff --git a/blockdev.c b/blockdev.c
+index 43818dade1..d8ff508eff 100644
+--- a/blockdev.c
++++ b/blockdev.c
+@@ -2929,10 +2929,9 @@ void qmp_block_resize(bool has_device, const char *device,
+         goto out;
+     }
+-    /* complete all in-flight operations before resizing the device */
+-    bdrv_drain_all();
+-
++    bdrv_drained_begin(bs);
+     ret = blk_truncate(blk, size);
++    bdrv_drained_end(bs);
+     switch (ret) {
+     case 0:
+         break;
+-- 
+2.11.0
+
diff --git a/debian/patches/extra/0006-aio-add-missing-aio_notify-to-aio_enable_external.patch b/debian/patches/extra/0006-aio-add-missing-aio_notify-to-aio_enable_external.patch
new file mode 100644 (file)
index 0000000..02dd110
--- /dev/null
@@ -0,0 +1,71 @@
+From c9d7fd0fd5736afd1f6c508f2b5f1ae0608847bd Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Mon, 8 May 2017 14:07:05 -0400
+Subject: [PATCH 06/15] aio: add missing aio_notify() to aio_enable_external()
+
+The main loop uses aio_disable_external()/aio_enable_external() to
+temporarily disable processing of external AioContext clients like
+device emulation.
+
+This allows monitor commands to quiesce I/O and prevent the guest from
+submitting new requests while a monitor command is in progress.
+
+The aio_enable_external() API is currently broken when an IOThread is in
+aio_poll() waiting for fd activity when the main loop re-enables
+external clients.  Incrementing ctx->external_disable_cnt does not wake
+the IOThread from ppoll(2) so fd processing remains suspended and leads
+to unresponsive emulated devices.
+
+This patch adds an aio_notify() call to aio_enable_external() so the
+IOThread is kicked out of ppoll(2) and will re-arm the file descriptors.
+
+The bug can be reproduced as follows:
+
+  $ qemu -M accel=kvm -m 1024 \
+         -object iothread,id=iothread0 \
+         -device virtio-scsi-pci,iothread=iothread0,id=virtio-scsi-pci0 \
+         -drive if=none,id=drive0,aio=native,cache=none,format=raw,file=test.img \
+         -device scsi-hd,id=scsi-hd0,drive=drive0 \
+         -qmp tcp::5555,server,nowait
+
+  $ scripts/qmp/qmp-shell localhost:5555
+  (qemu) blockdev-snapshot-sync device=drive0 snapshot-file=sn1.qcow2
+         mode=absolute-paths format=qcow2
+
+After blockdev-snapshot-sync completes the SCSI disk will be
+unresponsive.  This leads to request timeouts inside the guest.
+
+Reported-by: Qianqian Zhu <qizhu@redhat.com>
+Reviewed-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Message-id: 20170508180705.20609-1-stefanha@redhat.com
+Suggested-by: Fam Zheng <famz@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ include/block/aio.h | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/include/block/aio.h b/include/block/aio.h
+index 406e32305a..e9aeeaec94 100644
+--- a/include/block/aio.h
++++ b/include/block/aio.h
+@@ -454,8 +454,14 @@ static inline void aio_disable_external(AioContext *ctx)
+  */
+ static inline void aio_enable_external(AioContext *ctx)
+ {
+-    assert(ctx->external_disable_cnt > 0);
+-    atomic_dec(&ctx->external_disable_cnt);
++    int old;
++
++    old = atomic_fetch_dec(&ctx->external_disable_cnt);
++    assert(old > 0);
++    if (old == 1) {
++        /* Kick event loop so it re-arms file descriptors */
++        aio_notify(ctx);
++    }
+ }
+ /**
+-- 
+2.11.0
+
diff --git a/debian/patches/extra/0007-virtio-serial-bus-Unset-hotplug-handler-when-unreali.patch b/debian/patches/extra/0007-virtio-serial-bus-Unset-hotplug-handler-when-unreali.patch
new file mode 100644 (file)
index 0000000..a695a66
--- /dev/null
@@ -0,0 +1,42 @@
+From 48c670e522857fa54207794d3dfc014b4809079c Mon Sep 17 00:00:00 2001
+From: Ladi Prosek <lprosek@redhat.com>
+Date: Tue, 30 May 2017 10:59:43 +0200
+Subject: [PATCH 07/15] virtio-serial-bus: Unset hotplug handler when unrealize
+
+Virtio serial device controls the lifetime of virtio-serial-bus and
+virtio-serial-bus links back to the device via its hotplug-handler
+property. This extra ref-count prevents the device from getting
+finalized, leaving the VirtIODevice memory listener registered and
+leading to use-after-free later on.
+
+This patch addresses the same issue as Fam Zheng's
+"virtio-scsi: Unset hotplug handler when unrealize"
+only for a different virtio device.
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Ladi Prosek <lprosek@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
+Reviewed-by: Fam Zheng <famz@redhat.com>
+---
+ hw/char/virtio-serial-bus.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
+index d797a6796e..aa9c11ae92 100644
+--- a/hw/char/virtio-serial-bus.c
++++ b/hw/char/virtio-serial-bus.c
+@@ -1121,6 +1121,9 @@ static void virtio_serial_device_unrealize(DeviceState *dev, Error **errp)
+         timer_free(vser->post_load->timer);
+         g_free(vser->post_load);
+     }
++
++    qbus_set_hotplug_handler(BUS(&vser->bus), NULL, errp);
++
+     virtio_cleanup(vdev);
+ }
+-- 
+2.11.0
+
diff --git a/debian/patches/extra/0008-virtio-serial-fix-segfault-on-disconnect.patch b/debian/patches/extra/0008-virtio-serial-fix-segfault-on-disconnect.patch
new file mode 100644 (file)
index 0000000..ebe63f7
--- /dev/null
@@ -0,0 +1,74 @@
+From 129083526210432c2233874be45e47a61c405db0 Mon Sep 17 00:00:00 2001
+From: Stefan Hajnoczi <stefanha@redhat.com>
+Date: Fri, 2 Jun 2017 10:54:24 +0100
+Subject: [PATCH 08/15] virtio-serial: fix segfault on disconnect
+
+Since commit d4c19cdeeb2f1e474bc426a6da261f1d7346eb5b ("virtio-serial:
+add missing virtio_detach_element() call") the following commands may
+cause QEMU to segfault:
+
+  $ qemu -M accel=kvm -cpu host -m 1G \
+         -drive if=virtio,file=test.img,format=raw \
+         -device virtio-serial-pci,id=virtio-serial0 \
+         -chardev socket,id=channel1,path=/tmp/chardev.sock,server,nowait \
+         -device virtserialport,chardev=channel1,bus=virtio-serial0.0,id=port1
+  $ nc -U /tmp/chardev.sock
+  ^C
+
+  (guest)$ cat /dev/zero >/dev/vport0p1
+
+The segfault is non-deterministic: if the event loop notices the socket
+has been closed then there is no crash.  The disconnect has to happen
+right before QEMU attempts to write data to the socket.
+
+The backtrace is as follows:
+
+  Thread 1 "qemu-system-x86" received signal SIGSEGV, Segmentation fault.
+  0x00005555557e0698 in do_flush_queued_data (port=0x5555582cedf0, vq=0x7fffcc854290, vdev=0x55555807b1d0) at hw/char/virtio-serial-bus.c:180
+  180           for (i = port->iov_idx; i < port->elem->out_num; i++) {
+  #1  0x000055555580d363 in virtio_queue_notify_vq (vq=0x7fffcc854290) at hw/virtio/virtio.c:1524
+  #2  0x000055555580d363 in virtio_queue_host_notifier_read (n=0x7fffcc8542f8) at hw/virtio/virtio.c:2430
+  #3  0x0000555555b3482c in aio_dispatch_handlers (ctx=ctx@entry=0x5555566b8c80) at util/aio-posix.c:399
+  #4  0x0000555555b350d8 in aio_dispatch (ctx=0x5555566b8c80) at util/aio-posix.c:430
+  #5  0x0000555555b3212e in aio_ctx_dispatch (source=<optimized out>, callback=<optimized out>, user_data=<optimized out>) at util/async.c:261
+  #6  0x00007fffde71de52 in g_main_context_dispatch () at /lib64/libglib-2.0.so.0
+  #7  0x0000555555b34353 in glib_pollfds_poll () at util/main-loop.c:213
+  #8  0x0000555555b34353 in os_host_main_loop_wait (timeout=<optimized out>) at util/main-loop.c:261
+  #9  0x0000555555b34353 in main_loop_wait (nonblocking=<optimized out>) at util/main-loop.c:517
+  #10 0x0000555555773207 in main_loop () at vl.c:1917
+  #11 0x0000555555773207 in main (argc=<optimized out>, argv=<optimized out>, envp=<optimized out>) at vl.c:4751
+
+The do_flush_queued_data() function does not anticipate chardev close
+events during vsc->have_data().  It expects port->elem to remain
+non-NULL for the duration its for loop.
+
+The fix is simply to return from do_flush_queued_data() if the port
+closes because the close event already frees port->elem and drains the
+virtqueue - there is nothing left for do_flush_queued_data() to do.
+
+Reported-by: Sitong Liu <siliu@redhat.com>
+Reported-by: Min Deng <mdeng@redhat.com>
+Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
+Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
+---
+ hw/char/virtio-serial-bus.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/hw/char/virtio-serial-bus.c b/hw/char/virtio-serial-bus.c
+index aa9c11ae92..f5bc173844 100644
+--- a/hw/char/virtio-serial-bus.c
++++ b/hw/char/virtio-serial-bus.c
+@@ -186,6 +186,9 @@ static void do_flush_queued_data(VirtIOSerialPort *port, VirtQueue *vq,
+                                   port->elem->out_sg[i].iov_base
+                                   + port->iov_offset,
+                                   buf_size);
++            if (!port->elem) { /* bail if we got disconnected */
++                return;
++            }
+             if (port->throttled) {
+                 port->iov_idx = i;
+                 if (ret > 0) {
+-- 
+2.11.0
+
diff --git a/debian/patches/extra/0009-e1000e-Fix-ICR-Other-causes-clear-logic.patch b/debian/patches/extra/0009-e1000e-Fix-ICR-Other-causes-clear-logic.patch
new file mode 100644 (file)
index 0000000..cbc05bf
--- /dev/null
@@ -0,0 +1,96 @@
+From 1b050be441ffab9c4babec630bbdd14f14c95022 Mon Sep 17 00:00:00 2001
+From: Sameeh Jubran <sameeh@daynix.com>
+Date: Mon, 22 May 2017 14:26:22 +0300
+Subject: [PATCH 09/15] e1000e: Fix ICR "Other" causes clear logic
+
+This commit fixes a bug which causes the guest to hang. The bug was
+observed upon a "receive overrun" (bit #6 of the ICR register)
+interrupt which could be triggered post migration in a heavy traffic
+environment. Even though the "receive overrun" bit (#6) is masked out
+by the IMS register (refer to the log below) the driver still receives
+an interrupt as the "receive overrun" bit (#6) causes the "Other" -
+bit #24 of the ICR register - bit to be set as documented below. The
+driver handles the interrupt and clears the "Other" bit (#24) but
+doesn't clear the "receive overrun" bit (#6) which leads to an
+infinite loop. Apparently the Windows driver expects that the "receive
+overrun" bit and other ones - documented below - to be cleared when
+the "Other" bit (#24) is cleared.
+
+So to sum that up:
+1. Bit #6 of the ICR register is set by heavy traffic
+2. As a results of setting bit #6, bit #24 is set
+3. The driver receives an interrupt for bit 24 (it doesn't receieve an
+   interrupt for bit #6 as it is masked out by IMS)
+4. The driver handles and clears the interrupt of bit #24
+5. Bit #6 is still set.
+6. 2 happens all over again
+
+The Interrupt Cause Read - ICR register:
+
+The ICR has the "Other" bit - bit #24 - that is set when one or more
+of the following ICR register's bits are set:
+
+LSC - bit #2, RXO - bit #6, MDAC - bit #9, SRPD - bit #16, ACK - bit
+#17, MNG - bit #18
+
+This bug can occur with any of these bits depending on the driver's
+behaviour and the way it configures the device. However, trying to
+reproduce it with any bit other than RX0 is challenging and came to
+failure as the drivers don't implement most of these bits, trying to
+reproduce it with LSC (Link Status Change - bit #2) bit didn't succeed
+too as it seems that Windows handles this bit differently.
+
+Log sample of the storm:
+
+27563@1494850819.411877:e1000e_irq_pending_interrupts ICR PENDING: 0x1000000 (ICR: 0x815000c2, IMS: 0x1a00004)
+27563@1494850819.411900:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
+27563@1494850819.411915:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
+27563@1494850819.412380:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
+27563@1494850819.412395:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
+27563@1494850819.412436:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
+27563@1494850819.412441:e1000e_irq_pending_interrupts ICR PENDING: 0x0 (ICR: 0x815000c2, IMS: 0xa00004)
+27563@1494850819.412998:e1000e_irq_pending_interrupts ICR PENDING: 0x1000000 (ICR: 0x815000c2, IMS: 0x1a00004)
+
+* This bug behaviour wasn't observed with the Linux driver.
+
+This commit solves:
+https://bugzilla.redhat.com/show_bug.cgi?id=1447935
+https://bugzilla.redhat.com/show_bug.cgi?id=1449490
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Sameeh Jubran <sjubran@redhat.com>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+---
+ hw/net/e1000e_core.c | 10 ++++++++--
+ 1 file changed, 8 insertions(+), 2 deletions(-)
+
+diff --git a/hw/net/e1000e_core.c b/hw/net/e1000e_core.c
+index 28c5be1506..81405640f0 100644
+--- a/hw/net/e1000e_core.c
++++ b/hw/net/e1000e_core.c
+@@ -2454,14 +2454,20 @@ e1000e_set_ics(E1000ECore *core, int index, uint32_t val)
+ static void
+ e1000e_set_icr(E1000ECore *core, int index, uint32_t val)
+ {
++    uint32_t icr = 0;
+     if ((core->mac[ICR] & E1000_ICR_ASSERTED) &&
+         (core->mac[CTRL_EXT] & E1000_CTRL_EXT_IAME)) {
+         trace_e1000e_irq_icr_process_iame();
+         e1000e_clear_ims_bits(core, core->mac[IAM]);
+     }
+-    trace_e1000e_irq_icr_write(val, core->mac[ICR], core->mac[ICR] & ~val);
+-    core->mac[ICR] &= ~val;
++    icr = core->mac[ICR] & ~val;
++    /* Windows driver expects that the "receive overrun" bit and other
++     * ones to be cleared when the "Other" bit (#24) is cleared.
++     */
++    icr = (val & E1000_ICR_OTHER) ? (icr & ~E1000_ICR_OTHER_CAUSES) : icr;
++    trace_e1000e_irq_icr_write(val, core->mac[ICR], icr);
++    core->mac[ICR] = icr;
+     e1000e_update_interrupt_state(core);
+ }
+-- 
+2.11.0
+
diff --git a/debian/patches/extra/0010-mirror-Drop-permissions-on-s-target-on-completion.patch b/debian/patches/extra/0010-mirror-Drop-permissions-on-s-target-on-completion.patch
new file mode 100644 (file)
index 0000000..365bd69
--- /dev/null
@@ -0,0 +1,57 @@
+From 95166cdeaeaa9d00330483988b818abfcc473efe Mon Sep 17 00:00:00 2001
+From: Kevin Wolf <kwolf@redhat.com>
+Date: Mon, 29 May 2017 14:08:32 +0200
+Subject: [PATCH 10/15] mirror: Drop permissions on s->target on completion
+
+This fixes an assertion failure that was triggered by qemu-iotests 129
+on some CI host, while the same test case didn't seem to fail on other
+hosts.
+
+Essentially the problem is that the blk_unref(s->target) in
+mirror_exit() doesn't necessarily mean that the BlockBackend goes away
+immediately. It is possible that the job completion was triggered nested
+in mirror_drain(), which looks like this:
+
+    BlockBackend *target = s->target;
+    blk_ref(target);
+    blk_drain(target);
+    blk_unref(target);
+
+In this case, the write permissions for s->target are retained until
+after blk_drain(), which makes removing mirror_top_bs fail for the
+active commit case (can't have a writable backing file in the chain
+without the filter driver).
+
+Explicitly dropping the permissions first means that the additional
+reference doesn't hurt and the job can complete successfully even if
+called from the nested blk_drain().
+
+Cc: qemu-stable@nongnu.org
+Signed-off-by: Kevin Wolf <kwolf@redhat.com>
+Acked-by: Paolo Bonzini <pbonzini@redhat.com>
+Reviewed-by: Max Reitz <mreitz@redhat.com>
+---
+ block/mirror.c | 7 ++++++-
+ 1 file changed, 6 insertions(+), 1 deletion(-)
+
+diff --git a/block/mirror.c b/block/mirror.c
+index 164438f422..779b753b8a 100644
+--- a/block/mirror.c
++++ b/block/mirror.c
+@@ -514,7 +514,12 @@ static void mirror_exit(BlockJob *job, void *opaque)
+     /* Remove target parent that still uses BLK_PERM_WRITE/RESIZE before
+      * inserting target_bs at s->to_replace, where we might not be able to get
+-     * these permissions. */
++     * these permissions.
++     *
++     * Note that blk_unref() alone doesn't necessarily drop permissions because
++     * we might be running nested inside mirror_drain(), which takes an extra
++     * reference, so use an explicit blk_set_perm() first. */
++    blk_set_perm(s->target, 0, BLK_PERM_ALL, &error_abort);
+     blk_unref(s->target);
+     s->target = NULL;
+-- 
+2.11.0
+
diff --git a/debian/patches/extra/0011-vmw_pvscsi-check-message-ring-page-count-at-initiali.patch b/debian/patches/extra/0011-vmw_pvscsi-check-message-ring-page-count-at-initiali.patch
new file mode 100644 (file)
index 0000000..d208624
--- /dev/null
@@ -0,0 +1,34 @@
+From d2eb933639fa12bfa36238c72b1c5a8fb59bdfcd Mon Sep 17 00:00:00 2001
+From: P J P <ppandit@redhat.com>
+Date: Tue, 25 Apr 2017 18:36:23 +0530
+Subject: [PATCH 11/15] vmw_pvscsi: check message ring page count at
+ initialisation
+
+A guest could set the message ring page count to zero, resulting in
+infinite loop. Add check to avoid it.
+
+Reported-by: YY Z <bigbird475958471@gmail.com>
+Signed-off-by: P J P <ppandit@redhat.com>
+Message-Id: <20170425130623.3649-1-ppandit@redhat.com>
+Reviewed-by: Dmitry Fleytman <dmitry@daynix.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/scsi/vmw_pvscsi.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
+index 75575461e2..4a106da856 100644
+--- a/hw/scsi/vmw_pvscsi.c
++++ b/hw/scsi/vmw_pvscsi.c
+@@ -202,7 +202,7 @@ pvscsi_ring_init_msg(PVSCSIRingInfo *m, PVSCSICmdDescSetupMsgRing *ri)
+     uint32_t len_log2;
+     uint32_t ring_size;
+-    if (ri->numPages > PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES) {
++    if (!ri->numPages || ri->numPages > PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES) {
+         return -1;
+     }
+     ring_size = ri->numPages * PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE;
+-- 
+2.11.0
+
diff --git a/debian/patches/extra/0012-audio-release-capture-buffers.patch b/debian/patches/extra/0012-audio-release-capture-buffers.patch
new file mode 100644 (file)
index 0000000..5ca0bf5
--- /dev/null
@@ -0,0 +1,38 @@
+From 56ca431e96a6aadffdccecb882600dc780f13ad9 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Fri, 28 Apr 2017 09:56:12 +0200
+Subject: [PATCH 12/15] audio: release capture buffers
+
+AUD_add_capture() allocates two buffers which are never released.
+Add the missing calls to AUD_del_capture().
+
+Impact: Allows vnc clients to exhaust host memory by repeatedly
+starting and stopping audio capture.
+
+Fixes: CVE-2017-8309
+Cc: P J P <ppandit@redhat.com>
+Cc: Huawei PSIRT <PSIRT@huawei.com>
+Reported-by: "Jiangxin (hunter, SCC)" <jiangxin1@huawei.com>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Reviewed-by: Prasad J Pandit <pjp@fedoraproject.org>
+Message-id: 20170428075612.9997-1-kraxel@redhat.com
+---
+ audio/audio.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/audio/audio.c b/audio/audio.c
+index c8898d8422..beafed209b 100644
+--- a/audio/audio.c
++++ b/audio/audio.c
+@@ -2028,6 +2028,8 @@ void AUD_del_capture (CaptureVoiceOut *cap, void *cb_opaque)
+                     sw = sw1;
+                 }
+                 QLIST_REMOVE (cap, entries);
++                g_free (cap->hw.mix_buf);
++                g_free (cap->buf);
+                 g_free (cap);
+             }
+             return;
+-- 
+2.11.0
+
diff --git a/debian/patches/extra/0013-input-limit-kbd-queue-depth.patch b/debian/patches/extra/0013-input-limit-kbd-queue-depth.patch
new file mode 100644 (file)
index 0000000..ce02632
--- /dev/null
@@ -0,0 +1,90 @@
+From e4f39e928710d19db0a0669b66520236197352aa Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Fri, 28 Apr 2017 10:42:37 +0200
+Subject: [PATCH 13/15] input: limit kbd queue depth
+
+Apply a limit to the number of items we accept into the keyboard queue.
+
+Impact: Without this limit vnc clients can exhaust host memory by
+sending keyboard events faster than qemu feeds them to the guest.
+
+Fixes: CVE-2017-8379
+Cc: P J P <ppandit@redhat.com>
+Cc: Huawei PSIRT <PSIRT@huawei.com>
+Reported-by: jiangxin1@huawei.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: 20170428084237.23960-1-kraxel@redhat.com
+---
+ ui/input.c | 14 +++++++++++---
+ 1 file changed, 11 insertions(+), 3 deletions(-)
+
+diff --git a/ui/input.c b/ui/input.c
+index ed88cda6d6..fb1f404095 100644
+--- a/ui/input.c
++++ b/ui/input.c
+@@ -41,6 +41,8 @@ static QTAILQ_HEAD(QemuInputEventQueueHead, QemuInputEventQueue) kbd_queue =
+     QTAILQ_HEAD_INITIALIZER(kbd_queue);
+ static QEMUTimer *kbd_timer;
+ static uint32_t kbd_default_delay_ms = 10;
++static uint32_t queue_count;
++static uint32_t queue_limit = 1024;
+ QemuInputHandlerState *qemu_input_handler_register(DeviceState *dev,
+                                                    QemuInputHandler *handler)
+@@ -268,6 +270,7 @@ static void qemu_input_queue_process(void *opaque)
+             break;
+         }
+         QTAILQ_REMOVE(queue, item, node);
++        queue_count--;
+         g_free(item);
+     }
+ }
+@@ -282,6 +285,7 @@ static void qemu_input_queue_delay(struct QemuInputEventQueueHead *queue,
+     item->delay_ms = delay_ms;
+     item->timer = timer;
+     QTAILQ_INSERT_TAIL(queue, item, node);
++    queue_count++;
+     if (start_timer) {
+         timer_mod(item->timer, qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL)
+@@ -298,6 +302,7 @@ static void qemu_input_queue_event(struct QemuInputEventQueueHead *queue,
+     item->src = src;
+     item->evt = evt;
+     QTAILQ_INSERT_TAIL(queue, item, node);
++    queue_count++;
+ }
+ static void qemu_input_queue_sync(struct QemuInputEventQueueHead *queue)
+@@ -306,6 +311,7 @@ static void qemu_input_queue_sync(struct QemuInputEventQueueHead *queue)
+     item->type = QEMU_INPUT_QUEUE_SYNC;
+     QTAILQ_INSERT_TAIL(queue, item, node);
++    queue_count++;
+ }
+ void qemu_input_event_send_impl(QemuConsole *src, InputEvent *evt)
+@@ -381,7 +387,7 @@ void qemu_input_event_send_key(QemuConsole *src, KeyValue *key, bool down)
+         qemu_input_event_send(src, evt);
+         qemu_input_event_sync();
+         qapi_free_InputEvent(evt);
+-    } else {
++    } else if (queue_count < queue_limit) {
+         qemu_input_queue_event(&kbd_queue, src, evt);
+         qemu_input_queue_sync(&kbd_queue);
+     }
+@@ -409,8 +415,10 @@ void qemu_input_event_send_key_delay(uint32_t delay_ms)
+         kbd_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, qemu_input_queue_process,
+                                  &kbd_queue);
+     }
+-    qemu_input_queue_delay(&kbd_queue, kbd_timer,
+-                           delay_ms ? delay_ms : kbd_default_delay_ms);
++    if (queue_count < queue_limit) {
++        qemu_input_queue_delay(&kbd_queue, kbd_timer,
++                               delay_ms ? delay_ms : kbd_default_delay_ms);
++    }
+ }
+ InputEvent *qemu_input_event_new_btn(InputButton btn, bool down)
+-- 
+2.11.0
+
diff --git a/debian/patches/extra/0014-scsi-avoid-an-off-by-one-error-in-megasas_mmio_write.patch b/debian/patches/extra/0014-scsi-avoid-an-off-by-one-error-in-megasas_mmio_write.patch
new file mode 100644 (file)
index 0000000..277ecb3
--- /dev/null
@@ -0,0 +1,45 @@
+From 3bf1e29359a1e22a2ecdffb50f124db275abf5bd Mon Sep 17 00:00:00 2001
+From: Prasad J Pandit <pjp@fedoraproject.org>
+Date: Mon, 24 Apr 2017 17:36:34 +0530
+Subject: [PATCH 14/15] scsi: avoid an off-by-one error in megasas_mmio_write
+
+While reading magic sequence(MFI_SEQ) in megasas_mmio_write,
+an off-by-one error could occur as 's->adp_reset' index is not
+reset after reading the last sequence.
+
+Reported-by: YY Z <bigbird475958471@gmail.com>
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Message-Id: <20170424120634.12268-1-ppandit@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/scsi/megasas.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
+index 84b8caf901..804122ab05 100644
+--- a/hw/scsi/megasas.c
++++ b/hw/scsi/megasas.c
+@@ -2138,15 +2138,15 @@ static void megasas_mmio_write(void *opaque, hwaddr addr,
+     case MFI_SEQ:
+         trace_megasas_mmio_writel("MFI_SEQ", val);
+         /* Magic sequence to start ADP reset */
+-        if (adp_reset_seq[s->adp_reset] == val) {
+-            s->adp_reset++;
++        if (adp_reset_seq[s->adp_reset++] == val) {
++            if (s->adp_reset == 6) {
++                s->adp_reset = 0;
++                s->diag = MFI_DIAG_WRITE_ENABLE;
++            }
+         } else {
+             s->adp_reset = 0;
+             s->diag = 0;
+         }
+-        if (s->adp_reset == 6) {
+-            s->diag = MFI_DIAG_WRITE_ENABLE;
+-        }
+         break;
+     case MFI_DIAG:
+         trace_megasas_mmio_writel("MFI_DIAG", val);
+-- 
+2.11.0
+
diff --git a/debian/patches/extra/0015-9pfs-local-forbid-client-access-to-metadata-CVE-2017.patch b/debian/patches/extra/0015-9pfs-local-forbid-client-access-to-metadata-CVE-2017.patch
new file mode 100644 (file)
index 0000000..6a82e91
--- /dev/null
@@ -0,0 +1,175 @@
+From 6364ef68ee01ec566617ffa6982a8d551cec0f75 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Fri, 5 May 2017 14:48:08 +0200
+Subject: [PATCH 15/15] 9pfs: local: forbid client access to metadata
+ (CVE-2017-7493)
+
+When using the mapped-file security mode, we shouldn't let the client mess
+with the metadata. The current code already tries to hide the metadata dir
+from the client by skipping it in local_readdir(). But the client can still
+access or modify it through several other operations. This can be used to
+escalate privileges in the guest.
+
+Affected backend operations are:
+- local_mknod()
+- local_mkdir()
+- local_open2()
+- local_symlink()
+- local_link()
+- local_unlinkat()
+- local_renameat()
+- local_rename()
+- local_name_to_path()
+
+Other operations are safe because they are only passed a fid path, which
+is computed internally in local_name_to_path().
+
+This patch converts all the functions listed above to fail and return
+EINVAL when being passed the name of the metadata dir. This may look
+like a poor choice for errno, but there's no such thing as an illegal
+path name on Linux and I could not think of anything better.
+
+This fixes CVE-2017-7493.
+
+Reported-by: Leo Gaspard <leo@gaspard.io>
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+---
+ hw/9pfs/9p-local.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
+ 1 file changed, 56 insertions(+), 2 deletions(-)
+
+diff --git a/hw/9pfs/9p-local.c b/hw/9pfs/9p-local.c
+index 7a0c383e7e..226234d386 100644
+--- a/hw/9pfs/9p-local.c
++++ b/hw/9pfs/9p-local.c
+@@ -452,6 +452,11 @@ static off_t local_telldir(FsContext *ctx, V9fsFidOpenState *fs)
+     return telldir(fs->dir.stream);
+ }
++static bool local_is_mapped_file_metadata(FsContext *fs_ctx, const char *name)
++{
++    return !strcmp(name, VIRTFS_META_DIR);
++}
++
+ static struct dirent *local_readdir(FsContext *ctx, V9fsFidOpenState *fs)
+ {
+     struct dirent *entry;
+@@ -465,8 +470,8 @@ again:
+     if (ctx->export_flags & V9FS_SM_MAPPED) {
+         entry->d_type = DT_UNKNOWN;
+     } else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+-        if (!strcmp(entry->d_name, VIRTFS_META_DIR)) {
+-            /* skp the meta data directory */
++        if (local_is_mapped_file_metadata(ctx, entry->d_name)) {
++            /* skip the meta data directory */
+             goto again;
+         }
+         entry->d_type = DT_UNKNOWN;
+@@ -559,6 +564,12 @@ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
+     int err = -1;
+     int dirfd;
++    if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
++        local_is_mapped_file_metadata(fs_ctx, name)) {
++        errno = EINVAL;
++        return -1;
++    }
++
+     dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
+     if (dirfd == -1) {
+         return -1;
+@@ -605,6 +616,12 @@ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
+     int err = -1;
+     int dirfd;
++    if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
++        local_is_mapped_file_metadata(fs_ctx, name)) {
++        errno = EINVAL;
++        return -1;
++    }
++
+     dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
+     if (dirfd == -1) {
+         return -1;
+@@ -694,6 +711,12 @@ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
+     int err = -1;
+     int dirfd;
++    if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
++        local_is_mapped_file_metadata(fs_ctx, name)) {
++        errno = EINVAL;
++        return -1;
++    }
++
+     /*
+      * Mark all the open to not follow symlinks
+      */
+@@ -752,6 +775,12 @@ static int local_symlink(FsContext *fs_ctx, const char *oldpath,
+     int err = -1;
+     int dirfd;
++    if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE &&
++        local_is_mapped_file_metadata(fs_ctx, name)) {
++        errno = EINVAL;
++        return -1;
++    }
++
+     dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
+     if (dirfd == -1) {
+         return -1;
+@@ -826,6 +855,12 @@ static int local_link(FsContext *ctx, V9fsPath *oldpath,
+     int ret = -1;
+     int odirfd, ndirfd;
++    if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
++        local_is_mapped_file_metadata(ctx, name)) {
++        errno = EINVAL;
++        return -1;
++    }
++
+     odirfd = local_opendir_nofollow(ctx, odirpath);
+     if (odirfd == -1) {
+         goto out;
+@@ -1092,6 +1127,12 @@ static int local_lremovexattr(FsContext *ctx, V9fsPath *fs_path,
+ static int local_name_to_path(FsContext *ctx, V9fsPath *dir_path,
+                               const char *name, V9fsPath *target)
+ {
++    if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
++        local_is_mapped_file_metadata(ctx, name)) {
++        errno = EINVAL;
++        return -1;
++    }
++
+     if (dir_path) {
+         v9fs_path_sprintf(target, "%s/%s", dir_path->data, name);
+     } else if (strcmp(name, "/")) {
+@@ -1112,6 +1153,13 @@ static int local_renameat(FsContext *ctx, V9fsPath *olddir,
+     int ret;
+     int odirfd, ndirfd;
++    if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
++        (local_is_mapped_file_metadata(ctx, old_name) ||
++         local_is_mapped_file_metadata(ctx, new_name))) {
++        errno = EINVAL;
++        return -1;
++    }
++
+     odirfd = local_opendir_nofollow(ctx, olddir->data);
+     if (odirfd == -1) {
+         return -1;
+@@ -1202,6 +1250,12 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
+     int ret;
+     int dirfd;
++    if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
++        local_is_mapped_file_metadata(ctx, name)) {
++        errno = EINVAL;
++        return -1;
++    }
++
+     dirfd = local_opendir_nofollow(ctx, dir->data);
+     if (dirfd == -1) {
+         return -1;
+-- 
+2.11.0
+
index e6fe8a7b6e7a1ec114b40862e839236570fc9dec..07b852e901c34fe41ffbb8b0f9541fd40cc8c19a 100644 (file)
@@ -47,3 +47,18 @@ pve/0046-convert-savevm-async-to-threads.patch
 pve/0047-glusterfs-allow-partial-reads.patch
 pve/0048-vma-don-t-use-O_DIRECT-on-pipes.patch
 pve/0049-block-zeroinit-request-child-permissions.patch
+extra/0001-Revert-target-i386-disable-LINT0-after-reset.patch
+extra/0002-qemu-img-wait-for-convert-coroutines-to-complete.patch
+extra/0003-block-Do-not-unref-bs-file-on-error-in-BD-s-open.patch
+extra/0004-9pfs-local-fix-unlink-of-alien-files-in-mapped-file-.patch
+extra/0005-blockdev-use-drained_begin-end-for-qmp_block_resize.patch
+extra/0006-aio-add-missing-aio_notify-to-aio_enable_external.patch
+extra/0007-virtio-serial-bus-Unset-hotplug-handler-when-unreali.patch
+extra/0008-virtio-serial-fix-segfault-on-disconnect.patch
+extra/0009-e1000e-Fix-ICR-Other-causes-clear-logic.patch
+extra/0010-mirror-Drop-permissions-on-s-target-on-completion.patch
+extra/0011-vmw_pvscsi-check-message-ring-page-count-at-initiali.patch
+extra/0012-audio-release-capture-buffers.patch
+extra/0013-input-limit-kbd-queue-depth.patch
+extra/0014-scsi-avoid-an-off-by-one-error-in-megasas_mmio_write.patch
+extra/0015-9pfs-local-forbid-client-access-to-metadata-CVE-2017.patch