merge various stable fixes
This commit is contained in:
		
							parent
							
								
									f185a9695e
								
							
						
					
					
						commit
						90a6d95729
					
				
							
								
								
									
										33
									
								
								debian/patches/extra/0001-Revert-target-i386-disable-LINT0-after-reset.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										33
									
								
								debian/patches/extra/0001-Revert-target-i386-disable-LINT0-after-reset.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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 | ||||
| 
 | ||||
							
								
								
									
										98
									
								
								debian/patches/extra/0002-qemu-img-wait-for-convert-coroutines-to-complete.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										98
									
								
								debian/patches/extra/0002-qemu-img-wait-for-convert-coroutines-to-complete.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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 | ||||
| 
 | ||||
							
								
								
									
										78
									
								
								debian/patches/extra/0003-block-Do-not-unref-bs-file-on-error-in-BD-s-open.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										78
									
								
								debian/patches/extra/0003-block-Do-not-unref-bs-file-on-error-in-BD-s-open.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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 | ||||
| 
 | ||||
							
								
								
									
										103
									
								
								debian/patches/extra/0004-9pfs-local-fix-unlink-of-alien-files-in-mapped-file-.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										103
									
								
								debian/patches/extra/0004-9pfs-local-fix-unlink-of-alien-files-in-mapped-file-.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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 | ||||
| 
 | ||||
							
								
								
									
										44
									
								
								debian/patches/extra/0005-blockdev-use-drained_begin-end-for-qmp_block_resize.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										44
									
								
								debian/patches/extra/0005-blockdev-use-drained_begin-end-for-qmp_block_resize.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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 | ||||
| 
 | ||||
							
								
								
									
										71
									
								
								debian/patches/extra/0006-aio-add-missing-aio_notify-to-aio_enable_external.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										71
									
								
								debian/patches/extra/0006-aio-add-missing-aio_notify-to-aio_enable_external.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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 | ||||
| 
 | ||||
							
								
								
									
										42
									
								
								debian/patches/extra/0007-virtio-serial-bus-Unset-hotplug-handler-when-unreali.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										42
									
								
								debian/patches/extra/0007-virtio-serial-bus-Unset-hotplug-handler-when-unreali.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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 | ||||
| 
 | ||||
							
								
								
									
										74
									
								
								debian/patches/extra/0008-virtio-serial-fix-segfault-on-disconnect.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										74
									
								
								debian/patches/extra/0008-virtio-serial-fix-segfault-on-disconnect.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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 | ||||
| 
 | ||||
							
								
								
									
										96
									
								
								debian/patches/extra/0009-e1000e-Fix-ICR-Other-causes-clear-logic.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										96
									
								
								debian/patches/extra/0009-e1000e-Fix-ICR-Other-causes-clear-logic.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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 | ||||
| 
 | ||||
							
								
								
									
										57
									
								
								debian/patches/extra/0010-mirror-Drop-permissions-on-s-target-on-completion.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										57
									
								
								debian/patches/extra/0010-mirror-Drop-permissions-on-s-target-on-completion.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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 | ||||
| 
 | ||||
							
								
								
									
										34
									
								
								debian/patches/extra/0011-vmw_pvscsi-check-message-ring-page-count-at-initiali.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										34
									
								
								debian/patches/extra/0011-vmw_pvscsi-check-message-ring-page-count-at-initiali.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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 | ||||
| 
 | ||||
							
								
								
									
										38
									
								
								debian/patches/extra/0012-audio-release-capture-buffers.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										38
									
								
								debian/patches/extra/0012-audio-release-capture-buffers.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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 | ||||
| 
 | ||||
							
								
								
									
										90
									
								
								debian/patches/extra/0013-input-limit-kbd-queue-depth.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										90
									
								
								debian/patches/extra/0013-input-limit-kbd-queue-depth.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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 | ||||
| 
 | ||||
							
								
								
									
										45
									
								
								debian/patches/extra/0014-scsi-avoid-an-off-by-one-error-in-megasas_mmio_write.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										45
									
								
								debian/patches/extra/0014-scsi-avoid-an-off-by-one-error-in-megasas_mmio_write.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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 | ||||
| 
 | ||||
							
								
								
									
										175
									
								
								debian/patches/extra/0015-9pfs-local-forbid-client-access-to-metadata-CVE-2017.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										175
									
								
								debian/patches/extra/0015-9pfs-local-forbid-client-access-to-metadata-CVE-2017.patch
									
									
									
									
										vendored
									
									
										Normal file
									
								
							| @ -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 | ||||
| 
 | ||||
							
								
								
									
										15
									
								
								debian/patches/series
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										15
									
								
								debian/patches/series
									
									
									
									
										vendored
									
									
								
							| @ -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 | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Wolfgang Bumiller
						Wolfgang Bumiller