From 90a6d95729f4d84d48c63111017827604c86bbc9 Mon Sep 17 00:00:00 2001 From: Wolfgang Bumiller Date: Tue, 6 Jun 2017 13:22:50 +0200 Subject: [PATCH] merge various stable fixes --- ...arget-i386-disable-LINT0-after-reset.patch | 33 ++++ ...t-for-convert-coroutines-to-complete.patch | 98 ++++++++++ ...-unref-bs-file-on-error-in-BD-s-open.patch | 78 ++++++++ ...nlink-of-alien-files-in-mapped-file-.patch | 103 +++++++++++ ...ained_begin-end-for-qmp_block_resize.patch | 44 +++++ ...ng-aio_notify-to-aio_enable_external.patch | 71 +++++++ ...s-Unset-hotplug-handler-when-unreali.patch | 42 +++++ ...io-serial-fix-segfault-on-disconnect.patch | 74 ++++++++ ...00e-Fix-ICR-Other-causes-clear-logic.patch | 96 ++++++++++ ...ermissions-on-s-target-on-completion.patch | 57 ++++++ ...-message-ring-page-count-at-initiali.patch | 34 ++++ .../0012-audio-release-capture-buffers.patch | 38 ++++ .../0013-input-limit-kbd-queue-depth.patch | 90 +++++++++ ...f-by-one-error-in-megasas_mmio_write.patch | 45 +++++ ...d-client-access-to-metadata-CVE-2017.patch | 175 ++++++++++++++++++ debian/patches/series | 15 ++ 16 files changed, 1093 insertions(+) create mode 100644 debian/patches/extra/0001-Revert-target-i386-disable-LINT0-after-reset.patch create mode 100644 debian/patches/extra/0002-qemu-img-wait-for-convert-coroutines-to-complete.patch create mode 100644 debian/patches/extra/0003-block-Do-not-unref-bs-file-on-error-in-BD-s-open.patch create mode 100644 debian/patches/extra/0004-9pfs-local-fix-unlink-of-alien-files-in-mapped-file-.patch create mode 100644 debian/patches/extra/0005-blockdev-use-drained_begin-end-for-qmp_block_resize.patch create mode 100644 debian/patches/extra/0006-aio-add-missing-aio_notify-to-aio_enable_external.patch create mode 100644 debian/patches/extra/0007-virtio-serial-bus-Unset-hotplug-handler-when-unreali.patch create mode 100644 debian/patches/extra/0008-virtio-serial-fix-segfault-on-disconnect.patch create mode 100644 debian/patches/extra/0009-e1000e-Fix-ICR-Other-causes-clear-logic.patch create mode 100644 debian/patches/extra/0010-mirror-Drop-permissions-on-s-target-on-completion.patch create mode 100644 debian/patches/extra/0011-vmw_pvscsi-check-message-ring-page-count-at-initiali.patch create mode 100644 debian/patches/extra/0012-audio-release-capture-buffers.patch create mode 100644 debian/patches/extra/0013-input-limit-kbd-queue-depth.patch create mode 100644 debian/patches/extra/0014-scsi-avoid-an-off-by-one-error-in-megasas_mmio_write.patch create mode 100644 debian/patches/extra/0015-9pfs-local-forbid-client-access-to-metadata-CVE-2017.patch 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 index 0000000..1a11c4a --- /dev/null +++ b/debian/patches/extra/0001-Revert-target-i386-disable-LINT0-after-reset.patch @@ -0,0 +1,33 @@ +From 12949af5b296e6a5717df5189647559cc35677a4 Mon Sep 17 00:00:00 2001 +From: Wolfgang Bumiller +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 index 0000000..ecb3a3b --- /dev/null +++ b/debian/patches/extra/0002-qemu-img-wait-for-convert-coroutines-to-complete.patch @@ -0,0 +1,98 @@ +From 40bb673c38565bb8660f15f088a85bb0fd12ab82 Mon Sep 17 00:00:00 2001 +From: Anton Nefedov +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 +Reviewed-by: Peter Lieven +Signed-off-by: Kevin Wolf +--- + 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 index 0000000..5ed70b6 --- /dev/null +++ b/debian/patches/extra/0003-block-Do-not-unref-bs-file-on-error-in-BD-s-open.patch @@ -0,0 +1,78 @@ +From 7abd8d3ceb29140469c3662fb53de6a4dfe4623e Mon Sep 17 00:00:00 2001 +From: Max Reitz +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 +Signed-off-by: Max Reitz +Reviewed-by: Eric Blake +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Kevin Wolf +--- + 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 index 0000000..1d1a4dd --- /dev/null +++ b/debian/patches/extra/0004-9pfs-local-fix-unlink-of-alien-files-in-mapped-file-.patch @@ -0,0 +1,103 @@ +From 575b9657b84e7c35d4a378448cdb43939fb5e730 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Eric Blake +[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 index 0000000..eca386c --- /dev/null +++ b/debian/patches/extra/0005-blockdev-use-drained_begin-end-for-qmp_block_resize.patch @@ -0,0 +1,44 @@ +From a2486a266d8df715349ec0e325d0bedc0bdc0557 Mon Sep 17 00:00:00 2001 +From: John Snow +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 +Signed-off-by: John Snow +Reviewed-by: Eric Blake +Reviewed-by: Paolo Bonzini +Signed-off-by: Kevin Wolf +--- + 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 index 0000000..02dd110 --- /dev/null +++ b/debian/patches/extra/0006-aio-add-missing-aio_notify-to-aio_enable_external.patch @@ -0,0 +1,71 @@ +From c9d7fd0fd5736afd1f6c508f2b5f1ae0608847bd Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +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 +Reviewed-by: Fam Zheng +Signed-off-by: Stefan Hajnoczi +Message-id: 20170508180705.20609-1-stefanha@redhat.com +Suggested-by: Fam Zheng +Signed-off-by: Stefan Hajnoczi +--- + 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 index 0000000..a695a66 --- /dev/null +++ b/debian/patches/extra/0007-virtio-serial-bus-Unset-hotplug-handler-when-unreali.patch @@ -0,0 +1,42 @@ +From 48c670e522857fa54207794d3dfc014b4809079c Mon Sep 17 00:00:00 2001 +From: Ladi Prosek +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 +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Paolo Bonzini +Reviewed-by: Fam Zheng +--- + 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 index 0000000..ebe63f7 --- /dev/null +++ b/debian/patches/extra/0008-virtio-serial-fix-segfault-on-disconnect.patch @@ -0,0 +1,74 @@ +From 129083526210432c2233874be45e47a61c405db0 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +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=, callback=, user_data=) 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=) at util/main-loop.c:261 + #9 0x0000555555b34353 in main_loop_wait (nonblocking=) at util/main-loop.c:517 + #10 0x0000555555773207 in main_loop () at vl.c:1917 + #11 0x0000555555773207 in main (argc=, argv=, envp=) 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 +Reported-by: Min Deng +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +--- + 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 index 0000000..cbc05bf --- /dev/null +++ b/debian/patches/extra/0009-e1000e-Fix-ICR-Other-causes-clear-logic.patch @@ -0,0 +1,96 @@ +From 1b050be441ffab9c4babec630bbdd14f14c95022 Mon Sep 17 00:00:00 2001 +From: Sameeh Jubran +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 +Signed-off-by: Jason Wang +--- + 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 index 0000000..365bd69 --- /dev/null +++ b/debian/patches/extra/0010-mirror-Drop-permissions-on-s-target-on-completion.patch @@ -0,0 +1,57 @@ +From 95166cdeaeaa9d00330483988b818abfcc473efe Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +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 +Acked-by: Paolo Bonzini +Reviewed-by: Max Reitz +--- + 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 index 0000000..d208624 --- /dev/null +++ b/debian/patches/extra/0011-vmw_pvscsi-check-message-ring-page-count-at-initiali.patch @@ -0,0 +1,34 @@ +From d2eb933639fa12bfa36238c72b1c5a8fb59bdfcd Mon Sep 17 00:00:00 2001 +From: P J P +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 +Signed-off-by: P J P +Message-Id: <20170425130623.3649-1-ppandit@redhat.com> +Reviewed-by: Dmitry Fleytman +Signed-off-by: Paolo Bonzini +--- + 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 index 0000000..5ca0bf5 --- /dev/null +++ b/debian/patches/extra/0012-audio-release-capture-buffers.patch @@ -0,0 +1,38 @@ +From 56ca431e96a6aadffdccecb882600dc780f13ad9 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +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 +Cc: Huawei PSIRT +Reported-by: "Jiangxin (hunter, SCC)" +Signed-off-by: Gerd Hoffmann +Reviewed-by: Prasad J Pandit +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 index 0000000..ce02632 --- /dev/null +++ b/debian/patches/extra/0013-input-limit-kbd-queue-depth.patch @@ -0,0 +1,90 @@ +From e4f39e928710d19db0a0669b66520236197352aa Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +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 +Cc: Huawei PSIRT +Reported-by: jiangxin1@huawei.com +Signed-off-by: Gerd Hoffmann +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 index 0000000..277ecb3 --- /dev/null +++ b/debian/patches/extra/0014-scsi-avoid-an-off-by-one-error-in-megasas_mmio_write.patch @@ -0,0 +1,45 @@ +From 3bf1e29359a1e22a2ecdffb50f124db275abf5bd Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +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 +Signed-off-by: Prasad J Pandit +Message-Id: <20170424120634.12268-1-ppandit@redhat.com> +Signed-off-by: Paolo Bonzini +--- + 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 index 0000000..6a82e91 --- /dev/null +++ b/debian/patches/extra/0015-9pfs-local-forbid-client-access-to-metadata-CVE-2017.patch @@ -0,0 +1,175 @@ +From 6364ef68ee01ec566617ffa6982a8d551cec0f75 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Signed-off-by: Greg Kurz +Reviewed-by: Eric Blake +--- + 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 + diff --git a/debian/patches/series b/debian/patches/series index e6fe8a7..07b852e 100644 --- a/debian/patches/series +++ b/debian/patches/series @@ -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 -- 2.39.2