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/0047-glusterfs-allow-partial-reads.patch | ||||||
| pve/0048-vma-don-t-use-O_DIRECT-on-pipes.patch | pve/0048-vma-don-t-use-O_DIRECT-on-pipes.patch | ||||||
| pve/0049-block-zeroinit-request-child-permissions.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