[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

RFH: review and test qemu packages (was: qemu in jessie)



El 30/06/18 a las 17:51, Guido Günther escribió:
> On Sat, Jun 30, 2018 at 05:42:37PM +0200, Santiago R.R. wrote:
> > Dear security team,
> > 
> > I am working on the jessie package of qemu (the first time I work on
> > it), and I notice it hasn't been updated in jessie since May 2017.
> > There were various stretch updates since then, and I wonder if the
> > reason why jessie wasn't updated was mainly lack of time/resources, or
> > is there anything else I should be aware of (and I am missing in the
> > doc)?
> 
> Please look at what was done for the wheezy package. I backported some
> drivers from newer QEMU versions (cirrus, 9pfs) and this is needed in
> Jessie as well for further security updates to make sense. If there's no
> rush I can also take a look.

Thanks Guido for the offer. If it is still valid, could you please
review the attached debdiff?
I had indeed taken into account what was done on wheezy, and also the
patches from stretch and ubuntu.

For the moment, I have tested simple uses cases (creating images,
installing a system, accessing them via vnc…), and I will do more later.

For this release, that would fix a large number of CVEs, I find it
particularly helpful to have some feedback. As usual, test packages are
available at:

    deb https://people.debian.org/~santiago/debian santiago-jessie-security/
    deb-src https://people.debian.org/~santiago/debian santiago-jessie-security

Cheers,

Santiago

P.S. I still have to address CVE-2018-5683 and CVE-2018-7550, but I
prefer to publish the current state. I will send the new debdiff and
publish an updated version of the packages in a couple of days.
diff -Nru qemu-2.1+dfsg/debian/changelog qemu-2.1+dfsg/debian/changelog
--- qemu-2.1+dfsg/debian/changelog	2016-05-08 15:35:16.000000000 +0200
+++ qemu-2.1+dfsg/debian/changelog	2018-07-29 15:33:43.000000000 +0200
@@ -1,3 +1,99 @@
+qemu (1:2.1+dfsg-12+deb8u7~4.gbpf05699) UNRELEASED; urgency=medium
+
+  ** SNAPSHOT build @f05699642f8998227d18299f710abc06227b6b76 **
+
+  * Non-maintainer upload by the LTS Team.
+  * Add CVE-2016-2198-usb-ehci-add-capability-mmio-write-function.patch
+    (Closes: #813193)
+  * Add CVE-2016-6833-vmxnet3-check-for-device_active-before-write.patch
+    (Closes: #834904)
+  * Add CVE-2016-6835-net-vmxnet-check-IP-header-length.patch
+    (Closes: #835031)
+  * Add CVE-2016-9603-cirrus-vnc-zap-bitblit-support-from-console-code.patch
+    (Closes: #857744)
+  * Add CVE-2016-8576-fix-infinite-loop.patch
+  * CVE-2016-8667: dma: rc4030 divide by zero error in set_next_tick allowing
+    local guest OS administrators to cause a DoS via a large interval timer
+    reload value.
+    (Closes: #840950)
+  * CVE-2016-8669: char: divide by zero error in serial_update_parameters
+    (Closes: #840945)
+  * CVE-2016-9602: 9p: virtfs allows guest to access host filesystem
+    (Closes: #853006)
+  * CVE-2016-9776: net: mcf_fec: infinite loop while receiving data in
+    mcf_fec_receive
+  * CVE-2016-9907: usb: redirector: memory leakage when destroying redirector
+    (Closes: #847953)
+  * CVE-2016-9911: usb: ehci: memory leakage in ehci_init_transfer
+    (Closes: #847951)
+  * CVE-2016-9914: 9pfs: add missing cleanup operation in FileOperations
+    (Closes: #847496)
+  * CVE-2016-9915: 9pfs: add missing cleanup operation in the handle backend.
+  * CVE-2016-9916: 9pfs: add missing cleanup operation in the proxy backend
+    driver
+  * CVE-2016-9921, CVE-2016-9922: display: cirrus_vga: a divide by zero in
+    cirrus_do_copy
+    (Closes: #847960)
+  * CVE-2016-10155: Memory leak in hw/watchdog/wdt_i6300esb.c allowing local
+    guest OS privileged users to cause a denial of service (host memory
+    consumption and QEMU process crash) via a large number of device unplug
+    operations.
+    (Closes: #852232)
+  * CVE-2017-2615: cirrus: out-of-bounds access issue
+  * Add CVE-2017-2620-cirrus-add-blit_is_unsafe-call-to-cirrus_bi.patch
+  * CVE-2017-5525: memory leakage in ac97 device
+  * CVE-2017-5526: memory leakage in es1370 device (Closes: #851910)
+  * CVE-2017-5579: serial: host memory leakage 16550A UART emulation
+    (Closes: #853002)
+  * CVE-2017-5667: sd: sdhci: check data length during dma_memory_read
+    (Closes: #853996)
+  * CVE-2017-5715: mitigations against the Spectre v2 vulnerability.
+    (Closes: #886532)
+  * CVE-2017-5856: Memory leak in the megasas_handle_dcmd function in
+    hw/scsi/megasas.cc
+    (Closes: #853996)
+  * CVE-2017-5987: sd: infinite loop issue in multi block transfers
+  * CVE-2017-5973: infinite loop while doing control transfer in xhci_kick_epctx
+  * CVE-2017-6505: infinite loop issue in ohci_service_ed_list
+  * CVE-2017-7377: 9pfs: host memory leakage via v9fs_create
+  * CVE-2017-7471: improper access control issue
+  * CVE-2017-7493: 9pfs access control issue
+  * CVE-2017-7718: cirrus out-of-bounds access issue
+  * CVE-2017-7980: cirrus: heap-based buffer overflow
+  * CVE-2017-8086: 9pfs: host memory leakage via v9pfs_list_xattr
+  * CVE-2017-8112: vmw_pvscsi: infinite loop in pvscsi_log2 (Closes: #861351)
+  * CVE-2017-8309: audio: host memory leakage via capture buffer
+  * CVE-2017-8379: input: host memory lekage via keyboard
+  * CVE-2017-9330: usb: ohci: infinite loop due to incorrect return value
+  * CVE-2017-9373 ide: ahci host memory leakage during hotunplug.
+    CVE-2017-9374: usb: ehci host memory leakage during hotunplug
+    (Closes: #864216, #864568)
+  * CVE-2017-9503: megasas: null pointer dereference while processing megasas
+    command
+    (Closes: 865754)
+  * CVE-2017-10664: qemu-nbd: server breaks with SIGPIPE upon client abort
+    (Closes: #866674)
+  * CVE-2017-10806: usb-redirect: stack buffer overflow in debug logging
+    (Closes: #867751)
+  * Add xen-disk-don-t-leak-stack-data-via-response-ring-CVE-2017-10911.patch
+    (Closes: #869706)
+  * CVE-2017-11434: slirp: out-of-bounds read while parsing dhcp options
+    (Closes: #869171)
+  * CVE-2017-14167: i386: multiboot OOB access while loading guest kernel
+    image
+    (Closes: #874606)
+  * CVE-2017-15038: 9p: virtfs: information disclosure when reading extended
+    attributes
+    (Closes: #877890)
+  * CVE-2017-15289: cirrus: OOB access issue in mode4and5 write functions
+    (Closes: #880832)
+  * CVE-2017-16845: ps2: information leakage via post_load routine
+    (Closes: #882136)
+  * CVE-2017-18030: cirrus out-of-bounds array access
+  * CVE-2017-18043: Integer overflow in the macro ROUND_UP (n, d)
+
+ -- Santiago R.R. <santiagorr@riseup.net>  Sun, 29 Jul 2018 15:33:43 +0200
+
 qemu (1:2.1+dfsg-12+deb8u6) jessie-security; urgency=high
 
   * Non-maintainer upload by the Security Team.
diff -Nru qemu-2.1+dfsg/debian/patches/0001-cirrus-fix-oob-access-issue-CVE-2017-2615.patch qemu-2.1+dfsg/debian/patches/0001-cirrus-fix-oob-access-issue-CVE-2017-2615.patch
--- qemu-2.1+dfsg/debian/patches/0001-cirrus-fix-oob-access-issue-CVE-2017-2615.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/0001-cirrus-fix-oob-access-issue-CVE-2017-2615.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,50 @@
+Origin: backported, https://git.qemu.org/?p=qemu.git;a=commit;h=f054cead44cef75d330cfba39aa0c46be483813d
+Reviewed-by: Santiago R.R. <santiagorr@riseup.net>
+
+From f054cead44cef75d330cfba39aa0c46be483813d Mon Sep 17 00:00:00 2001
+From: Li Qiang <liqiang6-s@360.cn>
+Date: Wed, 1 Feb 2017 09:35:01 +0100
+Subject: [PATCH] cirrus: fix oob access issue (CVE-2017-2615)
+
+When doing bitblt copy in backward mode, we should minus the
+blt width first just like the adding in the forward mode. This
+can avoid the oob access of the front of vga's vram.
+
+Signed-off-by: Li Qiang <liqiang6-s@360.cn>
+
+{ kraxel: with backward blits (negative pitch) addr is the topmost
+          address, so check it as-is against vram size ]
+
+Cc: qemu-stable@nongnu.org
+Cc: P J P <ppandit@redhat.com>
+Cc: Laszlo Ersek <lersek@redhat.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Fixes: d3532a0db02296e687711b8cdc7791924efccea0 (CVE-2014-8106)
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: 1485938101-26602-1-git-send-email-kraxel@redhat.com
+Reviewed-by: Laszlo Ersek <lersek@redhat.com>
+(cherry picked from commit 62d4c6bd5263bb8413a06c80144fc678df6dfb64)
+Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
+---
+ hw/display/cirrus_vga.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+Index: qemu/hw/display/cirrus_vga.c
+===================================================================
+--- qemu.orig/hw/display/cirrus_vga.c
++++ qemu/hw/display/cirrus_vga.c
+@@ -272,10 +272,9 @@ static bool blit_region_is_unsafe(struct
+     }
+     if (pitch < 0) {
+         int64_t min = addr
+-            + ((int64_t)s->cirrus_blt_height-1) * pitch;
+-        int32_t max = addr
+-            + s->cirrus_blt_width;
+-        if (min < 0 || max >= s->vga.vram_size) {
++            + ((int64_t)s->cirrus_blt_height - 1) * pitch
++            - s->cirrus_blt_width;
++        if (min < -1 || addr >= s->vga.vram_size) {
+             return true;
+         }
+     } else {
diff -Nru qemu-2.1+dfsg/debian/patches/9pfs-local-forbid-client-access-to-metadata-CVE-2017-7493.patch qemu-2.1+dfsg/debian/patches/9pfs-local-forbid-client-access-to-metadata-CVE-2017-7493.patch
--- qemu-2.1+dfsg/debian/patches/9pfs-local-forbid-client-access-to-metadata-CVE-2017-7493.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/9pfs-local-forbid-client-access-to-metadata-CVE-2017-7493.patch	2018-06-29 21:25:26.000000000 +0200
@@ -0,0 +1,174 @@
+From: Greg Kurz <groug@kaod.org>
+Date: Fri, 5 May 2017 14:48:08 +0200
+Subject: 9pfs: local: forbid client access to metadata (CVE-2017-7493)
+Commit-Id: 7a95434e0ca8a037fd8aa1a2e2461f92585eb77b
+
+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 f3ebca4f7a..a2486566af 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;
+@@ -1096,6 +1131,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, "/")) {
+@@ -1116,6 +1157,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;
+@@ -1206,6 +1254,12 @@ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
+     int ret;
+     int dirfd;
+ 
++    if (ctx->export_flags & V9FS_SM_MAPPED_FILE &&
++        local_is_mapped_file_metadata(ctx, name)) {
++        errno = EINVAL;
++        return -1;
++    }
++
+     dirfd = local_opendir_nofollow(ctx, dir->data);
+     if (dirfd == -1) {
+         return -1;
+-- 
+2.11.0
+
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-10155.patch qemu-2.1+dfsg/debian/patches/CVE-2016-10155.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-10155.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-10155.patch	2018-07-24 11:52:34.000000000 +0200
@@ -0,0 +1,35 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by: Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 852232
+
+Backport of:
+
+From eb7a20a3616085d46aa6b4b4224e15587ec67e6e Mon Sep 17 00:00:00 2001
+From: Li Qiang <liqiang6-s@360.cn>
+Date: Mon, 28 Nov 2016 17:49:04 -0800
+Subject: [PATCH] watchdog: 6300esb: add exit function
+
+When the Intel 6300ESB watchdog is hot unplug. The timer allocated
+in realize isn't freed thus leaking memory leak. This patch avoid
+this through adding the exit function.
+
+Signed-off-by: Li Qiang <liqiang6-s@360.cn>
+Message-Id: <583cde9c.3223ed0a.7f0c2.886e@mx.google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/watchdog/wdt_i6300esb.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+Index: qemu-2.0.0+dfsg/hw/watchdog/wdt_i6300esb.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/watchdog/wdt_i6300esb.c	2017-04-06 09:50:33.025128615 -0400
++++ qemu-2.0.0+dfsg/hw/watchdog/wdt_i6300esb.c	2017-04-06 09:52:51.550860890 -0400
+@@ -430,6 +430,8 @@
+     I6300State *d = DO_UPCAST(I6300State, dev, dev);
+ 
+     memory_region_destroy(&d->io_mem);
++    timer_del(d->timer);
++    timer_free(d->timer);
+ }
+ 
+ static WatchdogTimerModel model = {
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-2198-usb-ehci-add-capability-mmio-write-function.patch qemu-2.1+dfsg/debian/patches/CVE-2016-2198-usb-ehci-add-capability-mmio-write-function.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-2198-usb-ehci-add-capability-mmio-write-function.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-2198-usb-ehci-add-capability-mmio-write-function.patch	2018-06-28 16:15:31.000000000 +0200
@@ -0,0 +1,43 @@
+From dff0367cf66f489aa772320fa2937a8cac1ca30d Mon Sep 17 00:00:00 2001
+From: Prasad J Pandit <pjp@fedoraproject.org>
+Date: Fri, 29 Jan 2016 18:30:34 +0530
+Subject: [PATCH] usb: ehci: add capability mmio write function
+
+USB Ehci emulation supports host controller capability registers.
+But its mmio '.write' function was missing, which lead to a null
+pointer dereference issue. Add a do nothing 'ehci_caps_write'
+definition to avoid it; Do nothing because capability registers
+are Read Only(RO).
+
+Reported-by: Zuozhi Fzz <zuozhi.fzz@alibaba-inc.com>
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Message-id: 1454072434-16045-1-git-send-email-ppandit@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/usb/hcd-ehci.c | 6 ++++++
+ 1 file changed, 6 insertions(+)
+
+Index: qemu/hw/usb/hcd-ehci.c
+===================================================================
+--- qemu.orig/hw/usb/hcd-ehci.c
++++ qemu/hw/usb/hcd-ehci.c
+@@ -899,6 +899,11 @@ static uint64_t ehci_caps_read(void *ptr
+     return s->caps[addr];
+ }
+ 
++static void ehci_caps_write(void *ptr, hwaddr addr,
++                             uint64_t val, unsigned size)
++{
++}
++
+ static uint64_t ehci_opreg_read(void *ptr, hwaddr addr,
+                                 unsigned size)
+ {
+@@ -2317,6 +2322,7 @@ static void ehci_frame_timer(void *opaqu
+ 
+ static const MemoryRegionOps ehci_mmio_caps_ops = {
+     .read = ehci_caps_read,
++    .write = ehci_caps_write,
+     .valid.min_access_size = 1,
+     .valid.max_access_size = 4,
+     .impl.min_access_size = 1,
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-6833-vmxnet3-check-for-device_active-before-write.patch qemu-2.1+dfsg/debian/patches/CVE-2016-6833-vmxnet3-check-for-device_active-before-write.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-6833-vmxnet3-check-for-device_active-before-write.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-6833-vmxnet3-check-for-device_active-before-write.patch	2018-06-27 19:13:47.000000000 +0200
@@ -0,0 +1,31 @@
+commit 6c352ca9b4ee3e1e286ea9e8434bd8e69ac7d0d8
+Author: Li Qiang <liqiang6-s@360.cn>
+Date:   Mon Aug 8 18:08:31 2016 +0530
+
+    net: vmxnet3: check for device_active before write
+    
+    Vmxnet3 device emulator does not check if the device is active,
+    before using it for write. It leads to a use after free issue,
+    if the vmxnet3_io_bar0_write routine is called after the device is
+    deactivated. Add check to avoid it.
+    
+    Reported-by: Li Qiang <liqiang6-s@360.cn>
+    Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+    Acked-by: Dmitry Fleytman <dmitry@daynix.com>
+    Signed-off-by: Jason Wang <jasowang@redhat.com>
+
+Index: qemu/hw/net/vmxnet3.c
+===================================================================
+--- qemu.orig/hw/net/vmxnet3.c
++++ qemu/hw/net/vmxnet3.c
+@@ -1071,6 +1071,10 @@ vmxnet3_io_bar0_write(void *opaque, hwad
+ {
+     VMXNET3State *s = opaque;
+ 
++    if (!s->device_active) {
++        return;
++    }
++
+     if (VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_TXPROD,
+                         VMXNET3_DEVICE_MAX_TX_QUEUES, VMXNET3_REG_ALIGN)) {
+         int tx_queue_idx =
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-6835-net-vmxnet-check-IP-header-length.patch qemu-2.1+dfsg/debian/patches/CVE-2016-6835-net-vmxnet-check-IP-header-length.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-6835-net-vmxnet-check-IP-header-length.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-6835-net-vmxnet-check-IP-header-length.patch	2018-06-28 13:12:23.000000000 +0200
@@ -0,0 +1,33 @@
+From 93060258ae748573ca7197204125a2670047896d Mon Sep 17 00:00:00 2001
+From: Li Qiang <liqiang6-s@360.cn>
+Date: Tue, 9 Aug 2016 16:49:47 +0530
+Subject: [PATCH] net: vmxnet: check IP header length
+
+Vmxnet3 device emulator when parsing packet headers does not check
+for IP header length. It could lead to a OOB access when reading
+further packet data. Add check to avoid it.
+
+Reported-by: Li Qiang <liqiang6-s@360.cn>
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Reviewed-by: Dmitry Fleytman <dmitry@daynix.com>
+Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
+---
+ hw/net/vmxnet_tx_pkt.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+Index: qemu/hw/net/vmxnet_tx_pkt.c
+===================================================================
+--- qemu.orig/hw/net/vmxnet_tx_pkt.c
++++ qemu/hw/net/vmxnet_tx_pkt.c
+@@ -177,6 +177,11 @@ static bool vmxnet_tx_pkt_parse_headers(
+         }
+ 
+         l3_hdr->iov_len = IP_HDR_GET_LEN(l3_hdr->iov_base);
++        if(l3_hdr->iov_len < sizeof(struct ip_header))
++        {
++            l3_hdr->iov_len = 0;
++            return false;
++        }
+         pkt->l4proto = ((struct ip_header *) l3_hdr->iov_base)->ip_p;
+ 
+         /* copy optional IPv4 header data */
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-8576-fix-infinite-loop.patch qemu-2.1+dfsg/debian/patches/CVE-2016-8576-fix-infinite-loop.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-8576-fix-infinite-loop.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-8576-fix-infinite-loop.patch	2018-07-08 18:03:38.000000000 +0200
@@ -0,0 +1,55 @@
+Description: xhci: limit the number of link trbs we are willing to process
+ Needed to avoid we run in circles forever in case the guest builds
+ an endless loop with link trbs.
+Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=05f43d44e4bc26611ce25fd7d726e483f73363ce
+Bug-Debian: https://bugs.debian.org/840343
+Index: qemu/hw/usb/hcd-xhci.c
+===================================================================
+--- qemu.orig/hw/usb/hcd-xhci.c
++++ qemu/hw/usb/hcd-xhci.c
+@@ -52,6 +52,8 @@
+  * to the specs when it gets them */
+ #define ER_FULL_HACK
+ 
++#define TRB_LINK_LIMIT  4
++
+ #define LEN_CAP         0x40
+ #define LEN_OPER        (0x400 + 0x10 * MAXPORTS)
+ #define LEN_RUNTIME     ((MAXINTRS + 1) * 0x20)
+@@ -994,6 +996,8 @@ static TRBType xhci_ring_fetch(XHCIState
+ {
+     PCIDevice *pci_dev = PCI_DEVICE(xhci);
+ 
++    uint32_t link_cnt = 0;
++
+     while (1) {
+         TRBType type;
+         pci_dma_read(pci_dev, ring->dequeue, trb, TRB_SIZE);
+@@ -1019,6 +1023,9 @@ static TRBType xhci_ring_fetch(XHCIState
+             ring->dequeue += TRB_SIZE;
+             return type;
+         } else {
++            if (++link_cnt > TRB_LINK_LIMIT) {
++                return 0;
++            }
+             ring->dequeue = xhci_mask64(trb->parameter);
+             if (trb->control & TRB_LK_TC) {
+                 ring->ccs = !ring->ccs;
+@@ -1036,6 +1043,7 @@ static int xhci_ring_chain_length(XHCISt
+     bool ccs = ring->ccs;
+     /* hack to bundle together the two/three TDs that make a setup transfer */
+     bool control_td_set = 0;
++    uint32_t link_cnt = 0;
+ 
+     while (1) {
+         TRBType type;
+@@ -1051,6 +1059,9 @@ static int xhci_ring_chain_length(XHCISt
+         type = TRB_TYPE(trb);
+ 
+         if (type == TR_LINK) {
++            if (++link_cnt > TRB_LINK_LIMIT) {
++                return -length;
++            }
+             dequeue = xhci_mask64(trb.parameter);
+             if (trb.control & TRB_LK_TC) {
+                 ccs = !ccs;
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-8667.patch qemu-2.1+dfsg/debian/patches/CVE-2016-8667.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-8667.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-8667.patch	2018-07-24 13:46:16.000000000 +0200
@@ -0,0 +1,39 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by: Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 840950
+
+From c0a3172fa6bbddcc73192f2a2c48d0bf3a7ba61c Mon Sep 17 00:00:00 2001
+From: Prasad J Pandit <pjp@fedoraproject.org>
+Date: Wed, 12 Oct 2016 18:07:41 +0530
+Subject: [PATCH] dma: rc4030: limit interval timer reload value
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf8
+Content-Transfer-Encoding: 8bit
+
+The JAZZ RC4030 chipset emulator has a periodic timer and
+associated interval reload register. The reload value is used
+as divider when computing timer's next tick value. If reload
+value is large, it could lead to divide by zero error. Limit
+the interval reload value to avoid it.
+
+Reported-by: Huawei PSIRT <psirt@huawei.com>
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Tested-by: Hervé Poussineau <hpoussin@reactos.org>
+Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
+---
+ hw/dma/rc4030.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: qemu-2.0.0+dfsg/hw/dma/rc4030.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/dma/rc4030.c	2017-04-05 11:22:52.516941129 -0400
++++ qemu-2.0.0+dfsg/hw/dma/rc4030.c	2017-04-05 11:22:52.512941077 -0400
+@@ -377,7 +377,7 @@
+         break;
+     /* Interval timer reload */
+     case 0x0228:
+-        s->itr = val;
++        s->itr = val & 0x01FF;
+         qemu_irq_lower(s->timer_irq);
+         set_next_tick(s);
+         break;
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-8669.patch qemu-2.1+dfsg/debian/patches/CVE-2016-8669.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-8669.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-8669.patch	2018-07-24 14:00:51.000000000 +0200
@@ -0,0 +1,38 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by: Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 840945
+
+From 3592fe0c919cf27a81d8e9f9b4f269553418bb01 Mon Sep 17 00:00:00 2001
+From: Prasad J Pandit <pjp@fedoraproject.org>
+Date: Wed, 12 Oct 2016 11:28:08 +0530
+Subject: [PATCH] char: serial: check divider value against baud base
+
+16550A UART device uses an oscillator to generate frequencies
+(baud base), which decide communication speed. This speed could
+be changed by dividing it by a divider. If the divider is
+greater than the baud base, speed is set to zero, leading to a
+divide by zero error. Add check to avoid it.
+
+Reported-by: Huawei PSIRT <psirt@huawei.com>
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Message-Id: <1476251888-20238-1-git-send-email-ppandit@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/char/serial.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+Index: qemu-2.5+dfsg/hw/char/serial.c
+===================================================================
+--- qemu-2.5+dfsg.orig/hw/char/serial.c	2017-04-04 13:50:18.820499175 -0400
++++ qemu-2.5+dfsg/hw/char/serial.c	2017-04-04 13:50:18.820499175 -0400
+@@ -150,8 +150,9 @@
+     int speed, parity, data_bits, stop_bits, frame_size;
+     QEMUSerialSetParams ssp;
+ 
+-    if (s->divider == 0)
++    if (s->divider == 0 || s->divider > s->baudbase) {
+         return;
++    }
+ 
+     /* Start bit. */
+     frame_size = 1;
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-10.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-10.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-10.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-10.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,167 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From 72f0d0bf51362011c4d841a89fb8f5cfb16e0bf3 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:42:51 +0100
+Subject: [PATCH] 9pfs: local: lremovexattr: don't follow symlinks
+
+The local_lremovexattr() callback is vulnerable to symlink attacks because
+it calls lremovexattr() which follows symbolic links in all path elements
+but the rightmost one.
+
+This patch introduces a helper to emulate the non-existing fremovexattrat()
+function: it is implemented with /proc/self/fd which provides a trusted
+path that can be safely passed to lremovexattr().
+
+local_lremovexattr() is converted to use this helper and opendir_nofollow().
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-posix-acl.c  | 10 ++--------
+ hw/9pfs/9p-xattr-user.c |  8 +-------
+ hw/9pfs/9p-xattr.c      | 36 +++++++++++++++++++++++++++++++-----
+ hw/9pfs/9p-xattr.h      |  2 ++
+ 4 files changed, 36 insertions(+), 20 deletions(-)
+
+Index: qemu-2.5+dfsg/hw/9pfs/virtio-9p-posix-acl.c
+===================================================================
+--- qemu-2.5+dfsg.orig/hw/9pfs/virtio-9p-posix-acl.c	2017-04-04 14:03:50.582929034 -0400
++++ qemu-2.5+dfsg/hw/9pfs/virtio-9p-posix-acl.c	2017-04-04 14:03:50.578928983 -0400
+@@ -59,10 +59,8 @@
+                                const char *path, const char *name)
+ {
+     int ret;
+-    char *buffer;
+ 
+-    buffer = rpath(ctx, path);
+-    ret  = lremovexattr(buffer, MAP_ACL_ACCESS);
++    ret = local_removexattr_nofollow(ctx, path, MAP_ACL_ACCESS);
+     if (ret == -1 && errno == ENODATA) {
+         /*
+          * We don't get ENODATA error when trying to remove a
+@@ -72,7 +70,6 @@
+         errno = 0;
+         ret = 0;
+     }
+-    g_free(buffer);
+     return ret;
+ }
+ 
+@@ -112,10 +109,8 @@
+                                const char *path, const char *name)
+ {
+     int ret;
+-    char *buffer;
+ 
+-    buffer = rpath(ctx, path);
+-    ret  = lremovexattr(buffer, MAP_ACL_DEFAULT);
++    ret = local_removexattr_nofollow(ctx, path, MAP_ACL_DEFAULT);
+     if (ret == -1 && errno == ENODATA) {
+         /*
+          * We don't get ENODATA error when trying to remove a
+@@ -125,7 +120,6 @@
+         errno = 0;
+         ret = 0;
+     }
+-    g_free(buffer);
+     return ret;
+ }
+ 
+Index: qemu-2.5+dfsg/hw/9pfs/virtio-9p-xattr-user.c
+===================================================================
+--- qemu-2.5+dfsg.orig/hw/9pfs/virtio-9p-xattr-user.c	2017-04-04 14:03:50.582929034 -0400
++++ qemu-2.5+dfsg/hw/9pfs/virtio-9p-xattr-user.c	2017-04-04 14:03:50.582929034 -0400
+@@ -82,9 +82,6 @@
+ static int mp_user_removexattr(FsContext *ctx,
+                                const char *path, const char *name)
+ {
+-    char *buffer;
+-    int ret;
+-
+     if (strncmp(name, "user.virtfs.", 12) == 0) {
+         /*
+          * Don't allow fetch of user.virtfs namesapce
+@@ -93,10 +90,7 @@
+         errno = EACCES;
+         return -1;
+     }
+-    buffer = rpath(ctx, path);
+-    ret = lremovexattr(buffer, name);
+-    g_free(buffer);
+-    return ret;
++    return local_removexattr_nofollow(ctx, path, name);
+ }
+ 
+ XattrOperations mapped_user_xattr = {
+Index: qemu-2.5+dfsg/hw/9pfs/virtio-9p-xattr.c
+===================================================================
+--- qemu-2.5+dfsg.orig/hw/9pfs/virtio-9p-xattr.c	2017-04-04 14:03:50.582929034 -0400
++++ qemu-2.5+dfsg/hw/9pfs/virtio-9p-xattr.c	2017-04-04 14:03:50.582929034 -0400
+@@ -234,17 +234,43 @@
+     return local_setxattr_nofollow(ctx, path, name, value, size, flags);
+ }
+ 
+-int pt_removexattr(FsContext *ctx, const char *path, const char *name)
++static ssize_t fremovexattrat_nofollow(int dirfd, const char *filename,
++                                       const char *name)
+ {
+-    char *buffer;
++    char *proc_path = g_strdup_printf("/proc/self/fd/%d/%s", dirfd, filename);
+     int ret;
+ 
+-    buffer = rpath(ctx, path);
+-    ret = lremovexattr(path, name);
+-    g_free(buffer);
++    ret = lremovexattr(proc_path, name);
++    g_free(proc_path);
+     return ret;
+ }
+ 
++ssize_t local_removexattr_nofollow(FsContext *ctx, const char *path,
++                                   const char *name)
++{
++    char *dirpath = g_path_get_dirname(path);
++    char *filename = g_path_get_basename(path);
++    int dirfd;
++    ssize_t ret = -1;
++
++    dirfd = local_opendir_nofollow(ctx, dirpath);
++    if (dirfd == -1) {
++        goto out;
++    }
++
++    ret = fremovexattrat_nofollow(dirfd, filename, name);
++    close_preserve_errno(dirfd);
++out:
++    g_free(dirpath);
++    g_free(filename);
++    return ret;
++}
++
++int pt_removexattr(FsContext *ctx, const char *path, const char *name)
++{
++    return local_removexattr_nofollow(ctx, path, name);
++}
++
+ ssize_t notsup_getxattr(FsContext *ctx, const char *path, const char *name,
+                         void *value, size_t size)
+ {
+Index: qemu-2.5+dfsg/hw/9pfs/virtio-9p-xattr.h
+===================================================================
+--- qemu-2.5+dfsg.orig/hw/9pfs/virtio-9p-xattr.h	2017-04-04 14:03:50.582929034 -0400
++++ qemu-2.5+dfsg/hw/9pfs/virtio-9p-xattr.h	2017-04-04 14:03:50.582929034 -0400
+@@ -33,6 +33,8 @@
+ ssize_t local_setxattr_nofollow(FsContext *ctx, const char *path,
+                                 const char *name, void *value, size_t size,
+                                 int flags);
++ssize_t local_removexattr_nofollow(FsContext *ctx, const char *path,
++                                   const char *name);
+ 
+ extern XattrOperations mapped_user_xattr;
+ extern XattrOperations passthrough_user_xattr;
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-11.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-11.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-11.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-11.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,150 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From df4938a6651b1f980018f9eaf86af43e6b9d7fed Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:43:00 +0100
+Subject: [PATCH] 9pfs: local: unlinkat: don't follow symlinks
+
+The local_unlinkat() callback is vulnerable to symlink attacks because it
+calls remove() which follows symbolic links in all path elements but the
+rightmost one.
+
+This patch converts local_unlinkat() to rely on opendir_nofollow() and
+unlinkat() instead.
+
+Most of the code is moved to a separate local_unlinkat_common() helper
+which will be reused in a subsequent patch to fix the same issue in
+local_remove().
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 99 ++++++++++++++++++++++++++++++------------------------
+ 1 file changed, 56 insertions(+), 43 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:32:33.340403789 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:32:33.336403738 -0400
+@@ -981,6 +981,56 @@
+     return ret;
+ }
+ 
++static int local_unlinkat_common(FsContext *ctx, int dirfd, const char *name,
++                                 int flags)
++{
++    int ret = -1;
++
++    if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
++        int map_dirfd;
++
++        if (flags == AT_REMOVEDIR) {
++            int fd;
++
++            fd = openat(dirfd, name, O_RDONLY | O_DIRECTORY | O_PATH);
++            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.
++             */
++            goto err_out;
++        }
++    }
++
++    ret = unlinkat(dirfd, name, flags);
++err_out:
++    return ret;
++}
++
+ static int local_remove(FsContext *ctx, const char *path)
+ {
+     int err;
+@@ -1133,52 +1183,15 @@
+                           const char *name, int flags)
+ {
+     int ret;
+-    V9fsString fullname;
+-    char *buffer;
++    int dirfd;
+ 
+-    v9fs_string_init(&fullname);
+-
+-    v9fs_string_sprintf(&fullname, "%s/%s", dir->data, name);
+-    if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+-        if (flags == AT_REMOVEDIR) {
+-            /*
+-             * If directory remove .virtfs_metadata contained in the
+-             * directory
+-             */
+-            buffer = g_strdup_printf("%s/%s/%s", ctx->fs_root,
+-                                     fullname.data, VIRTFS_META_DIR);
+-            ret = remove(buffer);
+-            g_free(buffer);
+-            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.
+-         */
+-        buffer = local_mapped_attr_path(ctx, fullname.data);
+-        ret = remove(buffer);
+-        g_free(buffer);
+-        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;
+-        }
++    dirfd = local_opendir_nofollow(ctx, dir->data);
++    if (dirfd == -1) {
++        return -1;
+     }
+-    /* Remove the name finally */
+-    buffer = rpath(ctx, fullname.data);
+-    ret = remove(buffer);
+-    g_free(buffer);
+ 
+-err_out:
+-    v9fs_string_free(&fullname);
++    ret = local_unlinkat_common(ctx, dirfd, name, flags);
++    close_preserve_errno(dirfd);
+     return ret;
+ }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-12.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-12.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-12.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-12.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,109 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From a0e640a87210b1e986bcd4e7f7de03beb3db0a4a Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:43:08 +0100
+Subject: [PATCH] 9pfs: local: remove: don't follow symlinks
+
+The local_remove() callback is vulnerable to symlink attacks because it
+calls:
+
+(1) lstat() which follows symbolic links in all path elements but the
+    rightmost one
+(2) remove() which follows symbolic links in all path elements but the
+    rightmost one
+
+This patch converts local_remove() to rely on opendir_nofollow(),
+fstatat(AT_SYMLINK_NOFOLLOW) to fix (1) and unlinkat() to fix (2).
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 64 ++++++++++++++++++------------------------------------
+ 1 file changed, 21 insertions(+), 43 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:32:42.912526775 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:32:42.912526775 -0400
+@@ -1033,54 +1033,32 @@
+ 
+ static int local_remove(FsContext *ctx, const char *path)
+ {
+-    int err;
+     struct stat stbuf;
+-    char *buffer;
++    char *dirpath = g_path_get_dirname(path);
++    char *name = g_path_get_basename(path);
++    int flags = 0;
++    int dirfd;
++    int err = -1;
+ 
+-    if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+-        buffer = rpath(ctx, path);
+-        err =  lstat(buffer, &stbuf);
+-        g_free(buffer);
+-        if (err) {
+-            goto err_out;
+-        }
+-        /*
+-         * If directory remove .virtfs_metadata contained in the
+-         * directory
+-         */
+-        if (S_ISDIR(stbuf.st_mode)) {
+-            buffer = g_strdup_printf("%s/%s/%s", ctx->fs_root,
+-                                     path, VIRTFS_META_DIR);
+-            err = remove(buffer);
+-            g_free(buffer);
+-            if (err < 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
+-         */
+-        buffer = local_mapped_attr_path(ctx, path);
+-        err = remove(buffer);
+-        g_free(buffer);
+-        if (err < 0 && errno != ENOENT) {
+-            /*
+-             * We didn't had the .virtfs_metadata file. May be file created
+-             * in non-mapped mode ?. Ignore ENOENT.
+-             */
+-            goto err_out;
+-        }
++    dirfd = local_opendir_nofollow(ctx, dirpath);
++    if (dirfd) {
++        goto out;
+     }
+ 
+-    buffer = rpath(ctx, path);
+-    err = remove(buffer);
+-    g_free(buffer);
++    if (fstatat(dirfd, path, &stbuf, AT_SYMLINK_NOFOLLOW) < 0) {
++        goto err_out;
++    }
++
++    if (S_ISDIR(stbuf.st_mode)) {
++        flags |= AT_REMOVEDIR;
++    }
++
++    err = local_unlinkat_common(ctx, dirfd, name, flags);
+ err_out:
++    close_preserve_errno(dirfd);
++out:
++    g_free(name);
++    g_free(dirpath);
+     return err;
+ }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-13.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-13.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-13.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-13.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,59 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From a33eda0dd99e00faa3bacae43d19490bb9500e07 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:43:17 +0100
+Subject: [PATCH] 9pfs: local: utimensat: don't follow symlinks
+
+The local_utimensat() callback is vulnerable to symlink attacks because it
+calls qemu_utimens()->utimensat(AT_SYMLINK_NOFOLLOW) which follows symbolic
+links in all path elements but the rightmost one or qemu_utimens()->utimes()
+which follows symbolic links for all path elements.
+
+This patch converts local_utimensat() to rely on opendir_nofollow() and
+utimensat(AT_SYMLINK_NOFOLLOW) directly instead of using qemu_utimens().
+It is hence assumed that the OS supports utimensat(), i.e. has glibc 2.6
+or higher and linux 2.6.22 or higher, which seems reasonable nowadays.
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 19 +++++++++++++------
+ 1 file changed, 13 insertions(+), 6 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:32:54.092670423 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:32:54.088670370 -0400
+@@ -971,13 +971,20 @@
+ static int local_utimensat(FsContext *s, V9fsPath *fs_path,
+                            const struct timespec *buf)
+ {
+-    char *buffer;
+-    int ret;
+-    char *path = fs_path->data;
++    char *dirpath = g_path_get_dirname(fs_path->data);
++    char *name = g_path_get_basename(fs_path->data);
++    int dirfd, ret = -1;
+ 
+-    buffer = rpath(s, path);
+-    ret = qemu_utimens(buffer, buf);
+-    g_free(buffer);
++    dirfd = local_opendir_nofollow(s, dirpath);
++    if (dirfd == -1) {
++        goto out;
++    }
++
++    ret = utimensat(dirfd, name, buf, AT_SYMLINK_NOFOLLOW);
++    close_preserve_errno(dirfd);
++out:
++    g_free(dirpath);
++    g_free(name);
+     return ret;
+ }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-14.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-14.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-14.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-14.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,46 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From 31e51d1c15b35dc98b88a301812914b70a2b55dc Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:43:25 +0100
+Subject: [PATCH] 9pfs: local: statfs: don't follow symlinks
+
+The local_statfs() callback is vulnerable to symlink attacks because it
+calls statfs() which follows symbolic links in all path elements.
+
+This patch converts local_statfs() to rely on open_nofollow() and fstatfs()
+instead.
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 10 ++++------
+ 1 file changed, 4 insertions(+), 6 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:33:00.680755069 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:33:00.676755017 -0400
+@@ -1089,13 +1089,11 @@
+ 
+ static int local_statfs(FsContext *s, V9fsPath *fs_path, struct statfs *stbuf)
+ {
+-    char *buffer;
+-    int ret;
+-    char *path = fs_path->data;
++    int fd, ret;
+ 
+-    buffer = rpath(s, path);
+-    ret = statfs(buffer, stbuf);
+-    g_free(buffer);
++    fd = local_open_nofollow(s, fs_path->data, O_RDONLY, 0);
++    ret = fstatfs(fd, stbuf);
++    close_preserve_errno(fd);
+     return ret;
+ }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-15.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-15.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-15.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-15.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,49 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From ac125d993b461d4dee4d6df4d93ac3f2eb959d1d Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:43:32 +0100
+Subject: [PATCH] 9pfs: local: truncate: don't follow symlinks
+
+The local_truncate() callback is vulnerable to symlink attacks because
+it calls truncate() which follows symbolic links in all path elements.
+
+This patch converts local_truncate() to rely on open_nofollow() and
+ftruncate() instead.
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 13 +++++++------
+ 1 file changed, 7 insertions(+), 6 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:33:06.948835604 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:33:06.944835552 -0400
+@@ -906,13 +906,14 @@
+ 
+ static int local_truncate(FsContext *ctx, V9fsPath *fs_path, off_t size)
+ {
+-    char *buffer;
+-    int ret;
+-    char *path = fs_path->data;
++    int fd, ret;
+ 
+-    buffer = rpath(ctx, path);
+-    ret = truncate(buffer, size);
+-    g_free(buffer);
++    fd = local_open_nofollow(ctx, fs_path->data, O_WRONLY, 0);
++    if (fd == -1) {
++        return -1;
++    }
++    ret = ftruncate(fd, size);
++    close_preserve_errno(fd);
+     return ret;
+ }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-16.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-16.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-16.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-16.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,79 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From bec1e9546e03b9e7f5152cf3e8c95cf8acff5e12 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:43:40 +0100
+Subject: [PATCH] 9pfs: local: readlink: don't follow symlinks
+
+The local_readlink() callback is vulnerable to symlink attacks because it
+calls:
+
+(1) open(O_NOFOLLOW) which follows symbolic links for all path elements but
+    the rightmost one
+(2) readlink() which follows symbolic links for all path elements but the
+    rightmost one
+
+This patch converts local_readlink() to rely on open_nofollow() to fix (1)
+and opendir_nofollow(), readlinkat() to fix (2).
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 26 +++++++++++++++++---------
+ 1 file changed, 17 insertions(+), 9 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:33:15.120940602 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:34:21.017787272 -0400
+@@ -339,28 +339,36 @@
+                               char *buf, size_t bufsz)
+ {
+     ssize_t tsize = -1;
+-    char *buffer;
+-    char *path = fs_path->data;
+ 
+     if ((fs_ctx->export_flags & V9FS_SM_MAPPED) ||
+         (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE)) {
+         int fd;
+-        buffer = rpath(fs_ctx, path);
+-        fd = open(buffer, O_RDONLY | O_NOFOLLOW);
+-        g_free(buffer);
++
++        fd = local_open_nofollow(fs_ctx, fs_path->data, O_RDONLY, 0);
+         if (fd == -1) {
+             return -1;
+         }
+         do {
+             tsize = read(fd, (void *)buf, bufsz);
+         } while (tsize == -1 && errno == EINTR);
+-        close(fd);
++        close_preserve_errno(fd);
+         return tsize;
+     } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
+                (fs_ctx->export_flags & V9FS_SM_NONE)) {
+-        buffer = rpath(fs_ctx, path);
+-        tsize = readlink(buffer, buf, bufsz);
+-        g_free(buffer);
++        char *dirpath = g_path_get_dirname(fs_path->data);
++        char *name = g_path_get_basename(fs_path->data);
++        int dirfd;
++
++        dirfd = local_opendir_nofollow(fs_ctx, dirpath);
++        if (dirfd == -1) {
++            goto out;
++        }
++
++        tsize = readlinkat(dirfd, name, buf, bufsz);
++        close_preserve_errno(dirfd);
++    out:
++        g_free(name);
++        g_free(dirpath);
+     }
+     return tsize;
+ }
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-17.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-17.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-17.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-17.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,160 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From f9aef99b3e6df88036436b0d3dc3d504b9346c8c Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:43:48 +0100
+Subject: [PATCH] 9pfs: local: lstat: don't follow symlinks
+
+The local_lstat() callback is vulnerable to symlink attacks because it
+calls:
+
+(1) lstat() which follows symbolic links in all path elements but the
+    rightmost one
+(2) getxattr() which follows symbolic links in all path elements
+(3) local_mapped_file_attr()->local_fopen()->openat(O_NOFOLLOW) which
+    follows symbolic links in all path elements but the rightmost
+    one
+
+This patch converts local_lstat() to rely on opendir_nofollow() and
+fstatat(AT_SYMLINK_NOFOLLOW) to fix (1), fgetxattrat_nofollow() to
+fix (2).
+
+A new local_fopenat() helper is introduced as a replacement to
+local_fopen() to fix (3). No effort is made to factor out code
+because local_fopen() will be dropped when all users have been
+converted to call local_fopenat().
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 78 ++++++++++++++++++++++++++++++++++++++++++------------
+ 1 file changed, 61 insertions(+), 17 deletions(-)
+
+Index: qemu/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu.orig/hw/9pfs/virtio-9p-local.c
++++ qemu/hw/9pfs/virtio-9p-local.c
+@@ -111,17 +111,49 @@ static FILE *local_fopen(const char *pat
+     return fp;
+ }
+ 
++static FILE *local_fopenat(int dirfd, const char *name, const char *mode)
++{
++    int fd, o_mode = 0;
++    FILE *fp;
++    int flags;
++    /*
++     * only supports two modes
++     */
++    if (mode[0] == 'r') {
++        flags = O_RDONLY;
++    } else if (mode[0] == 'w') {
++        flags = O_WRONLY | O_TRUNC | O_CREAT;
++        o_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
++    } else {
++        return NULL;
++    }
++    fd = openat_file(dirfd, name, flags, o_mode);
++    if (fd == -1) {
++        return NULL;
++    }
++    fp = fdopen(fd, mode);
++    if (!fp) {
++        close(fd);
++    }
++    return fp;
++}
++
+ #define ATTR_MAX 100
+-static void local_mapped_file_attr(FsContext *ctx, const char *path,
++static void local_mapped_file_attr(int dirfd, const char *name,
+                                    struct stat *stbuf)
+ {
+     FILE *fp;
+     char buf[ATTR_MAX];
+-    char *attr_path;
++    int map_dirfd;
++
++    map_dirfd = openat(dirfd, VIRTFS_META_DIR,
++                       O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
++    if (map_dirfd == -1) {
++        return;
++    }
+ 
+-    attr_path = local_mapped_attr_path(ctx, path);
+-    fp = local_fopen(attr_path, "r");
+-    g_free(attr_path);
++    fp = local_fopenat(map_dirfd, name, "r");
++    close_preserve_errno(map_dirfd);
+     if (!fp) {
+         return;
+     }
+@@ -143,12 +175,17 @@ static void local_mapped_file_attr(FsCon
+ 
+ static int local_lstat(FsContext *fs_ctx, V9fsPath *fs_path, struct stat *stbuf)
+ {
+-    int err;
+-    char *buffer;
+-    char *path = fs_path->data;
++    int err = -1;
++    char *dirpath = g_path_get_dirname(fs_path->data);
++    char *name = g_path_get_basename(fs_path->data);
++    int dirfd;
++
++    dirfd = local_opendir_nofollow(fs_ctx, dirpath);
++    if (dirfd == -1) {
++        goto out;
++    }
+ 
+-    buffer = rpath(fs_ctx, path);
+-    err =  lstat(buffer, stbuf);
++    err = fstatat(dirfd, name, stbuf, AT_SYMLINK_NOFOLLOW);
+     if (err) {
+         goto err_out;
+     }
+@@ -158,25 +195,33 @@ static int local_lstat(FsContext *fs_ctx
+         gid_t tmp_gid;
+         mode_t tmp_mode;
+         dev_t tmp_dev;
+-        if (getxattr(buffer, "user.virtfs.uid", &tmp_uid, sizeof(uid_t)) > 0) {
++
++        if (fgetxattrat_nofollow(dirfd, name, "user.virtfs.uid", &tmp_uid,
++                                 sizeof(uid_t)) > 0) {
+             stbuf->st_uid = le32_to_cpu(tmp_uid);
+         }
+-        if (getxattr(buffer, "user.virtfs.gid", &tmp_gid, sizeof(gid_t)) > 0) {
++        if (fgetxattrat_nofollow(dirfd, name, "user.virtfs.gid", &tmp_gid,
++                                 sizeof(gid_t)) > 0) {
+             stbuf->st_gid = le32_to_cpu(tmp_gid);
+         }
+-        if (getxattr(buffer, "user.virtfs.mode",
+-                    &tmp_mode, sizeof(mode_t)) > 0) {
++        if (fgetxattrat_nofollow(dirfd, name, "user.virtfs.mode", &tmp_mode,
++                                 sizeof(mode_t)) > 0) {
++
+             stbuf->st_mode = le32_to_cpu(tmp_mode);
+         }
+-        if (getxattr(buffer, "user.virtfs.rdev", &tmp_dev, sizeof(dev_t)) > 0) {
++        if (fgetxattrat_nofollow(dirfd, name, "user.virtfs.rdev", &tmp_dev,
++                                 sizeof(dev_t)) > 0) {
+             stbuf->st_rdev = le64_to_cpu(tmp_dev);
+         }
+     } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+-        local_mapped_file_attr(fs_ctx, path, stbuf);
++        local_mapped_file_attr(dirfd, name, stbuf);
+     }
+ 
+ err_out:
+-    g_free(buffer);
++    close_preserve_errno(dirfd);
++out:
++    g_free(name);
++    g_free(dirpath);
+     return err;
+ }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-18.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-18.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-18.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-18.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,126 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From 99f2cf4b2dad7b37c69759deb0d0b19d3ec1a24a Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:43:55 +0100
+Subject: [PATCH] 9pfs: local: renameat: don't follow symlinks
+
+The local_renameat() callback is currently a wrapper around local_rename()
+which is vulnerable to symlink attacks.
+
+This patch rewrites local_renameat() to have its own implementation, based
+on local_opendir_nofollow() and renameat().
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++--------
+ 1 file changed, 64 insertions(+), 10 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:37:10.935970451 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:37:10.931970400 -0400
+@@ -64,6 +64,14 @@
+     return local_open_nofollow(fs_ctx, path, O_DIRECTORY | O_RDONLY, 0);
+ }
+ 
++static void renameat_preserve_errno(int odirfd, const char *opath, int ndirfd,
++                                    const char *npath)
++{
++    int serrno = errno;
++    renameat(odirfd, opath, ndirfd, npath);
++    errno = serrno;
++}
++
+ #define VIRTFS_META_DIR ".virtfs_metadata"
+ 
+ static char *local_mapped_attr_path(FsContext *ctx, const char *path)
+@@ -145,8 +153,7 @@
+     char buf[ATTR_MAX];
+     int map_dirfd;
+ 
+-    map_dirfd = openat(dirfd, VIRTFS_META_DIR,
+-                       O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
++    map_dirfd = openat_dir(dirfd, VIRTFS_META_DIR);
+     if (map_dirfd == -1) {
+         return;
+     }
+@@ -1201,17 +1208,64 @@
+                           const char *new_name)
+ {
+     int ret;
+-    V9fsString old_full_name, new_full_name;
++    int odirfd, ndirfd;
++
++    odirfd = local_opendir_nofollow(ctx, olddir->data);
++    if (odirfd == -1) {
++        return -1;
++    }
++
++    ndirfd = local_opendir_nofollow(ctx, newdir->data);
++    if (ndirfd == -1) {
++        close_preserve_errno(odirfd);
++        return -1;
++    }
++
++    ret = renameat(odirfd, old_name, ndirfd, new_name);
++    if (ret < 0) {
++        goto out;
++    }
+ 
+-    v9fs_string_init(&old_full_name);
+-    v9fs_string_init(&new_full_name);
++    if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
++        int omap_dirfd, nmap_dirfd;
+ 
+-    v9fs_string_sprintf(&old_full_name, "%s/%s", olddir->data, old_name);
+-    v9fs_string_sprintf(&new_full_name, "%s/%s", newdir->data, new_name);
++        ret = mkdirat(ndirfd, VIRTFS_META_DIR, 0700);
++        if (ret < 0 && errno != EEXIST) {
++            goto err_undo_rename;
++        }
+ 
+-    ret = local_rename(ctx, old_full_name.data, new_full_name.data);
+-    v9fs_string_free(&old_full_name);
+-    v9fs_string_free(&new_full_name);
++        omap_dirfd = openat(odirfd, VIRTFS_META_DIR,
++                            O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
++        if (omap_dirfd == -1) {
++            goto err;
++        }
++
++        nmap_dirfd = openat(ndirfd, VIRTFS_META_DIR,
++                            O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
++        if (nmap_dirfd == -1) {
++            close_preserve_errno(omap_dirfd);
++            goto err;
++        }
++
++        /* rename the .virtfs_metadata files */
++        ret = renameat(omap_dirfd, old_name, nmap_dirfd, new_name);
++        close_preserve_errno(nmap_dirfd);
++        close_preserve_errno(omap_dirfd);
++        if (ret < 0 && errno != ENOENT) {
++            goto err_undo_rename;
++        }
++
++        ret = 0;
++    }
++    goto out;
++
++err:
++    ret = -1;
++err_undo_rename:
++    renameat_preserve_errno(ndirfd, new_name, odirfd, old_name);
++out:
++    close_preserve_errno(ndirfd);
++    close_preserve_errno(odirfd);
+     return ret;
+ }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-19.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-19.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-19.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-19.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,100 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From d2767edec582558f1e6c52e1dd9370d62e2b30fc Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:44:03 +0100
+Subject: [PATCH] 9pfs: local: rename: use renameat
+
+The local_rename() callback is vulnerable to symlink attacks because it
+uses rename() which follows symbolic links in all path elements but the
+rightmost one.
+
+This patch simply transforms local_rename() into a wrapper around
+local_renameat() which is symlink-attack safe.
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 57 ++++++++++++++++++++++++++----------------------------
+ 1 file changed, 27 insertions(+), 30 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:37:16.872046721 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:37:16.868046669 -0400
+@@ -976,36 +976,6 @@
+     return ret;
+ }
+ 
+-static int local_rename(FsContext *ctx, const char *oldpath,
+-                        const char *newpath)
+-{
+-    int err;
+-    char *buffer, *buffer1;
+-
+-    if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+-        err = local_create_mapped_attr_dir(ctx, newpath);
+-        if (err < 0) {
+-            return err;
+-        }
+-        /* rename the .virtfs_metadata files */
+-        buffer = local_mapped_attr_path(ctx, oldpath);
+-        buffer1 = local_mapped_attr_path(ctx, newpath);
+-        err = rename(buffer, buffer1);
+-        g_free(buffer);
+-        g_free(buffer1);
+-        if (err < 0 && errno != ENOENT) {
+-            return err;
+-        }
+-    }
+-
+-    buffer = rpath(ctx, oldpath);
+-    buffer1 = rpath(ctx, newpath);
+-    err = rename(buffer, buffer1);
+-    g_free(buffer);
+-    g_free(buffer1);
+-    return err;
+-}
+-
+ static int local_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
+ {
+     char *buffer;
+@@ -1269,6 +1239,33 @@
+     return ret;
+ }
+ 
++static void v9fs_path_init_dirname(V9fsPath *path, const char *str)
++{
++    path->data = g_path_get_dirname(str);
++    path->size = strlen(path->data) + 1;
++}
++
++static int local_rename(FsContext *ctx, const char *oldpath,
++                        const char *newpath)
++{
++    int err;
++    char *oname = g_path_get_basename(oldpath);
++    char *nname = g_path_get_basename(newpath);
++    V9fsPath olddir, newdir;
++
++    v9fs_path_init_dirname(&olddir, oldpath);
++    v9fs_path_init_dirname(&newdir, newpath);
++
++    err = local_renameat(ctx, &olddir, oname, &newdir, nname);
++
++    v9fs_path_free(&newdir);
++    v9fs_path_free(&olddir);
++    g_free(nname);
++    g_free(oname);
++
++    return err;
++}
++
+ static int local_unlinkat(FsContext *ctx, V9fsPath *dir,
+                           const char *name, int flags)
+ {
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-1.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-1.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-1.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-1.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,184 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From 56fc494bdcba35d74da27e1d34dbb6db6fa7bd67 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:41:40 +0100
+Subject: [PATCH] 9pfs: local: move xattr security ops to 9p-xattr.c
+
+These functions are always called indirectly. It really doesn't make sense
+for them to sit in a header file.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-xattr.c | 61 +++++++++++++++++++++++++++++++++++++++++
+ hw/9pfs/9p-xattr.h | 80 ++++++++++--------------------------------------------
+ 2 files changed, 75 insertions(+), 66 deletions(-)
+
+Index: qemu-2.6.1+dfsg/hw/9pfs/virtio-9p-xattr.c
+===================================================================
+--- qemu-2.6.1+dfsg.orig/hw/9pfs/virtio-9p-xattr.c	2017-04-04 08:06:34.775512919 -0400
++++ qemu-2.6.1+dfsg/hw/9pfs/virtio-9p-xattr.c	2017-04-04 08:06:34.767512815 -0400
+@@ -143,6 +143,67 @@
+ 
+ }
+ 
++ssize_t pt_getxattr(FsContext *ctx, const char *path, const char *name,
++                    void *value, size_t size)
++{
++    char *buffer;
++    ssize_t ret;
++
++    buffer = rpath(ctx, path);
++    ret = lgetxattr(buffer, name, value, size);
++    g_free(buffer);
++    return ret;
++}
++
++int pt_setxattr(FsContext *ctx, const char *path, const char *name, void *value,
++                size_t size, int flags)
++{
++    char *buffer;
++    int ret;
++
++    buffer = rpath(ctx, path);
++    ret = lsetxattr(buffer, name, value, size, flags);
++    g_free(buffer);
++    return ret;
++}
++
++int pt_removexattr(FsContext *ctx, const char *path, const char *name)
++{
++    char *buffer;
++    int ret;
++
++    buffer = rpath(ctx, path);
++    ret = lremovexattr(path, name);
++    g_free(buffer);
++    return ret;
++}
++
++ssize_t notsup_getxattr(FsContext *ctx, const char *path, const char *name,
++                        void *value, size_t size)
++{
++    errno = ENOTSUP;
++    return -1;
++}
++
++int notsup_setxattr(FsContext *ctx, const char *path, const char *name,
++                    void *value, size_t size, int flags)
++{
++    errno = ENOTSUP;
++    return -1;
++}
++
++ssize_t notsup_listxattr(FsContext *ctx, const char *path, char *name,
++                         void *value, size_t size)
++{
++    return 0;
++}
++
++int notsup_removexattr(FsContext *ctx, const char *path, const char *name)
++{
++    errno = ENOTSUP;
++    return -1;
++}
++
+ XattrOperations *mapped_xattr_ops[] = {
+     &mapped_user_xattr,
+     &mapped_pacl_xattr,
+Index: qemu-2.6.1+dfsg/hw/9pfs/virtio-9p-xattr.h
+===================================================================
+--- qemu-2.6.1+dfsg.orig/hw/9pfs/virtio-9p-xattr.h	2017-04-04 08:06:34.775512919 -0400
++++ qemu-2.6.1+dfsg/hw/9pfs/virtio-9p-xattr.h	2017-04-04 08:06:34.771512867 -0400
+@@ -48,73 +48,21 @@
+ int v9fs_set_xattr(FsContext *ctx, const char *path, const char *name,
+                           void *value, size_t size, int flags);
+ int v9fs_remove_xattr(FsContext *ctx, const char *path, const char *name);
++
+ ssize_t pt_listxattr(FsContext *ctx, const char *path, char *name, void *value,
+                      size_t size);
+-
+-static inline ssize_t pt_getxattr(FsContext *ctx, const char *path,
+-                                  const char *name, void *value, size_t size)
+-{
+-    char *buffer;
+-    ssize_t ret;
+-
+-    buffer = rpath(ctx, path);
+-    ret = lgetxattr(buffer, name, value, size);
+-    g_free(buffer);
+-    return ret;
+-}
+-
+-static inline int pt_setxattr(FsContext *ctx, const char *path,
+-                              const char *name, void *value,
+-                              size_t size, int flags)
+-{
+-    char *buffer;
+-    int ret;
+-
+-    buffer = rpath(ctx, path);
+-    ret = lsetxattr(buffer, name, value, size, flags);
+-    g_free(buffer);
+-    return ret;
+-}
+-
+-static inline int pt_removexattr(FsContext *ctx,
+-                                 const char *path, const char *name)
+-{
+-    char *buffer;
+-    int ret;
+-
+-    buffer = rpath(ctx, path);
+-    ret = lremovexattr(path, name);
+-    g_free(buffer);
+-    return ret;
+-}
+-
+-static inline ssize_t notsup_getxattr(FsContext *ctx, const char *path,
+-                                      const char *name, void *value,
+-                                      size_t size)
+-{
+-    errno = ENOTSUP;
+-    return -1;
+-}
+-
+-static inline int notsup_setxattr(FsContext *ctx, const char *path,
+-                                  const char *name, void *value,
+-                                  size_t size, int flags)
+-{
+-    errno = ENOTSUP;
+-    return -1;
+-}
+-
+-static inline ssize_t notsup_listxattr(FsContext *ctx, const char *path,
+-                                       char *name, void *value, size_t size)
+-{
+-    return 0;
+-}
+-
+-static inline int notsup_removexattr(FsContext *ctx,
+-                                     const char *path, const char *name)
+-{
+-    errno = ENOTSUP;
+-    return -1;
+-}
++ssize_t pt_getxattr(FsContext *ctx, const char *path, const char *name,
++                    void *value, size_t size);
++int pt_setxattr(FsContext *ctx, const char *path, const char *name, void *value,
++                size_t size, int flags);
++int pt_removexattr(FsContext *ctx, const char *path, const char *name);
++
++ssize_t notsup_getxattr(FsContext *ctx, const char *path, const char *name,
++                        void *value, size_t size);
++int notsup_setxattr(FsContext *ctx, const char *path, const char *name,
++                    void *value, size_t size, int flags);
++ssize_t notsup_listxattr(FsContext *ctx, const char *path, char *name,
++                         void *value, size_t size);
++int notsup_removexattr(FsContext *ctx, const char *path, const char *name);
+ 
+ #endif
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-20.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-20.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-20.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-20.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,94 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From 6dd4b1f1d026e478d9177b28169b377e212400f3 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:44:11 +0100
+Subject: [PATCH] 9pfs: local: improve error handling in link op
+
+When using the mapped-file security model, we also have to create a link
+for the metadata file if it exists. In case of failure, we should rollback.
+
+That's what this patch does.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 32 +++++++++++++++++++++-----------
+ 1 file changed, 21 insertions(+), 11 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:37:23.432131007 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:37:23.428130956 -0400
+@@ -932,6 +932,7 @@
+     int ret;
+     V9fsString newpath;
+     char *buffer, *buffer1;
++    int serrno;
+ 
+     v9fs_string_init(&newpath);
+     v9fs_string_sprintf(&newpath, "%s/%s", dirpath->data, name);
+@@ -940,25 +941,36 @@
+     buffer1 = rpath(ctx, newpath.data);
+     ret = link(buffer, buffer1);
+     g_free(buffer);
+-    g_free(buffer1);
++    if (ret < 0) {
++        goto out;
++    }
+ 
+     /* now link the virtfs_metadata files */
+-    if (!ret && (ctx->export_flags & V9FS_SM_MAPPED_FILE)) {
++    if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
++        char *vbuffer, *vbuffer1;
++
+         /* Link the .virtfs_metadata files. Create the metada directory */
+         ret = local_create_mapped_attr_dir(ctx, newpath.data);
+         if (ret < 0) {
+             goto err_out;
+         }
+-        buffer = local_mapped_attr_path(ctx, oldpath->data);
+-        buffer1 = local_mapped_attr_path(ctx, newpath.data);
+-        ret = link(buffer, buffer1);
+-        g_free(buffer);
+-        g_free(buffer1);
++        vbuffer = local_mapped_attr_path(ctx, oldpath->data);
++        vbuffer1 = local_mapped_attr_path(ctx, newpath.data);
++        ret = link(vbuffer, vbuffer1);
++        g_free(vbuffer);
++        g_free(vbuffer1);
+         if (ret < 0 && errno != ENOENT) {
+             goto err_out;
+         }
+     }
++    goto out;
++
+ err_out:
++    serrno = errno;
++    remove(buffer1);
++    errno = serrno;
++out:
++    g_free(buffer1);
+     v9fs_string_free(&newpath);
+     return ret;
+ }
+@@ -1204,14 +1216,12 @@
+             goto err_undo_rename;
+         }
+ 
+-        omap_dirfd = openat(odirfd, VIRTFS_META_DIR,
+-                            O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
++        omap_dirfd = openat_dir(odirfd, VIRTFS_META_DIR);
+         if (omap_dirfd == -1) {
+             goto err;
+         }
+ 
+-        nmap_dirfd = openat(ndirfd, VIRTFS_META_DIR,
+-                            O_RDONLY | O_DIRECTORY | O_NOFOLLOW);
++        nmap_dirfd = openat_dir(ndirfd, VIRTFS_META_DIR);
+         if (nmap_dirfd == -1) {
+             close_preserve_errno(omap_dirfd);
+             goto err;
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-21.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-21.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-21.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-21.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,147 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From ad0b46e6ac769b187cb4dcf0065675ef8a198a5e Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:44:20 +0100
+Subject: [PATCH] 9pfs: local: link: don't follow symlinks
+
+The local_link() callback is vulnerable to symlink attacks because it calls:
+
+(1) link() which follows symbolic links for all path elements but the
+    rightmost one
+(2) local_create_mapped_attr_dir()->mkdir() which follows symbolic links
+    for all path elements but the rightmost one
+
+This patch converts local_link() to rely on opendir_nofollow() and linkat()
+to fix (1), mkdirat() to fix (2).
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 84 +++++++++++++++++++++++++++++++++++-------------------
+ 1 file changed, 55 insertions(+), 29 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:38:34.521044387 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:38:34.517044336 -0400
+@@ -72,6 +72,13 @@
+     errno = serrno;
+ }
+ 
++static void unlinkat_preserve_errno(int dirfd, const char *path, int flags)
++{
++    int serrno = errno;
++    unlinkat(dirfd, path, flags);
++    errno = serrno;
++}
++
+ #define VIRTFS_META_DIR ".virtfs_metadata"
+ 
+ static char *local_mapped_attr_path(FsContext *ctx, const char *path)
+@@ -929,49 +936,68 @@
+ static int local_link(FsContext *ctx, V9fsPath *oldpath,
+                       V9fsPath *dirpath, const char *name)
+ {
+-    int ret;
+-    V9fsString newpath;
+-    char *buffer, *buffer1;
+-    int serrno;
+-
+-    v9fs_string_init(&newpath);
+-    v9fs_string_sprintf(&newpath, "%s/%s", dirpath->data, name);
+-
+-    buffer = rpath(ctx, oldpath->data);
+-    buffer1 = rpath(ctx, newpath.data);
+-    ret = link(buffer, buffer1);
+-    g_free(buffer);
+-    if (ret < 0) {
++    char *odirpath = g_path_get_dirname(oldpath->data);
++    char *oname = g_path_get_basename(oldpath->data);
++    int ret = -1;
++    int odirfd, ndirfd;
++
++    odirfd = local_opendir_nofollow(ctx, odirpath);
++    if (odirfd == -1) {
+         goto out;
+     }
+ 
++    ndirfd = local_opendir_nofollow(ctx, dirpath->data);
++    if (ndirfd == -1) {
++        close_preserve_errno(odirfd);
++        goto out;
++    }
++
++    ret = linkat(odirfd, oname, ndirfd, name, 0);
++    if (ret < 0) {
++        goto out_close;
++    }
++
+     /* now link the virtfs_metadata files */
+     if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+-        char *vbuffer, *vbuffer1;
++        int omap_dirfd, nmap_dirfd;
++
++        ret = mkdirat(ndirfd, VIRTFS_META_DIR, 0700);
++        if (ret < 0 && errno != EEXIST) {
++            goto err_undo_link;
++        }
++
++        omap_dirfd = openat_dir(odirfd, VIRTFS_META_DIR);
++        if (omap_dirfd == -1) {
++            goto err;
++        }
++
++        nmap_dirfd = openat_dir(ndirfd, VIRTFS_META_DIR);
++        if (nmap_dirfd == -1) {
++            close_preserve_errno(omap_dirfd);
++            goto err;
++        }
+ 
+-        /* Link the .virtfs_metadata files. Create the metada directory */
+-        ret = local_create_mapped_attr_dir(ctx, newpath.data);
+-        if (ret < 0) {
+-            goto err_out;
+-        }
+-        vbuffer = local_mapped_attr_path(ctx, oldpath->data);
+-        vbuffer1 = local_mapped_attr_path(ctx, newpath.data);
+-        ret = link(vbuffer, vbuffer1);
+-        g_free(vbuffer);
+-        g_free(vbuffer1);
++        ret = linkat(omap_dirfd, oname, nmap_dirfd, name, 0);
++        close_preserve_errno(nmap_dirfd);
++        close_preserve_errno(omap_dirfd);
+         if (ret < 0 && errno != ENOENT) {
+-            goto err_out;
++            goto err_undo_link;
+         }
++
++        ret = 0;
+     }
+-    goto out;
++    goto out_close;
+ 
+-err_out:
+-    serrno = errno;
+-    remove(buffer1);
+-    errno = serrno;
++err:
++    ret = -1;
++err_undo_link:
++    unlinkat_preserve_errno(ndirfd, name, 0);
++out_close:
++    close_preserve_errno(ndirfd);
++    close_preserve_errno(odirfd);
+ out:
+-    g_free(buffer1);
+-    v9fs_string_free(&newpath);
++    g_free(oname);
++    g_free(odirpath);
+     return ret;
+ }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-22.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-22.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-22.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-22.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,245 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From e3187a45dd02a7490f9191c16527dc28a4ba45b9 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:44:28 +0100
+Subject: [PATCH] 9pfs: local: chmod: don't follow symlinks
+
+The local_chmod() callback is vulnerable to symlink attacks because it
+calls:
+
+(1) chmod() which follows symbolic links for all path elements
+(2) local_set_xattr()->setxattr() which follows symbolic links for all
+    path elements
+(3) local_set_mapped_file_attr() which calls in turn local_fopen() and
+    mkdir(), both functions following symbolic links for all path
+    elements but the rightmost one
+
+We would need fchmodat() to implement AT_SYMLINK_NOFOLLOW to fix (1). This
+isn't the case on linux unfortunately: the kernel doesn't even have a flags
+argument to the syscall :-\ It is impossible to fix it in userspace in
+a race-free manner. This patch hence converts local_chmod() to rely on
+open_nofollow() and fchmod(). This fixes the vulnerability but introduces
+a limitation: the target file must readable and/or writable for the call
+to openat() to succeed.
+
+It introduces a local_set_xattrat() replacement to local_set_xattr()
+based on fsetxattrat() to fix (2), and a local_set_mapped_file_attrat()
+replacement to local_set_mapped_file_attr() based on local_fopenat()
+and mkdirat() to fix (3). No effort is made to factor out code because
+both local_set_xattr() and local_set_mapped_file_attr() will be dropped
+when all users have been converted to use the "at" versions.
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 178 +++++++++++++++++++++++++++++++++++++++++++++++++----
+ 1 file changed, 167 insertions(+), 11 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:38:40.141116596 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:38:40.137116544 -0400
+@@ -366,6 +366,155 @@
+     return 0;
+ }
+ 
++static int local_set_mapped_file_attrat(int dirfd, const char *name,
++                                        FsCred *credp)
++{
++    FILE *fp;
++    int ret;
++    char buf[ATTR_MAX];
++    int uid = -1, gid = -1, mode = -1, rdev = -1;
++    int map_dirfd;
++
++    ret = mkdirat(dirfd, VIRTFS_META_DIR, 0700);
++    if (ret < 0 && errno != EEXIST) {
++        return -1;
++    }
++
++    map_dirfd = openat_dir(dirfd, VIRTFS_META_DIR);
++    if (map_dirfd == -1) {
++        return -1;
++    }
++
++    fp = local_fopenat(map_dirfd, name, "r");
++    if (!fp) {
++        if (errno == ENOENT) {
++            goto update_map_file;
++        } else {
++            close_preserve_errno(map_dirfd);
++            return -1;
++        }
++    }
++    memset(buf, 0, ATTR_MAX);
++    while (fgets(buf, ATTR_MAX, fp)) {
++        if (!strncmp(buf, "virtfs.uid", 10)) {
++            uid = atoi(buf + 11);
++        } else if (!strncmp(buf, "virtfs.gid", 10)) {
++            gid = atoi(buf + 11);
++        } else if (!strncmp(buf, "virtfs.mode", 11)) {
++            mode = atoi(buf + 12);
++        } else if (!strncmp(buf, "virtfs.rdev", 11)) {
++            rdev = atoi(buf + 12);
++        }
++        memset(buf, 0, ATTR_MAX);
++    }
++    fclose(fp);
++
++update_map_file:
++    fp = local_fopenat(map_dirfd, name, "w");
++    close_preserve_errno(map_dirfd);
++    if (!fp) {
++        return -1;
++    }
++
++    if (credp->fc_uid != -1) {
++        uid = credp->fc_uid;
++    }
++    if (credp->fc_gid != -1) {
++        gid = credp->fc_gid;
++    }
++    if (credp->fc_mode != -1) {
++        mode = credp->fc_mode;
++    }
++    if (credp->fc_rdev != -1) {
++        rdev = credp->fc_rdev;
++    }
++
++    if (uid != -1) {
++        fprintf(fp, "virtfs.uid=%d\n", uid);
++    }
++    if (gid != -1) {
++        fprintf(fp, "virtfs.gid=%d\n", gid);
++    }
++    if (mode != -1) {
++        fprintf(fp, "virtfs.mode=%d\n", mode);
++    }
++    if (rdev != -1) {
++        fprintf(fp, "virtfs.rdev=%d\n", rdev);
++    }
++    fclose(fp);
++
++    return 0;
++}
++
++static int fchmodat_nofollow(int dirfd, const char *name, mode_t mode)
++{
++    int fd, ret;
++
++    /* FIXME: this should be handled with fchmodat(AT_SYMLINK_NOFOLLOW).
++     * Unfortunately, the linux kernel doesn't implement it yet. As an
++     * alternative, let's open the file and use fchmod() instead. This
++     * may fail depending on the permissions of the file, but it is the
++     * best we can do to avoid TOCTTOU. We first try to open read-only
++     * in case name points to a directory. If that fails, we try write-only
++     * in case name doesn't point to a directory.
++     */
++    fd = openat_file(dirfd, name, O_RDONLY, 0);
++    if (fd == -1) {
++        /* In case the file is writable-only and isn't a directory. */
++        if (errno == EACCES) {
++            fd = openat_file(dirfd, name, O_WRONLY, 0);
++        }
++        if (fd == -1 && errno == EISDIR) {
++            errno = EACCES;
++        }
++    }
++    if (fd == -1) {
++        return -1;
++    }
++    ret = fchmod(fd, mode);
++    close_preserve_errno(fd);
++    return ret;
++}
++
++static int local_set_xattrat(int dirfd, const char *path, FsCred *credp)
++{
++    int err;
++
++    if (credp->fc_uid != -1) {
++        uint32_t tmp_uid = cpu_to_le32(credp->fc_uid);
++        err = fsetxattrat_nofollow(dirfd, path, "user.virtfs.uid", &tmp_uid,
++                                   sizeof(uid_t), 0);
++        if (err) {
++            return err;
++        }
++    }
++    if (credp->fc_gid != -1) {
++        uint32_t tmp_gid = cpu_to_le32(credp->fc_gid);
++        err = fsetxattrat_nofollow(dirfd, path, "user.virtfs.gid", &tmp_gid,
++                                   sizeof(gid_t), 0);
++        if (err) {
++            return err;
++        }
++    }
++    if (credp->fc_mode != -1) {
++        uint32_t tmp_mode = cpu_to_le32(credp->fc_mode);
++        err = fsetxattrat_nofollow(dirfd, path, "user.virtfs.mode", &tmp_mode,
++                                   sizeof(mode_t), 0);
++        if (err) {
++            return err;
++        }
++    }
++    if (credp->fc_rdev != -1) {
++        uint64_t tmp_rdev = cpu_to_le64(credp->fc_rdev);
++        err = fsetxattrat_nofollow(dirfd, path, "user.virtfs.rdev", &tmp_rdev,
++                                   sizeof(dev_t), 0);
++        if (err) {
++            return err;
++        }
++    }
++    return 0;
++}
++
+ static int local_post_create_passthrough(FsContext *fs_ctx, const char *path,
+                                          FsCred *credp)
+ {
+@@ -554,22 +703,29 @@
+ 
+ static int local_chmod(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
+ {
+-    char *buffer;
++    char *dirpath = g_path_get_dirname(fs_path->data);
++    char *name = g_path_get_basename(fs_path->data);
+     int ret = -1;
+-    char *path = fs_path->data;
++    int dirfd;
++
++    dirfd = local_opendir_nofollow(fs_ctx, dirpath);
++    if (dirfd == -1) {
++        goto out;
++    }
+ 
+     if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
+-        buffer = rpath(fs_ctx, path);
+-        ret = local_set_xattr(buffer, credp);
+-        g_free(buffer);
++        ret = local_set_xattrat(dirfd, name, credp);
+     } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+-        return local_set_mapped_file_attr(fs_ctx, path, credp);
+-    } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
+-               (fs_ctx->export_flags & V9FS_SM_NONE)) {
+-        buffer = rpath(fs_ctx, path);
+-        ret = chmod(buffer, credp->fc_mode);
+-        g_free(buffer);
+-    }
++        ret = local_set_mapped_file_attrat(dirfd, name, credp);
++    } else if (fs_ctx->export_flags & V9FS_SM_PASSTHROUGH ||
++               fs_ctx->export_flags & V9FS_SM_NONE) {
++        ret = fchmodat_nofollow(dirfd, name, credp->fc_mode);
++    }
++    close_preserve_errno(dirfd);
++
++out:
++    g_free(dirpath);
++    g_free(name);
+     return ret;
+ }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-23.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-23.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-23.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-23.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,78 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From d369f20763a857eac544a5289a046d0285a91df8 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:44:37 +0100
+Subject: [PATCH] 9pfs: local: chown: don't follow symlinks
+
+The local_chown() callback is vulnerable to symlink attacks because it
+calls:
+
+(1) lchown() which follows symbolic links for all path elements but the
+    rightmost one
+(2) local_set_xattr()->setxattr() which follows symbolic links for all
+    path elements
+(3) local_set_mapped_file_attr() which calls in turn local_fopen() and
+    mkdir(), both functions following symbolic links for all path
+    elements but the rightmost one
+
+This patch converts local_chown() to rely on open_nofollow() and
+fchownat() to fix (1), as well as local_set_xattrat() and
+local_set_mapped_file_attrat() to fix (2) and (3) respectively.
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 26 +++++++++++++++++---------
+ 1 file changed, 17 insertions(+), 9 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:38:45.673187674 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:38:45.669187622 -0400
+@@ -1172,23 +1172,31 @@
+ 
+ static int local_chown(FsContext *fs_ctx, V9fsPath *fs_path, FsCred *credp)
+ {
+-    char *buffer;
++    char *dirpath = g_path_get_dirname(fs_path->data);
++    char *name = g_path_get_basename(fs_path->data);
+     int ret = -1;
+-    char *path = fs_path->data;
++    int dirfd;
++
++    dirfd = local_opendir_nofollow(fs_ctx, dirpath);
++    if (dirfd == -1) {
++        goto out;
++    }
+ 
+     if ((credp->fc_uid == -1 && credp->fc_gid == -1) ||
+         (fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
+         (fs_ctx->export_flags & V9FS_SM_NONE)) {
+-        buffer = rpath(fs_ctx, path);
+-        ret = lchown(buffer, credp->fc_uid, credp->fc_gid);
+-        g_free(buffer);
++        ret = fchownat(dirfd, name, credp->fc_uid, credp->fc_gid,
++                       AT_SYMLINK_NOFOLLOW);
+     } else if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
+-        buffer = rpath(fs_ctx, path);
+-        ret = local_set_xattr(buffer, credp);
+-        g_free(buffer);
++        ret = local_set_xattrat(dirfd, name, credp);
+     } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+-        return local_set_mapped_file_attr(fs_ctx, path, credp);
++        ret = local_set_mapped_file_attrat(dirfd, name, credp);
+     }
++
++    close_preserve_errno(dirfd);
++out:
++    g_free(name);
++    g_free(dirpath);
+     return ret;
+ }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-24.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-24.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-24.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-24.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,172 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From 38771613ea6759f499645afd709aa422161eb27e Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:44:46 +0100
+Subject: [PATCH] 9pfs: local: symlink: don't follow symlinks
+
+The local_symlink() callback is vulnerable to symlink attacks because it
+calls:
+
+(1) symlink() which follows symbolic links for all path elements but the
+    rightmost one
+(2) open(O_NOFOLLOW) which follows symbolic links for all path elements but
+    the rightmost one
+(3) local_set_xattr()->setxattr() which follows symbolic links for all
+    path elements
+(4) local_set_mapped_file_attr() which calls in turn local_fopen() and
+    mkdir(), both functions following symbolic links for all path
+    elements but the rightmost one
+
+This patch converts local_symlink() to rely on opendir_nofollow() and
+symlinkat() to fix (1), openat(O_NOFOLLOW) to fix (2), as well as
+local_set_xattrat() and local_set_mapped_file_attrat() to fix (3) and
+(4) respectively.
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 81 +++++++++++++++++-------------------------------------
+ 1 file changed, 25 insertions(+), 56 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:38:53.361286453 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:43:39.164958577 -0400
+@@ -987,24 +987,22 @@
+                          V9fsPath *dir_path, const char *name, FsCred *credp)
+ {
+     int err = -1;
+-    int serrno = 0;
+-    char *newpath;
+-    V9fsString fullname;
+-    char *buffer;
+-
+-    v9fs_string_init(&fullname);
+-    v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
+-    newpath = fullname.data;
++    int dirfd;
++
++    dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
++    if (dirfd == -1) {
++        return -1;
++    }
+ 
+     /* Determine the security model */
+-    if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
++    if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
++        fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+         int fd;
+         ssize_t oldpath_size, write_size;
+-        buffer = rpath(fs_ctx, newpath);
+-        fd = open(buffer, O_CREAT|O_EXCL|O_RDWR|O_NOFOLLOW, SM_LOCAL_MODE_BITS);
++
++        fd = openat_file(dirfd, name, O_CREAT | O_EXCL | O_RDWR,
++                         SM_LOCAL_MODE_BITS);
+         if (fd == -1) {
+-            g_free(buffer);
+-            err = fd;
+             goto out;
+         }
+         /* Write the oldpath (target) to the file. */
+@@ -1012,80 +1010,48 @@
+         do {
+             write_size = write(fd, (void *)oldpath, oldpath_size);
+         } while (write_size == -1 && errno == EINTR);
++        close_preserve_errno(fd);
+ 
+         if (write_size != oldpath_size) {
+-            serrno = errno;
+-            close(fd);
+-            err = -1;
+             goto err_end;
+         }
+-        close(fd);
+         /* Set cleint credentials in symlink's xattr */
+-        credp->fc_mode = credp->fc_mode|S_IFLNK;
+-        err = local_set_xattr(buffer, credp);
+-        if (err == -1) {
+-            serrno = errno;
+-            goto err_end;
+-        }
+-    } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+-        int fd;
+-        ssize_t oldpath_size, write_size;
+-        buffer = rpath(fs_ctx, newpath);
+-        fd = open(buffer, O_CREAT|O_EXCL|O_RDWR|O_NOFOLLOW, SM_LOCAL_MODE_BITS);
+-        if (fd == -1) {
+-            g_free(buffer);
+-            err = fd;
+-            goto out;
+-        }
+-        /* Write the oldpath (target) to the file. */
+-        oldpath_size = strlen(oldpath);
+-        do {
+-            write_size = write(fd, (void *)oldpath, oldpath_size);
+-        } while (write_size == -1 && errno == EINTR);
++        credp->fc_mode = credp->fc_mode | S_IFLNK;
+ 
+-        if (write_size != oldpath_size) {
+-            serrno = errno;
+-            close(fd);
+-            err = -1;
+-            goto err_end;
++        if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
++            err = local_set_xattrat(dirfd, name, credp);
++        } else {
++            err = local_set_mapped_file_attrat(dirfd, name, credp);
+         }
+-        close(fd);
+-        /* Set cleint credentials in symlink's xattr */
+-        credp->fc_mode = credp->fc_mode|S_IFLNK;
+-        err = local_set_mapped_file_attr(fs_ctx, newpath, credp);
+         if (err == -1) {
+-            serrno = errno;
+             goto err_end;
+         }
+-    } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
+-               (fs_ctx->export_flags & V9FS_SM_NONE)) {
+-        buffer = rpath(fs_ctx, newpath);
+-        err = symlink(oldpath, buffer);
++    } else if (fs_ctx->export_flags & V9FS_SM_PASSTHROUGH ||
++               fs_ctx->export_flags & V9FS_SM_NONE) {
++        err = symlinkat(oldpath, dirfd, name);
+         if (err) {
+-            g_free(buffer);
+             goto out;
+         }
+-        err = lchown(buffer, credp->fc_uid, credp->fc_gid);
++        err = fchownat(dirfd, name, credp->fc_uid, credp->fc_gid,
++                       AT_SYMLINK_NOFOLLOW);
+         if (err == -1) {
+             /*
+              * If we fail to change ownership and if we are
+              * using security model none. Ignore the error
+              */
+             if ((fs_ctx->export_flags & V9FS_SEC_MASK) != V9FS_SM_NONE) {
+-                serrno = errno;
+                 goto err_end;
+-            } else
++            } else {
+                 err = 0;
++            }
+         }
+     }
+     goto out;
+ 
+ err_end:
+-    remove(buffer);
+-    errno = serrno;
+-    g_free(buffer);
++    unlinkat_preserve_errno(dirfd, name, 0);
+ out:
+-    v9fs_string_free(&fullname);
++    close_preserve_errno(dirfd);
+     return err;
+ }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-25.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-25.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-25.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-25.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,155 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From d815e7219036d6911fce12efe3e59906264c8536 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:44:54 +0100
+Subject: [PATCH] 9pfs: local: mknod: don't follow symlinks
+
+The local_mknod() callback is vulnerable to symlink attacks because it
+calls:
+
+(1) mknod() which follows symbolic links for all path elements but the
+    rightmost one
+(2) local_set_xattr()->setxattr() which follows symbolic links for all
+    path elements
+(3) local_set_mapped_file_attr() which calls in turn local_fopen() and
+    mkdir(), both functions following symbolic links for all path
+    elements but the rightmost one
+(4) local_post_create_passthrough() which calls in turn lchown() and
+    chmod(), both functions also following symbolic links
+
+This patch converts local_mknod() to rely on opendir_nofollow() and
+mknodat() to fix (1), as well as local_set_xattrat() and
+local_set_mapped_file_attrat() to fix (2) and (3) respectively.
+
+A new local_set_cred_passthrough() helper based on fchownat() and
+fchmodat_nofollow() is introduced as a replacement to
+local_post_create_passthrough() to fix (4).
+
+The mapped and mapped-file security modes are supposed to be identical,
+except for the place where credentials and file modes are stored. While
+here, we also make that explicit by sharing the call to mknodat().
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 68 ++++++++++++++++++++++++++++--------------------------
+ 1 file changed, 35 insertions(+), 33 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:44:35.673684625 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:46:59.295529938 -0400
+@@ -542,6 +542,23 @@
+     return -1;
+ }
+ 
++static int local_set_cred_passthrough(FsContext *fs_ctx, int dirfd,
++                                      const char *name, FsCred *credp)
++{
++    if (fchownat(dirfd, name, credp->fc_uid, credp->fc_gid,
++                 AT_SYMLINK_NOFOLLOW | AT_EMPTY_PATH) < 0) {
++        /*
++         * If we fail to change ownership and if we are
++         * using security model none. Ignore the error
++         */
++        if ((fs_ctx->export_flags & V9FS_SEC_MASK) != V9FS_SM_NONE) {
++            return -1;
++        }
++    }
++
++    return fchmodat_nofollow(dirfd, name, credp->fc_mode & 07777);
++}
++
+ static ssize_t local_readlink(FsContext *fs_ctx, V9fsPath *fs_path,
+                               char *buf, size_t bufsz)
+ {
+@@ -732,64 +749,45 @@
+ static int local_mknod(FsContext *fs_ctx, V9fsPath *dir_path,
+                        const char *name, FsCred *credp)
+ {
+-    char *path;
+     int err = -1;
+-    int serrno = 0;
+-    V9fsString fullname;
+-    char *buffer;
+-
+-    v9fs_string_init(&fullname);
+-    v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
+-    path = fullname.data;
++    int dirfd;
+ 
+-    /* Determine the security model */
+-    if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
+-        buffer = rpath(fs_ctx, path);
+-        err = mknod(buffer, SM_LOCAL_MODE_BITS|S_IFREG, 0);
+-        if (err == -1) {
+-            g_free(buffer);
+-            goto out;
+-        }
+-        err = local_set_xattr(buffer, credp);
+-        if (err == -1) {
+-            serrno = errno;
+-            goto err_end;
+-        }
+-    } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
++    dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
++    if (dirfd == -1) {
++        return -1;
++    }
+ 
+-        buffer = rpath(fs_ctx, path);
+-        err = mknod(buffer, SM_LOCAL_MODE_BITS|S_IFREG, 0);
++    if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
++        fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
++        err = mknodat(dirfd, name, SM_LOCAL_MODE_BITS | S_IFREG, 0);
+         if (err == -1) {
+-            g_free(buffer);
+             goto out;
+         }
+-        err = local_set_mapped_file_attr(fs_ctx, path, credp);
++        if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
++            err = local_set_xattrat(dirfd, name, credp);
++        } else {
++            err = local_set_mapped_file_attrat(dirfd, name, credp);
++        }
+         if (err == -1) {
+-            serrno = errno;
+             goto err_end;
+         }
+-    } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
+-               (fs_ctx->export_flags & V9FS_SM_NONE)) {
+-        buffer = rpath(fs_ctx, path);
+-        err = mknod(buffer, credp->fc_mode, credp->fc_rdev);
++    } else if (fs_ctx->export_flags & V9FS_SM_PASSTHROUGH ||
++               fs_ctx->export_flags & V9FS_SM_NONE) {
++        err = mknodat(dirfd, name, credp->fc_mode, credp->fc_rdev);
+         if (err == -1) {
+-            g_free(buffer);
+             goto out;
+         }
+-        err = local_post_create_passthrough(fs_ctx, path, credp);
++        err = local_set_cred_passthrough(fs_ctx, dirfd, name, credp);
+         if (err == -1) {
+-            serrno = errno;
+             goto err_end;
+         }
+     }
+     goto out;
+ 
+ err_end:
+-    remove(buffer);
+-    errno = serrno;
+-    g_free(buffer);
++    unlinkat_preserve_errno(dirfd, name, 0);
+ out:
+-    v9fs_string_free(&fullname);
++    close_preserve_errno(dirfd);
+     return err;
+ }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-26.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-26.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-26.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-26.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,130 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From 3f3a16990b09e62d787bd2eb2dd51aafbe90019a Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:45:02 +0100
+Subject: [PATCH] 9pfs: local: mkdir: don't follow symlinks
+
+The local_mkdir() callback is vulnerable to symlink attacks because it
+calls:
+
+(1) mkdir() which follows symbolic links for all path elements but the
+    rightmost one
+(2) local_set_xattr()->setxattr() which follows symbolic links for all
+    path elements
+(3) local_set_mapped_file_attr() which calls in turn local_fopen() and
+    mkdir(), both functions following symbolic links for all path
+    elements but the rightmost one
+(4) local_post_create_passthrough() which calls in turn lchown() and
+    chmod(), both functions also following symbolic links
+
+This patch converts local_mkdir() to rely on opendir_nofollow() and
+mkdirat() to fix (1), as well as local_set_xattrat(),
+local_set_mapped_file_attrat() and local_set_cred_passthrough() to
+fix (2), (3) and (4) respectively.
+
+The mapped and mapped-file security modes are supposed to be identical,
+except for the place where credentials and file modes are stored. While
+here, we also make that explicit by sharing the call to mkdirat().
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 55 ++++++++++++++++++++----------------------------------
+ 1 file changed, 20 insertions(+), 35 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:47:47.348147338 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:49:54.265778028 -0400
+@@ -794,65 +794,47 @@
+ static int local_mkdir(FsContext *fs_ctx, V9fsPath *dir_path,
+                        const char *name, FsCred *credp)
+ {
+-    char *path;
+     int err = -1;
+-    int serrno = 0;
+-    V9fsString fullname;
+-    char *buffer;
++    int dirfd;
+ 
+-    v9fs_string_init(&fullname);
+-    v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
+-    path = fullname.data;
++    dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
++    if (dirfd == -1) {
++        return -1;
++    }
+ 
+-    /* Determine the security model */
+-    if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
+-        buffer = rpath(fs_ctx, path);
+-        err = mkdir(buffer, SM_LOCAL_DIR_MODE_BITS);
++    if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
++        fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
++        err = mkdirat(dirfd, name, SM_LOCAL_DIR_MODE_BITS);
+         if (err == -1) {
+-            g_free(buffer);
+             goto out;
+         }
+-        credp->fc_mode = credp->fc_mode|S_IFDIR;
+-        err = local_set_xattr(buffer, credp);
+-        if (err == -1) {
+-            serrno = errno;
+-            goto err_end;
+-        }
+-    } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+-        buffer = rpath(fs_ctx, path);
+-        err = mkdir(buffer, SM_LOCAL_DIR_MODE_BITS);
+-        if (err == -1) {
+-            g_free(buffer);
+-            goto out;
++        credp->fc_mode = credp->fc_mode | S_IFDIR;
++
++        if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
++            err = local_set_xattrat(dirfd, name, credp);
++        } else {
++            err = local_set_mapped_file_attrat(dirfd, name, credp);
+         }
+-        credp->fc_mode = credp->fc_mode|S_IFDIR;
+-        err = local_set_mapped_file_attr(fs_ctx, path, credp);
+         if (err == -1) {
+-            serrno = errno;
+             goto err_end;
+         }
+-    } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
+-               (fs_ctx->export_flags & V9FS_SM_NONE)) {
+-        buffer = rpath(fs_ctx, path);
+-        err = mkdir(buffer, credp->fc_mode);
++    } else if (fs_ctx->export_flags & V9FS_SM_PASSTHROUGH ||
++               fs_ctx->export_flags & V9FS_SM_NONE) {
++        err = mkdirat(dirfd, name, credp->fc_mode);
+         if (err == -1) {
+-            g_free(buffer);
+             goto out;
+         }
+-        err = local_post_create_passthrough(fs_ctx, path, credp);
++        err = local_set_cred_passthrough(fs_ctx, dirfd, name, credp);
+         if (err == -1) {
+-            serrno = errno;
+             goto err_end;
+         }
+     }
+     goto out;
+ 
+ err_end:
+-    remove(buffer);
+-    errno = serrno;
+-    g_free(buffer);
++    unlinkat_preserve_errno(dirfd, name, AT_REMOVEDIR);
+ out:
+-    v9fs_string_free(&fullname);
++    close_preserve_errno(dirfd);
+     return err;
+ }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-27.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-27.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-27.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-27.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,144 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From a565fea56546e254b7610305b07711f0a3bda0c7 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:45:09 +0100
+Subject: [PATCH] 9pfs: local: open2: don't follow symlinks
+
+The local_open2() callback is vulnerable to symlink attacks because it
+calls:
+
+(1) open() which follows symbolic links for all path elements but the
+    rightmost one
+(2) local_set_xattr()->setxattr() which follows symbolic links for all
+    path elements
+(3) local_set_mapped_file_attr() which calls in turn local_fopen() and
+    mkdir(), both functions following symbolic links for all path
+    elements but the rightmost one
+(4) local_post_create_passthrough() which calls in turn lchown() and
+    chmod(), both functions also following symbolic links
+
+This patch converts local_open2() to rely on opendir_nofollow() and
+mkdirat() to fix (1), as well as local_set_xattrat(),
+local_set_mapped_file_attrat() and local_set_cred_passthrough() to
+fix (2), (3) and (4) respectively. Since local_open2() already opens
+a descriptor to the target file, local_set_cred_passthrough() is
+modified to reuse it instead of opening a new one.
+
+The mapped and mapped-file security modes are supposed to be identical,
+except for the place where credentials and file modes are stored. While
+here, we also make that explicit by sharing the call to openat().
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 56 ++++++++++++++++++------------------------------------
+ 1 file changed, 19 insertions(+), 37 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:50:11.093994244 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:53:00.292168172 -0400
+@@ -886,65 +886,45 @@
+ static int local_open2(FsContext *fs_ctx, V9fsPath *dir_path, const char *name,
+                        int flags, FsCred *credp, V9fsFidOpenState *fs)
+ {
+-    char *path;
+     int fd = -1;
+     int err = -1;
+-    int serrno = 0;
+-    V9fsString fullname;
+-    char *buffer;
++    int dirfd;
+ 
+     /*
+      * Mark all the open to not follow symlinks
+      */
+     flags |= O_NOFOLLOW;
+ 
+-    v9fs_string_init(&fullname);
+-    v9fs_string_sprintf(&fullname, "%s/%s", dir_path->data, name);
+-    path = fullname.data;
++    dirfd = local_opendir_nofollow(fs_ctx, dir_path->data);
++    if (dirfd == -1) {
++        return -1;
++    }
+ 
+     /* Determine the security model */
+-    if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
+-        buffer = rpath(fs_ctx, path);
+-        fd = open(buffer, flags, SM_LOCAL_MODE_BITS);
++    if (fs_ctx->export_flags & V9FS_SM_MAPPED ||
++        fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
++        fd = openat_file(dirfd, name, flags, SM_LOCAL_MODE_BITS);
+         if (fd == -1) {
+-            g_free(buffer);
+-            err = fd;
+             goto out;
+         }
+         credp->fc_mode = credp->fc_mode|S_IFREG;
+-        /* Set cleint credentials in xattr */
+-        err = local_set_xattr(buffer, credp);
+-        if (err == -1) {
+-            serrno = errno;
+-            goto err_end;
++        if (fs_ctx->export_flags & V9FS_SM_MAPPED) {
++            /* Set cleint credentials in xattr */
++            err = local_set_xattrat(dirfd, name, credp);
++        } else {
++            err = local_set_mapped_file_attrat(dirfd, name, credp);
+         }
+-    } else if (fs_ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+-        buffer = rpath(fs_ctx, path);
+-        fd = open(buffer, flags, SM_LOCAL_MODE_BITS);
+-        if (fd == -1) {
+-            g_free(buffer);
+-            err = fd;
+-            goto out;
+-        }
+-        credp->fc_mode = credp->fc_mode|S_IFREG;
+-        /* Set client credentials in .virtfs_metadata directory files */
+-        err = local_set_mapped_file_attr(fs_ctx, path, credp);
+         if (err == -1) {
+-            serrno = errno;
+             goto err_end;
+         }
+     } else if ((fs_ctx->export_flags & V9FS_SM_PASSTHROUGH) ||
+                (fs_ctx->export_flags & V9FS_SM_NONE)) {
+-        buffer = rpath(fs_ctx, path);
+-        fd = open(buffer, flags, credp->fc_mode);
++        fd = openat_file(dirfd, name, flags, credp->fc_mode);
+         if (fd == -1) {
+-            g_free(buffer);
+-            err = fd;
+             goto out;
+         }
+-        err = local_post_create_passthrough(fs_ctx, path, credp);
++        err = local_set_cred_passthrough(fs_ctx, dirfd, name, credp);
+         if (err == -1) {
+-            serrno = errno;
+             goto err_end;
+         }
+     }
+@@ -953,12 +933,11 @@
+     goto out;
+ 
+ err_end:
+-    close(fd);
+-    remove(buffer);
+-    errno = serrno;
+-    g_free(buffer);
++    unlinkat_preserve_errno(dirfd, name,
++                            flags & O_DIRECTORY ? AT_REMOVEDIR : 0);
++    close_preserve_errno(fd);
+ out:
+-    v9fs_string_free(&fullname);
++    close_preserve_errno(dirfd);
+     return err;
+ }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-28.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-28.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-28.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-28.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,244 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From c23d5f1d5bc0e23aeb845b1af8f996f16783ce98 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:45:17 +0100
+Subject: [PATCH] 9pfs: local: drop unused code
+
+Now that the all callbacks have been converted to use "at" syscalls, we
+can drop this code.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 198 -----------------------------------------------------
+ 1 file changed, 198 deletions(-)
+
+Index: qemu/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu.orig/hw/9pfs/virtio-9p-local.c
++++ qemu/hw/9pfs/virtio-9p-local.c
+@@ -82,50 +82,6 @@ static void unlinkat_preserve_errno(int
+ 
+ #define VIRTFS_META_DIR ".virtfs_metadata"
+ 
+-static char *local_mapped_attr_path(FsContext *ctx, const char *path)
+-{
+-    char *dir_name;
+-    char *tmp_path = g_strdup(path);
+-    char *base_name = basename(tmp_path);
+-    char *buffer;
+-
+-    /* NULL terminate the directory */
+-    dir_name = tmp_path;
+-    *(base_name - 1) = '\0';
+-
+-    buffer = g_strdup_printf("%s/%s/%s/%s",
+-             ctx->fs_root, dir_name, VIRTFS_META_DIR, base_name);
+-    g_free(tmp_path);
+-    return buffer;
+-}
+-
+-static FILE *local_fopen(const char *path, const char *mode)
+-{
+-    int fd, o_mode = 0;
+-    FILE *fp;
+-    int flags = O_NOFOLLOW;
+-    /*
+-     * only supports two modes
+-     */
+-    if (mode[0] == 'r') {
+-        flags |= O_RDONLY;
+-    } else if (mode[0] == 'w') {
+-        flags |= O_WRONLY | O_TRUNC | O_CREAT;
+-        o_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+-    } else {
+-        return NULL;
+-    }
+-    fd = open(path, flags, o_mode);
+-    if (fd == -1) {
+-        return NULL;
+-    }
+-    fp = fdopen(fd, mode);
+-    if (!fp) {
+-        close(fd);
+-    }
+-    return fp;
+-}
+-
+ static FILE *local_fopenat(int dirfd, const char *name, const char *mode)
+ {
+     int fd, o_mode = 0;
+@@ -239,135 +195,6 @@ out:
+     return err;
+ }
+ 
+-static int local_create_mapped_attr_dir(FsContext *ctx, const char *path)
+-{
+-    int err;
+-    char *attr_dir;
+-    char *tmp_path = g_strdup(path);
+-
+-    attr_dir = g_strdup_printf("%s/%s/%s",
+-             ctx->fs_root, dirname(tmp_path), VIRTFS_META_DIR);
+-
+-    err = mkdir(attr_dir, 0700);
+-    if (err < 0 && errno == EEXIST) {
+-        err = 0;
+-    }
+-    g_free(attr_dir);
+-    g_free(tmp_path);
+-    return err;
+-}
+-
+-static int local_set_mapped_file_attr(FsContext *ctx,
+-                                      const char *path, FsCred *credp)
+-{
+-    FILE *fp;
+-    int ret = 0;
+-    char buf[ATTR_MAX];
+-    char *attr_path;
+-    int uid = -1, gid = -1, mode = -1, rdev = -1;
+-
+-    attr_path = local_mapped_attr_path(ctx, path);
+-    fp = local_fopen(attr_path, "r");
+-    if (!fp) {
+-        goto create_map_file;
+-    }
+-    memset(buf, 0, ATTR_MAX);
+-    while (fgets(buf, ATTR_MAX, fp)) {
+-        if (!strncmp(buf, "virtfs.uid", 10)) {
+-            uid = atoi(buf+11);
+-        } else if (!strncmp(buf, "virtfs.gid", 10)) {
+-            gid = atoi(buf+11);
+-        } else if (!strncmp(buf, "virtfs.mode", 11)) {
+-            mode = atoi(buf+12);
+-        } else if (!strncmp(buf, "virtfs.rdev", 11)) {
+-            rdev = atoi(buf+12);
+-        }
+-        memset(buf, 0, ATTR_MAX);
+-    }
+-    fclose(fp);
+-    goto update_map_file;
+-
+-create_map_file:
+-    ret = local_create_mapped_attr_dir(ctx, path);
+-    if (ret < 0) {
+-        goto err_out;
+-    }
+-
+-update_map_file:
+-    fp = local_fopen(attr_path, "w");
+-    if (!fp) {
+-        ret = -1;
+-        goto err_out;
+-    }
+-
+-    if (credp->fc_uid != -1) {
+-        uid = credp->fc_uid;
+-    }
+-    if (credp->fc_gid != -1) {
+-        gid = credp->fc_gid;
+-    }
+-    if (credp->fc_mode != -1) {
+-        mode = credp->fc_mode;
+-    }
+-    if (credp->fc_rdev != -1) {
+-        rdev = credp->fc_rdev;
+-    }
+-
+-
+-    if (uid != -1) {
+-        fprintf(fp, "virtfs.uid=%d\n", uid);
+-    }
+-    if (gid != -1) {
+-        fprintf(fp, "virtfs.gid=%d\n", gid);
+-    }
+-    if (mode != -1) {
+-        fprintf(fp, "virtfs.mode=%d\n", mode);
+-    }
+-    if (rdev != -1) {
+-        fprintf(fp, "virtfs.rdev=%d\n", rdev);
+-    }
+-    fclose(fp);
+-
+-err_out:
+-    g_free(attr_path);
+-    return ret;
+-}
+-
+-static int local_set_xattr(const char *path, FsCred *credp)
+-{
+-    int err;
+-
+-    if (credp->fc_uid != -1) {
+-        uint32_t tmp_uid = cpu_to_le32(credp->fc_uid);
+-        err = setxattr(path, "user.virtfs.uid", &tmp_uid, sizeof(uid_t), 0);
+-        if (err) {
+-            return err;
+-        }
+-    }
+-    if (credp->fc_gid != -1) {
+-        uint32_t tmp_gid = cpu_to_le32(credp->fc_gid);
+-        err = setxattr(path, "user.virtfs.gid", &tmp_gid, sizeof(gid_t), 0);
+-        if (err) {
+-            return err;
+-        }
+-    }
+-    if (credp->fc_mode != -1) {
+-        uint32_t tmp_mode = cpu_to_le32(credp->fc_mode);
+-        err = setxattr(path, "user.virtfs.mode", &tmp_mode, sizeof(mode_t), 0);
+-        if (err) {
+-            return err;
+-        }
+-    }
+-    if (credp->fc_rdev != -1) {
+-        uint64_t tmp_rdev = cpu_to_le64(credp->fc_rdev);
+-        err = setxattr(path, "user.virtfs.rdev", &tmp_rdev, sizeof(dev_t), 0);
+-        if (err) {
+-            return err;
+-        }
+-    }
+-    return 0;
+-}
+-
+ static int local_set_mapped_file_attrat(int dirfd, const char *name,
+                                         FsCred *credp)
+ {
+@@ -517,33 +344,6 @@ static int local_set_xattrat(int dirfd,
+     return 0;
+ }
+ 
+-static int local_post_create_passthrough(FsContext *fs_ctx, const char *path,
+-                                         FsCred *credp)
+-{
+-    char *buffer;
+-
+-    buffer = rpath(fs_ctx, path);
+-    if (lchown(buffer, credp->fc_uid, credp->fc_gid) < 0) {
+-        /*
+-         * If we fail to change ownership and if we are
+-         * using security model none. Ignore the error
+-         */
+-        if ((fs_ctx->export_flags & V9FS_SEC_MASK) != V9FS_SM_NONE) {
+-            goto err;
+-        }
+-    }
+-
+-    if (chmod(buffer, credp->fc_mode & 07777) < 0) {
+-        goto err;
+-    }
+-
+-    g_free(buffer);
+-    return 0;
+-err:
+-    g_free(buffer);
+-    return -1;
+-}
+-
+ static int local_set_cred_passthrough(FsContext *fs_ctx, int dirfd,
+                                       const char *name, FsCred *credp)
+ {
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-29.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-29.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-29.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-29.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,53 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From b003fc0d8aa5e7060dbf7e5862b8013c73857c7f Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Mon, 6 Mar 2017 17:34:01 +0100
+Subject: [PATCH] 9pfs: fix vulnerability in openat_dir() and
+ local_unlinkat_common()
+
+We should pass O_NOFOLLOW otherwise openat() will follow symlinks and make
+QEMU vulnerable.
+
+While here, we also fix local_unlinkat_common() to use openat_dir() for
+the same reasons (it was a leftover in the original patchset actually).
+
+This fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Daniel P. Berrange <berrange@redhat.com>
+Reviewed-by: Eric Blake <eblake@redhat.com>
+---
+ hw/9pfs/9p-local.c | 2 +-
+ hw/9pfs/9p-util.h  | 3 ++-
+ 2 files changed, 3 insertions(+), 2 deletions(-)
+
+Index: qemu-2.5+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.5+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-04 14:05:54.056515474 -0400
++++ qemu-2.5+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-04 14:05:54.052515422 -0400
+@@ -956,7 +956,7 @@
+         if (flags == AT_REMOVEDIR) {
+             int fd;
+ 
+-            fd = openat(dirfd, name, O_RDONLY | O_DIRECTORY | O_PATH);
++            fd = openat_dir(dirfd, name);
+             if (fd == -1) {
+                 goto err_out;
+             }
+Index: qemu-2.5+dfsg/hw/9pfs/virtio-9p-util.h
+===================================================================
+--- qemu-2.5+dfsg.orig/hw/9pfs/virtio-9p-util.h	2017-04-04 14:05:54.056515474 -0400
++++ qemu-2.5+dfsg/hw/9pfs/virtio-9p-util.h	2017-04-04 14:05:54.056515474 -0400
+@@ -22,7 +22,7 @@
+ 
+ static inline int openat_dir(int dirfd, const char *name)
+ {
+-    return openat(dirfd, name, O_DIRECTORY | O_RDONLY | O_PATH);
++    return openat(dirfd, name, O_DIRECTORY | O_RDONLY | O_NOFOLLOW | O_PATH);
+ }
+ 
+ static inline int openat_file(int dirfd, const char *name, int flags,
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-2.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-2.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-2.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-2.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,75 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From 00c90bd1c2ff6aabb9ca948a254ba044a403e399 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:41:48 +0100
+Subject: [PATCH] 9pfs: remove side-effects in local_init()
+
+If this function fails, it should not modify *ctx.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 37 +++++++++++++++++++------------------
+ 1 file changed, 19 insertions(+), 18 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:29:08.129767157 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:29:08.125767106 -0400
+@@ -1183,9 +1183,25 @@
+ 
+ static int local_init(FsContext *ctx)
+ {
+-    int err = 0;
+     struct statfs stbuf;
+ 
++#ifdef FS_IOC_GETVERSION
++    /*
++     * use ioc_getversion only if the ioctl is definied
++     */
++    if (statfs(ctx->fs_root, &stbuf) < 0) {
++        return -1;
++    }
++    switch (stbuf.f_type) {
++    case EXT2_SUPER_MAGIC:
++    case BTRFS_SUPER_MAGIC:
++    case REISERFS_SUPER_MAGIC:
++    case XFS_SUPER_MAGIC:
++        ctx->exops.get_st_gen = local_ioc_getversion;
++        break;
++    }
++#endif
++
+     if (ctx->export_flags & V9FS_SM_PASSTHROUGH) {
+         ctx->xops = passthrough_xattr_ops;
+     } else if (ctx->export_flags & V9FS_SM_MAPPED) {
+@@ -1200,23 +1216,8 @@
+         ctx->xops = passthrough_xattr_ops;
+     }
+     ctx->export_flags |= V9FS_PATHNAME_FSCONTEXT;
+-#ifdef FS_IOC_GETVERSION
+-    /*
+-     * use ioc_getversion only if the iocl is definied
+-     */
+-    err = statfs(ctx->fs_root, &stbuf);
+-    if (!err) {
+-        switch (stbuf.f_type) {
+-        case EXT2_SUPER_MAGIC:
+-        case BTRFS_SUPER_MAGIC:
+-        case REISERFS_SUPER_MAGIC:
+-        case XFS_SUPER_MAGIC:
+-            ctx->exops.get_st_gen = local_ioc_getversion;
+-            break;
+-        }
+-    }
+-#endif
+-    return err;
++
++    return 0;
+ }
+ 
+ static int local_parse_opts(QemuOpts *opts, struct FsDriverEntry *fse)
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-3.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-3.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-3.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-3.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,58 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From 21328e1e57f526e3f0c2fcd00f10c8aa6e7bc07f Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:41:55 +0100
+Subject: [PATCH] 9pfs: remove side-effects in local_open() and local_opendir()
+
+If these functions fail, they should not change *fs. Let's use local
+variables to fix this.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 13 ++++++++++---
+ 1 file changed, 10 insertions(+), 3 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-local.c	2017-04-05 11:31:19.635456797 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c	2017-04-05 11:31:19.631456746 -0400
+@@ -356,10 +356,15 @@
+ {
+     char *buffer;
+     char *path = fs_path->data;
++    int fd;
+ 
+     buffer = rpath(ctx, path);
+-    fs->fd = open(buffer, flags | O_NOFOLLOW);
++    fd = open(buffer, flags | O_NOFOLLOW);
+     g_free(buffer);
++    if (fd == -1) {
++        return -1;
++    }
++    fs->fd = fd;
+     return fs->fd;
+ }
+ 
+@@ -368,13 +373,15 @@
+ {
+     char *buffer;
+     char *path = fs_path->data;
++    DIR *stream;
+ 
+     buffer = rpath(ctx, path);
+-    fs->dir = opendir(buffer);
++    stream = opendir(buffer);
+     g_free(buffer);
+-    if (!fs->dir) {
++    if (!stream) {
+         return -1;
+     }
++    fs->dir = stream;
+     return 0;
+ }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-4.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-4.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-4.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-4.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,191 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From 6482a961636d66cc10928dde5d4d908206e5f65a Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:42:03 +0100
+Subject: [PATCH] 9pfs: introduce relative_openat_nofollow() helper
+
+When using the passthrough security mode, symbolic links created by the
+guest are actual symbolic links on the host file system.
+
+Since the resolution of symbolic links during path walk is supposed to
+occur on the client side. The server should hence never receive any path
+pointing to an actual symbolic link. This isn't guaranteed by the protocol
+though, and malicious code in the guest can trick the server to issue
+various syscalls on paths whose one or more elements are symbolic links.
+In the case of the "local" backend using the "passthrough" or "none"
+security modes, the guest can directly create symbolic links to arbitrary
+locations on the host (as per spec). The "mapped-xattr" and "mapped-file"
+security modes are also affected to a lesser extent as they require some
+help from an external entity to create actual symbolic links on the host,
+i.e. another guest using "passthrough" mode for example.
+
+The current code hence relies on O_NOFOLLOW and "l*()" variants of system
+calls. Unfortunately, this only applies to the rightmost path component.
+A guest could maliciously replace any component in a trusted path with a
+symbolic link. This could allow any guest to escape a virtfs shared folder.
+
+This patch introduces a variant of the openat() syscall that successively
+opens each path element with O_NOFOLLOW. When passing a file descriptor
+pointing to a trusted directory, one is guaranteed to be returned a
+file descriptor pointing to a path which is beneath the trusted directory.
+This will be used by subsequent patches to implement symlink-safe path walk
+for any access to the backend.
+
+Symbolic links aren't the only threats actually: a malicious guest could
+change a path element to point to other types of file with undesirable
+effects:
+- a named pipe or any other thing that would cause openat() to block
+- a terminal device which would become QEMU's controlling terminal
+
+These issues can be addressed with O_NONBLOCK and O_NOCTTY.
+
+Two helpers are introduced: one to open intermediate path elements and one
+to open the rightmost path element.
+
+Suggested-by: Jann Horn <jannh@google.com>
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+(renamed openat_nofollow() to relative_openat_nofollow(),
+ assert path is relative and doesn't contain '//',
+ fixed side-effect in assert, Greg Kurz)
+Signed-off-by: Greg Kurz <groug@kaod.org>
+---
+ hw/9pfs/9p-util.c     | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++
+ hw/9pfs/9p-util.h     | 50 ++++++++++++++++++++++++++++++++++++++++++++
+ hw/9pfs/Makefile.objs |  2 +-
+ 3 files changed, 108 insertions(+), 1 deletion(-)
+ create mode 100644 hw/9pfs/9p-util.c
+ create mode 100644 hw/9pfs/9p-util.h
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-util.c
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-util.c	2017-04-06 08:58:38.617979891 -0400
+@@ -0,0 +1,58 @@
++/*
++ * 9p utilities
++ *
++ * Copyright IBM, Corp. 2017
++ *
++ * Authors:
++ *  Greg Kurz <groug@kaod.org>
++ *
++ * This work is licensed under the terms of the GNU GPL, version 2 or later.
++ * See the COPYING file in the top-level directory.
++ */
++
++#include "qemu/osdep.h"
++#include "hw/virtio/virtio.h"
++#include "virtio-9p-util.h"
++
++int relative_openat_nofollow(int dirfd, const char *path, int flags,
++                             mode_t mode)
++{
++    int fd;
++
++    fd = dup(dirfd);
++    if (fd == -1) {
++        return -1;
++    }
++
++    while (*path) {
++        const char *c;
++        int next_fd;
++        char *head;
++
++        /* Only relative paths without consecutive slashes */
++        assert(path[0] != '/');
++
++        head = g_strdup(path);
++        c = strchr(path, '/');
++        if (c) {
++            head[c - path] = 0;
++            next_fd = openat_dir(fd, head);
++        } else {
++            next_fd = openat_file(fd, head, flags, mode);
++        }
++        g_free(head);
++        if (next_fd == -1) {
++            close_preserve_errno(fd);
++            return -1;
++        }
++        close(fd);
++        fd = next_fd;
++
++        if (!c) {
++            break;
++        }
++        path = c + 1;
++    }
++
++    return fd;
++}
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-util.h
+===================================================================
+--- /dev/null	1970-01-01 00:00:00.000000000 +0000
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-util.h	2017-04-06 08:58:23.481788107 -0400
+@@ -0,0 +1,50 @@
++/*
++ * 9p utilities
++ *
++ * Copyright IBM, Corp. 2017
++ *
++ * Authors:
++ *  Greg Kurz <groug@kaod.org>
++ *
++ * This work is licensed under the terms of the GNU GPL, version 2 or later.
++ * See the COPYING file in the top-level directory.
++ */
++
++#ifndef QEMU_9P_UTIL_H
++#define QEMU_9P_UTIL_H
++
++static inline void close_preserve_errno(int fd)
++{
++    int serrno = errno;
++    close(fd);
++    errno = serrno;
++}
++
++static inline int openat_dir(int dirfd, const char *name)
++{
++    return openat(dirfd, name, O_DIRECTORY | O_RDONLY | O_PATH);
++}
++
++static inline int openat_file(int dirfd, const char *name, int flags,
++                              mode_t mode)
++{
++    int fd, serrno, ret;
++
++    fd = openat(dirfd, name, flags | O_NOFOLLOW | O_NOCTTY | O_NONBLOCK,
++                mode);
++    if (fd == -1) {
++        return -1;
++    }
++
++    serrno = errno;
++    /* O_NONBLOCK was only needed to open the file. Let's drop it. */
++    ret = fcntl(fd, F_SETFL, flags);
++    assert(!ret);
++    errno = serrno;
++    return fd;
++}
++
++int relative_openat_nofollow(int dirfd, const char *path, int flags,
++                             mode_t mode);
++
++#endif
+Index: qemu-2.0.0+dfsg/hw/9pfs/Makefile.objs
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/Makefile.objs	2017-04-06 08:58:23.481788107 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/Makefile.objs	2017-04-06 08:58:23.481788107 -0400
+@@ -1,4 +1,4 @@
+-common-obj-y  = virtio-9p.o
++common-obj-y  = virtio-9p.o virtio-9p-util.o
+ common-obj-y += virtio-9p-local.o virtio-9p-xattr.o
+ common-obj-y += virtio-9p-xattr-user.o virtio-9p-posix-acl.o
+ common-obj-y += virtio-9p-coth.o cofs.o codir.o cofile.o
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-5.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-5.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-5.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-5.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,94 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From 0e35a3782948c6154d7fafe9a02a86bc130199c7 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:42:10 +0100
+Subject: [PATCH] 9pfs: local: keep a file descriptor on the shared folder
+
+This patch opens the shared folder and caches the file descriptor, so that
+it can be used to do symlink-safe path walk.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 30 ++++++++++++++++++++++++++++--
+ 1 file changed, 28 insertions(+), 2 deletions(-)
+
+Index: qemu/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu.orig/hw/9pfs/virtio-9p-local.c
++++ qemu/hw/9pfs/virtio-9p-local.c
+@@ -14,6 +14,7 @@
+ #include "hw/virtio/virtio.h"
+ #include "virtio-9p.h"
+ #include "virtio-9p-xattr.h"
++#include "virtio-9p-util.h"
+ #include "fsdev/qemu-fsdev.h"   /* local_ops */
+ #include <arpa/inet.h>
+ #include <pwd.h>
+@@ -41,6 +42,10 @@
+ #define BTRFS_SUPER_MAGIC 0x9123683E
+ #endif
+ 
++typedef struct {
++    int mountfd;
++} LocalData;
++
+ #define VIRTFS_META_DIR ".virtfs_metadata"
+ 
+ static char *local_mapped_attr_path(FsContext *ctx, const char *path)
+@@ -1192,13 +1197,20 @@ static int local_ioc_getversion(FsContex
+ static int local_init(FsContext *ctx)
+ {
+     struct statfs stbuf;
++    LocalData *data = g_malloc(sizeof(*data));
++
++    data->mountfd = open(ctx->fs_root, O_DIRECTORY | O_RDONLY);
++    if (data->mountfd == -1) {
++        goto err;
++    }
+ 
+ #ifdef FS_IOC_GETVERSION
+     /*
+      * use ioc_getversion only if the ioctl is definied
+      */
+-    if (statfs(ctx->fs_root, &stbuf) < 0) {
+-        return -1;
++    if (fstatfs(data->mountfd, &stbuf) < 0) {
++        close_preserve_errno(data->mountfd);
++        goto err;
+     }
+     switch (stbuf.f_type) {
+     case EXT2_SUPER_MAGIC:
+@@ -1225,7 +1237,20 @@ static int local_init(FsContext *ctx)
+     }
+     ctx->export_flags |= V9FS_PATHNAME_FSCONTEXT;
+ 
++    ctx->private = data;
+     return 0;
++
++err:
++    g_free(data);
++    return -1;
++}
++
++static void local_cleanup(FsContext *ctx)
++{
++    LocalData *data = ctx->private;
++
++    close(data->mountfd);
++    g_free(data);
+ }
+ 
+ static int local_parse_opts(QemuOpts *opts, struct FsDriverEntry *fse)
+@@ -1268,6 +1293,7 @@ static int local_parse_opts(QemuOpts *op
+ FileOperations local_ops = {
+     .parse_opts = local_parse_opts,
+     .init  = local_init,
++    .cleanup = local_cleanup,
+     .lstat = local_lstat,
+     .readlink = local_readlink,
+     .close = local_close,
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-6.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-6.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-6.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-6.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,129 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From 996a0d76d7e756e4023ef79bc37bfe629b9eaca7 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:42:18 +0100
+Subject: [PATCH] 9pfs: local: open/opendir: don't follow symlinks
+
+The local_open() and local_opendir() callbacks are vulnerable to symlink
+attacks because they call:
+
+(1) open(O_NOFOLLOW) which follows symbolic links in all path elements but
+    the rightmost one
+(2) opendir() which follows symbolic links in all path elements
+
+This patch converts both callbacks to use new helpers based on
+openat_nofollow() to only open files and directories if they are
+below the virtfs shared folder
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-local.c | 37 +++++++++++++++++++++++++++----------
+ hw/9pfs/9p-local.h | 20 ++++++++++++++++++++
+ 2 files changed, 47 insertions(+), 10 deletions(-)
+ create mode 100644 hw/9pfs/9p-local.h
+
+Index: qemu/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu.orig/hw/9pfs/virtio-9p-local.c
++++ qemu/hw/9pfs/virtio-9p-local.c
+@@ -13,6 +13,7 @@
+ 
+ #include "hw/virtio/virtio.h"
+ #include "virtio-9p.h"
++#include "virtio-9p-local.h"
+ #include "virtio-9p-xattr.h"
+ #include "virtio-9p-util.h"
+ #include "fsdev/qemu-fsdev.h"   /* local_ops */
+@@ -46,6 +47,24 @@ typedef struct {
+     int mountfd;
+ } LocalData;
+ 
++int local_open_nofollow(FsContext *fs_ctx, const char *path, int flags,
++                        mode_t mode)
++{
++    LocalData *data = fs_ctx->private;
++
++    /* All paths are relative to the path data->mountfd points to */
++    while (*path == '/') {
++        path++;
++    }
++
++    return relative_openat_nofollow(data->mountfd, path, flags, mode);
++}
++
++int local_opendir_nofollow(FsContext *fs_ctx, const char *path)
++{
++    return local_open_nofollow(fs_ctx, path, O_DIRECTORY | O_RDONLY, 0);
++}
++
+ #define VIRTFS_META_DIR ".virtfs_metadata"
+ 
+ static char *local_mapped_attr_path(FsContext *ctx, const char *path)
+@@ -360,13 +379,9 @@ static int local_closedir(FsContext *ctx
+ static int local_open(FsContext *ctx, V9fsPath *fs_path,
+                       int flags, V9fsFidOpenState *fs)
+ {
+-    char *buffer;
+-    char *path = fs_path->data;
+     int fd;
+ 
+-    buffer = rpath(ctx, path);
+-    fd = open(buffer, flags | O_NOFOLLOW);
+-    g_free(buffer);
++    fd = local_open_nofollow(ctx, fs_path->data, flags, 0);
+     if (fd == -1) {
+         return -1;
+     }
+@@ -377,13 +392,15 @@ static int local_open(FsContext *ctx, V9
+ static int local_opendir(FsContext *ctx,
+                          V9fsPath *fs_path, V9fsFidOpenState *fs)
+ {
+-    char *buffer;
+-    char *path = fs_path->data;
++    int dirfd;
+     DIR *stream;
+ 
+-    buffer = rpath(ctx, path);
+-    stream = opendir(buffer);
+-    g_free(buffer);
++    dirfd = local_opendir_nofollow(ctx, fs_path->data);
++    if (dirfd == -1) {
++        return -1;
++    }
++
++    stream = fdopendir(dirfd);
+     if (!stream) {
+         return -1;
+     }
+Index: qemu/hw/9pfs/virtio-9p-local.h
+===================================================================
+--- /dev/null
++++ qemu/hw/9pfs/virtio-9p-local.h
+@@ -0,0 +1,20 @@
++/*
++ * 9p local backend utilities
++ *
++ * Copyright IBM, Corp. 2017
++ *
++ * Authors:
++ *  Greg Kurz <groug@kaod.org>
++ *
++ * This work is licensed under the terms of the GNU GPL, version 2 or later.
++ * See the COPYING file in the top-level directory.
++ */
++
++#ifndef QEMU_9P_LOCAL_H
++#define QEMU_9P_LOCAL_H
++
++int local_open_nofollow(FsContext *fs_ctx, const char *path, int flags,
++                        mode_t mode);
++int local_opendir_nofollow(FsContext *fs_ctx, const char *path);
++
++#endif
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-7.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-7.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-7.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-7.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,197 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From 56ad3e54dad6cdcee8668d170df161d89581846f Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:42:26 +0100
+Subject: [PATCH] 9pfs: local: lgetxattr: don't follow symlinks
+
+The local_lgetxattr() callback is vulnerable to symlink attacks because
+it calls lgetxattr() which follows symbolic links in all path elements but
+the rightmost one.
+
+This patch introduces a helper to emulate the non-existing fgetxattrat()
+function: it is implemented with /proc/self/fd which provides a trusted
+path that can be safely passed to lgetxattr().
+
+local_lgetxattr() is converted to use this helper and opendir_nofollow().
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-posix-acl.c  | 16 ++--------------
+ hw/9pfs/9p-util.c       | 12 ++++++++++++
+ hw/9pfs/9p-util.h       |  2 ++
+ hw/9pfs/9p-xattr-user.c |  8 +-------
+ hw/9pfs/9p-xattr.c      | 31 ++++++++++++++++++++++++-------
+ hw/9pfs/9p-xattr.h      |  2 ++
+ 6 files changed, 43 insertions(+), 28 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-posix-acl.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-posix-acl.c	2017-04-06 08:58:51.798146797 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-posix-acl.c	2017-04-06 08:58:51.794146746 -0400
+@@ -26,13 +26,7 @@
+ static ssize_t mp_pacl_getxattr(FsContext *ctx, const char *path,
+                                 const char *name, void *value, size_t size)
+ {
+-    char *buffer;
+-    ssize_t ret;
+-
+-    buffer = rpath(ctx, path);
+-    ret = lgetxattr(buffer, MAP_ACL_ACCESS, value, size);
+-    g_free(buffer);
+-    return ret;
++    return local_getxattr_nofollow(ctx, path, MAP_ACL_ACCESS, value, size);
+ }
+ 
+ static ssize_t mp_pacl_listxattr(FsContext *ctx, const char *path,
+@@ -90,13 +84,7 @@
+ static ssize_t mp_dacl_getxattr(FsContext *ctx, const char *path,
+                                 const char *name, void *value, size_t size)
+ {
+-    char *buffer;
+-    ssize_t ret;
+-
+-    buffer = rpath(ctx, path);
+-    ret = lgetxattr(buffer, MAP_ACL_DEFAULT, value, size);
+-    g_free(buffer);
+-    return ret;
++    return local_getxattr_nofollow(ctx, path, MAP_ACL_DEFAULT, value, size);
+ }
+ 
+ static ssize_t mp_dacl_listxattr(FsContext *ctx, const char *path,
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-util.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-util.c	2017-04-06 08:58:51.798146797 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-util.c	2017-04-06 08:59:04.450306939 -0400
+@@ -11,6 +11,7 @@
+  */
+ 
+ #include "qemu/osdep.h"
++#include "qemu/xattr.h"
+ #include "hw/virtio/virtio.h"
+ #include "virtio-9p-util.h"
+ 
+@@ -56,3 +57,14 @@
+ 
+     return fd;
+ }
++
++ssize_t fgetxattrat_nofollow(int dirfd, const char *filename, const char *name,
++                             void *value, size_t size)
++{
++    char *proc_path = g_strdup_printf("/proc/self/fd/%d/%s", dirfd, filename);
++    int ret;
++
++    ret = lgetxattr(proc_path, name, value, size);
++    g_free(proc_path);
++    return ret;
++}
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-util.h
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-util.h	2017-04-06 08:58:51.798146797 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-util.h	2017-04-06 08:58:51.794146746 -0400
+@@ -46,5 +46,7 @@
+ 
+ int relative_openat_nofollow(int dirfd, const char *path, int flags,
+                              mode_t mode);
++ssize_t fgetxattrat_nofollow(int dirfd, const char *path, const char *name,
++                             void *value, size_t size);
+ 
+ #endif
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-xattr-user.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-xattr-user.c	2017-04-06 08:58:51.798146797 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-xattr-user.c	2017-04-06 08:58:51.794146746 -0400
+@@ -21,9 +21,6 @@
+ static ssize_t mp_user_getxattr(FsContext *ctx, const char *path,
+                                 const char *name, void *value, size_t size)
+ {
+-    char *buffer;
+-    ssize_t ret;
+-
+     if (strncmp(name, "user.virtfs.", 12) == 0) {
+         /*
+          * Don't allow fetch of user.virtfs namesapce
+@@ -32,10 +29,7 @@
+         errno = ENOATTR;
+         return -1;
+     }
+-    buffer = rpath(ctx, path);
+-    ret = lgetxattr(buffer, name, value, size);
+-    g_free(buffer);
+-    return ret;
++    return local_getxattr_nofollow(ctx, path, name, value, size);
+ }
+ 
+ static ssize_t mp_user_listxattr(FsContext *ctx, const char *path,
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-xattr.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-xattr.c	2017-04-06 08:58:51.798146797 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-xattr.c	2017-04-06 08:58:51.794146746 -0400
+@@ -15,6 +15,8 @@
+ #include "virtio-9p.h"
+ #include "fsdev/file-op-9p.h"
+ #include "virtio-9p-xattr.h"
++#include "virtio-9p-util.h"
++#include "virtio-9p-local.h"
+ 
+ 
+ static XattrOperations *get_xattr_operations(XattrOperations **h,
+@@ -143,16 +145,31 @@
+ 
+ }
+ 
++ssize_t local_getxattr_nofollow(FsContext *ctx, const char *path,
++                                const char *name, void *value, size_t size)
++{
++    char *dirpath = g_path_get_dirname(path);
++    char *filename = g_path_get_basename(path);
++    int dirfd;
++    ssize_t ret = -1;
++
++    dirfd = local_opendir_nofollow(ctx, dirpath);
++    if (dirfd == -1) {
++        goto out;
++    }
++
++    ret = fgetxattrat_nofollow(dirfd, filename, name, value, size);
++    close_preserve_errno(dirfd);
++out:
++    g_free(dirpath);
++    g_free(filename);
++    return ret;
++}
++
+ ssize_t pt_getxattr(FsContext *ctx, const char *path, const char *name,
+                     void *value, size_t size)
+ {
+-    char *buffer;
+-    ssize_t ret;
+-
+-    buffer = rpath(ctx, path);
+-    ret = lgetxattr(buffer, name, value, size);
+-    g_free(buffer);
+-    return ret;
++    return local_getxattr_nofollow(ctx, path, name, value, size);
+ }
+ 
+ int pt_setxattr(FsContext *ctx, const char *path, const char *name, void *value,
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-xattr.h
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-xattr.h	2017-04-06 08:58:51.798146797 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-xattr.h	2017-04-06 08:58:51.794146746 -0400
+@@ -28,6 +28,8 @@
+                        const char *path, const char *name);
+ } XattrOperations;
+ 
++ssize_t local_getxattr_nofollow(FsContext *ctx, const char *path,
++                                const char *name, void *value, size_t size);
+ 
+ extern XattrOperations mapped_user_xattr;
+ extern XattrOperations passthrough_user_xattr;
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-8.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-8.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-8.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-8.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,96 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From 5507904e362df252f6065cb27d1ff98372db6abc Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:42:34 +0100
+Subject: [PATCH] 9pfs: local: llistxattr: don't follow symlinks
+
+The local_llistxattr() callback is vulnerable to symlink attacks because
+it calls llistxattr() which follows symbolic links in all path elements but
+the rightmost one.
+
+This patch introduces a helper to emulate the non-existing flistxattrat()
+function: it is implemented with /proc/self/fd which provides a trusted
+path that can be safely passed to llistxattr().
+
+local_llistxattr() is converted to use this helper and opendir_nofollow().
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-xattr.c | 35 +++++++++++++++++++++++++++++------
+ 1 file changed, 29 insertions(+), 6 deletions(-)
+
+diff --git a/hw/9pfs/virtio-9p-xattr.c b/hw/9pfs/virtio-9p-xattr.c
+index aa4391e..54193c6 100644
+--- a/hw/9pfs/virtio-9p-xattr.c
++++ b/hw/9pfs/virtio-9p-xattr.c
+@@ -60,6 +60,16 @@ ssize_t pt_listxattr(FsContext *ctx, const char *path,
+     return name_size;
+ }
+ 
++static ssize_t flistxattrat_nofollow(int dirfd, const char *filename,
++                                     char *list, size_t size)
++{
++    char *proc_path = g_strdup_printf("/proc/self/fd/%d/%s", dirfd, filename);
++    int ret;
++
++    ret = llistxattr(proc_path, list, size);
++    g_free(proc_path);
++    return ret;
++}
+ 
+ /*
+  * Get the list and pass to each layer to find out whether
+@@ -69,24 +79,37 @@ ssize_t v9fs_list_xattr(FsContext *ctx, const char *path,
+                         void *value, size_t vsize)
+ {
+     ssize_t size = 0;
+-    char *buffer;
+     void *ovalue = value;
+     XattrOperations *xops;
+     char *orig_value, *orig_value_start;
+     ssize_t xattr_len, parsed_len = 0, attr_len;
++    char *dirpath, *name;
++    int dirfd;
+ 
+     /* Get the actual len */
+-    buffer = rpath(ctx, path);
+-    xattr_len = llistxattr(buffer, value, 0);
++    dirpath = g_path_get_dirname(path);
++    dirfd = local_opendir_nofollow(ctx, dirpath);
++    g_free(dirpath);
++    if (dirfd == -1) {
++        return -1;
++    }
++
++    name = g_path_get_basename(path);
++    xattr_len = flistxattrat_nofollow(dirfd, name, value, 0);
+     if (xattr_len <= 0) {
+-        g_free(buffer);
++        g_free(name);
++        close_preserve_errno(dirfd);
+         return xattr_len;
+     }
+ 
+     /* Now fetch the xattr and find the actual size */
+     orig_value = g_malloc(xattr_len);
+-    xattr_len = llistxattr(buffer, orig_value, xattr_len);
+-    g_free(buffer);
++    xattr_len = flistxattrat_nofollow(dirfd, name, orig_value, xattr_len);
++    g_free(name);
++    close_preserve_errno(dirfd);
++    if (xattr_len < 0) {
++        return -1;
++    }
+ 
+     /* store the orig pointer */
+     orig_value_start = orig_value;
+-- 
+1.8.3.1
+
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-9.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-9.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-9.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-9.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,176 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From 3e36aba757f76673007a80b3cd56a4062c2e3462 Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Sun, 26 Feb 2017 23:42:43 +0100
+Subject: [PATCH] 9pfs: local: lsetxattr: don't follow symlinks
+
+The local_lsetxattr() callback is vulnerable to symlink attacks because
+it calls lsetxattr() which follows symbolic links in all path elements but
+the rightmost one.
+
+This patch introduces a helper to emulate the non-existing fsetxattrat()
+function: it is implemented with /proc/self/fd which provides a trusted
+path that can be safely passed to lsetxattr().
+
+local_lsetxattr() is converted to use this helper and opendir_nofollow().
+
+This partly fixes CVE-2016-9602.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
+---
+ hw/9pfs/9p-posix-acl.c  | 18 ++++--------------
+ hw/9pfs/9p-util.h       |  2 ++
+ hw/9pfs/9p-xattr-user.c |  8 +-------
+ hw/9pfs/9p-xattr.c      | 39 +++++++++++++++++++++++++++++++++------
+ hw/9pfs/9p-xattr.h      |  3 +++
+ 5 files changed, 43 insertions(+), 27 deletions(-)
+
+Index: qemu-2.5+dfsg/hw/9pfs/virtio-9p-posix-acl.c
+===================================================================
+--- qemu-2.5+dfsg.orig/hw/9pfs/virtio-9p-posix-acl.c	2017-04-04 14:03:42.470824807 -0400
++++ qemu-2.5+dfsg/hw/9pfs/virtio-9p-posix-acl.c	2017-04-04 14:03:42.466824755 -0400
+@@ -51,13 +51,8 @@
+ static int mp_pacl_setxattr(FsContext *ctx, const char *path, const char *name,
+                             void *value, size_t size, int flags)
+ {
+-    char *buffer;
+-    int ret;
+-
+-    buffer = rpath(ctx, path);
+-    ret = lsetxattr(buffer, MAP_ACL_ACCESS, value, size, flags);
+-    g_free(buffer);
+-    return ret;
++    return local_setxattr_nofollow(ctx, path, MAP_ACL_ACCESS, value, size,
++                                   flags);
+ }
+ 
+ static int mp_pacl_removexattr(FsContext *ctx,
+@@ -109,13 +104,8 @@
+ static int mp_dacl_setxattr(FsContext *ctx, const char *path, const char *name,
+                             void *value, size_t size, int flags)
+ {
+-    char *buffer;
+-    int ret;
+-
+-    buffer = rpath(ctx, path);
+-    ret = lsetxattr(buffer, MAP_ACL_DEFAULT, value, size, flags);
+-    g_free(buffer);
+-    return ret;
++    return local_setxattr_nofollow(ctx, path, MAP_ACL_DEFAULT, value, size,
++                                   flags);
+ }
+ 
+ static int mp_dacl_removexattr(FsContext *ctx,
+Index: qemu-2.5+dfsg/hw/9pfs/virtio-9p-util.h
+===================================================================
+--- qemu-2.5+dfsg.orig/hw/9pfs/virtio-9p-util.h	2017-04-04 14:03:42.470824807 -0400
++++ qemu-2.5+dfsg/hw/9pfs/virtio-9p-util.h	2017-04-04 14:03:42.466824755 -0400
+@@ -48,5 +48,7 @@
+                              mode_t mode);
+ ssize_t fgetxattrat_nofollow(int dirfd, const char *path, const char *name,
+                              void *value, size_t size);
++int fsetxattrat_nofollow(int dirfd, const char *path, const char *name,
++                         void *value, size_t size, int flags);
+ 
+ #endif
+Index: qemu-2.5+dfsg/hw/9pfs/virtio-9p-xattr-user.c
+===================================================================
+--- qemu-2.5+dfsg.orig/hw/9pfs/virtio-9p-xattr-user.c	2017-04-04 14:03:42.470824807 -0400
++++ qemu-2.5+dfsg/hw/9pfs/virtio-9p-xattr-user.c	2017-04-04 14:03:42.466824755 -0400
+@@ -68,9 +68,6 @@
+ static int mp_user_setxattr(FsContext *ctx, const char *path, const char *name,
+                             void *value, size_t size, int flags)
+ {
+-    char *buffer;
+-    int ret;
+-
+     if (strncmp(name, "user.virtfs.", 12) == 0) {
+         /*
+          * Don't allow fetch of user.virtfs namesapce
+@@ -79,10 +76,7 @@
+         errno = EACCES;
+         return -1;
+     }
+-    buffer = rpath(ctx, path);
+-    ret = lsetxattr(buffer, name, value, size, flags);
+-    g_free(buffer);
+-    return ret;
++    return local_setxattr_nofollow(ctx, path, name, value, size, flags);
+ }
+ 
+ static int mp_user_removexattr(FsContext *ctx,
+Index: qemu-2.5+dfsg/hw/9pfs/virtio-9p-xattr.c
+===================================================================
+--- qemu-2.5+dfsg.orig/hw/9pfs/virtio-9p-xattr.c	2017-04-04 14:03:42.470824807 -0400
++++ qemu-2.5+dfsg/hw/9pfs/virtio-9p-xattr.c	2017-04-04 14:03:42.466824755 -0400
+@@ -195,18 +195,45 @@
+     return local_getxattr_nofollow(ctx, path, name, value, size);
+ }
+ 
+-int pt_setxattr(FsContext *ctx, const char *path, const char *name, void *value,
+-                size_t size, int flags)
++int fsetxattrat_nofollow(int dirfd, const char *filename, const char *name,
++                         void *value, size_t size, int flags)
+ {
+-    char *buffer;
++    char *proc_path = g_strdup_printf("/proc/self/fd/%d/%s", dirfd, filename);
+     int ret;
+ 
+-    buffer = rpath(ctx, path);
+-    ret = lsetxattr(buffer, name, value, size, flags);
+-    g_free(buffer);
++    ret = lsetxattr(proc_path, name, value, size, flags);
++    g_free(proc_path);
+     return ret;
+ }
+ 
++ssize_t local_setxattr_nofollow(FsContext *ctx, const char *path,
++                                const char *name, void *value, size_t size,
++                                int flags)
++{
++    char *dirpath = g_path_get_dirname(path);
++    char *filename = g_path_get_basename(path);
++    int dirfd;
++    ssize_t ret = -1;
++
++    dirfd = local_opendir_nofollow(ctx, dirpath);
++    if (dirfd == -1) {
++        goto out;
++    }
++
++    ret = fsetxattrat_nofollow(dirfd, filename, name, value, size, flags);
++    close_preserve_errno(dirfd);
++out:
++    g_free(dirpath);
++    g_free(filename);
++    return ret;
++}
++
++int pt_setxattr(FsContext *ctx, const char *path, const char *name, void *value,
++                size_t size, int flags)
++{
++    return local_setxattr_nofollow(ctx, path, name, value, size, flags);
++}
++
+ int pt_removexattr(FsContext *ctx, const char *path, const char *name)
+ {
+     char *buffer;
+Index: qemu-2.5+dfsg/hw/9pfs/virtio-9p-xattr.h
+===================================================================
+--- qemu-2.5+dfsg.orig/hw/9pfs/virtio-9p-xattr.h	2017-04-04 14:03:42.470824807 -0400
++++ qemu-2.5+dfsg/hw/9pfs/virtio-9p-xattr.h	2017-04-04 14:03:42.466824755 -0400
+@@ -30,6 +30,9 @@
+ 
+ ssize_t local_getxattr_nofollow(FsContext *ctx, const char *path,
+                                 const char *name, void *value, size_t size);
++ssize_t local_setxattr_nofollow(FsContext *ctx, const char *path,
++                                const char *name, void *value, size_t size,
++                                int flags);
+ 
+ extern XattrOperations mapped_user_xattr;
+ extern XattrOperations passthrough_user_xattr;
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9602-pre.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9602-pre.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9602-pre.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9602-pre.patch	2018-07-24 14:28:26.000000000 +0200
@@ -0,0 +1,47 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853006
+Backport of:
+
+From 529490e5d664a20d5c4223070dd7c03a0e02b6bd Mon Sep 17 00:00:00 2001
+From: Peter Maydell <peter.maydell@linaro.org>
+Date: Fri, 4 Dec 2015 17:34:20 +0000
+Subject: [PATCH] osdep.h: Include glib-compat.h in osdep.h rather than
+ qemu-common.h
+
+Our use of glib is now pervasive across QEMU. Move the include of glib-compat.h
+from qemu-common.h to osdep.h so that it is more widely accessible and doesn't
+get forgotten by accident. (Failure to include it will result in build failure
+on old versions of glib which is likely to be unnoticed by most developers.)
+
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
+---
+ include/qemu-common.h | 1 -
+ include/qemu/osdep.h  | 2 ++
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+Index: qemu-2.0.0+dfsg/include/qemu-common.h
+===================================================================
+--- qemu-2.0.0+dfsg.orig/include/qemu-common.h	2017-04-05 11:55:10.681843473 -0400
++++ qemu-2.0.0+dfsg/include/qemu-common.h	2017-04-05 11:55:32.738126860 -0400
+@@ -40,7 +40,6 @@
+ #include <sys/time.h>
+ #include <assert.h>
+ #include <signal.h>
+-#include "glib-compat.h"
+ 
+ #ifdef _WIN32
+ #include "sysemu/os-win32.h"
+Index: qemu-2.0.0+dfsg/include/qemu/osdep.h
+===================================================================
+--- qemu-2.0.0+dfsg.orig/include/qemu/osdep.h	2017-04-05 11:55:10.681843473 -0400
++++ qemu-2.0.0+dfsg/include/qemu/osdep.h	2017-04-05 11:56:10.790615775 -0400
+@@ -18,6 +18,7 @@
+ #endif
+ 
+ #include <sys/time.h>
++#include "glib-compat.h"
+ 
+ #if defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10
+ /* [u]int_fast*_t not in <sys/int_types.h> */
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9603-cirrus-vnc-zap-bitblit-support-from-console-code.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9603-cirrus-vnc-zap-bitblit-support-from-console-code.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9603-cirrus-vnc-zap-bitblit-support-from-console-code.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9603-cirrus-vnc-zap-bitblit-support-from-console-code.patch	2018-06-29 12:54:05.000000000 +0200
@@ -0,0 +1,254 @@
+Origin: backported, https://git.qemu.org/?p=qemu.git;a=commit;h=50628d3479e4f9aa97e323506856e394fe7ad7a6
+Reviewed-by: Santiago R.R. <santiagorr@riseup.net>
+
+From 50628d3479e4f9aa97e323506856e394fe7ad7a6 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Tue, 14 Mar 2017 13:26:59 +0100
+Subject: [PATCH] cirrus/vnc: zap bitblit support from console code.
+
+There is a special code path (dpy_gfx_copy) to allow graphic emulation
+notify user interface code about bitblit operations carryed out by
+guests.  It is supported by cirrus and vnc server.  The intended purpose
+is to optimize display scrolls and just send over the scroll op instead
+of a full display update.
+
+This is rarely used these days though because modern guests simply don't
+use the cirrus blitter any more.  Any linux guest using the cirrus drm
+driver doesn't.  Any windows guest newer than winxp doesn't ship with a
+cirrus driver any more and thus uses the cirrus as simple framebuffer.
+
+So this code tends to bitrot and bugs can go unnoticed for a long time.
+See for example commit "3e10c3e vnc: fix qemu crash because of SIGSEGV"
+which fixes a bug lingering in the code for almost a year, added by
+commit "c7628bf vnc: only alloc server surface with clients connected".
+
+Also the vnc server will throttle the frame rate in case it figures the
+network can't keep up (send buffers are full).  This doesn't work with
+dpy_gfx_copy, for any copy operation sent to the vnc client we have to
+send all outstanding updates beforehand, otherwise the vnc client might
+run the client side blit on outdated data and thereby corrupt the
+display.  So this dpy_gfx_copy "optimization" might even make things
+worse on slow network links.
+
+Lets kill it once for all.
+
+Oh, and one more reason: Turns out (after writing the patch) we have a
+security bug in that code path ...
+
+Fixes: CVE-2016-9603
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: 1489494419-14340-1-git-send-email-kraxel@redhat.com
+---
+ hw/display/cirrus_vga.c |  12 ++---
+ include/ui/console.h    |   7 ---
+ ui/console.c            |  28 -----------
+ ui/vnc.c                | 100 ----------------------------------------
+ 4 files changed, 3 insertions(+), 144 deletions(-)
+
+Index: qemu/hw/display/cirrus_vga.c
+===================================================================
+--- qemu.orig/hw/display/cirrus_vga.c
++++ qemu/hw/display/cirrus_vga.c
+@@ -753,11 +753,6 @@ static void cirrus_do_copy(CirrusVGAStat
+         }
+     }
+ 
+-    /* we have to flush all pending changes so that the copy
+-       is generated at the appropriate moment in time */
+-    if (notify)
+-        graphic_hw_update(s->vga.con);
+-
+     (*s->cirrus_rop) (s, s->vga.vram_ptr +
+ 		      (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
+ 		      s->vga.vram_ptr +
+@@ -766,10 +761,9 @@ static void cirrus_do_copy(CirrusVGAStat
+ 		      s->cirrus_blt_width, s->cirrus_blt_height);
+ 
+     if (notify) {
+-        qemu_console_copy(s->vga.con,
+-			  sx, sy, dx, dy,
+-			  s->cirrus_blt_width / depth,
+-			  s->cirrus_blt_height);
++        dpy_gfx_update(s->vga.con, dx, dy,
++                       s->cirrus_blt_width / depth,
++                       s->cirrus_blt_height);
+     }
+ 
+     /* we don't have to notify the display that this portion has
+Index: qemu/ui/console.c
+===================================================================
+--- qemu.orig/ui/console.c
++++ qemu/ui/console.c
+@@ -1433,27 +1433,6 @@ static void dpy_refresh(DisplayState *s)
+     }
+ }
+ 
+-void dpy_gfx_copy(QemuConsole *con, int src_x, int src_y,
+-                  int dst_x, int dst_y, int w, int h)
+-{
+-    DisplayState *s = con->ds;
+-    DisplayChangeListener *dcl;
+-
+-    if (!qemu_console_is_visible(con)) {
+-        return;
+-    }
+-    QLIST_FOREACH(dcl, &s->listeners, next) {
+-        if (con != (dcl->con ? dcl->con : active_console)) {
+-            continue;
+-        }
+-        if (dcl->ops->dpy_gfx_copy) {
+-            dcl->ops->dpy_gfx_copy(dcl, src_x, src_y, dst_x, dst_y, w, h);
+-        } else { /* TODO */
+-            dcl->ops->dpy_gfx_update(dcl, dst_x, dst_y, w, h);
+-        }
+-    }
+-}
+-
+ void dpy_text_cursor(QemuConsole *con, int x, int y)
+ {
+     DisplayState *s = con->ds;
+@@ -1883,13 +1862,6 @@ void qemu_console_resize(QemuConsole *s,
+     dpy_gfx_replace_surface(s, surface);
+ }
+ 
+-void qemu_console_copy(QemuConsole *con, int src_x, int src_y,
+-                       int dst_x, int dst_y, int w, int h)
+-{
+-    assert(con->console_type == GRAPHIC_CONSOLE);
+-    dpy_gfx_copy(con, src_x, src_y, dst_x, dst_y, w, h);
+-}
+-
+ DisplaySurface *qemu_console_surface(QemuConsole *console)
+ {
+     return console->surface;
+Index: qemu/ui/vnc.c
+===================================================================
+--- qemu.orig/ui/vnc.c
++++ qemu/ui/vnc.c
+@@ -733,96 +733,6 @@ int vnc_send_framebuffer_update(VncState
+     return n;
+ }
+ 
+-static void vnc_copy(VncState *vs, int src_x, int src_y, int dst_x, int dst_y, int w, int h)
+-{
+-    /* send bitblit op to the vnc client */
+-    vnc_lock_output(vs);
+-    vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE);
+-    vnc_write_u8(vs, 0);
+-    vnc_write_u16(vs, 1); /* number of rects */
+-    vnc_framebuffer_update(vs, dst_x, dst_y, w, h, VNC_ENCODING_COPYRECT);
+-    vnc_write_u16(vs, src_x);
+-    vnc_write_u16(vs, src_y);
+-    vnc_unlock_output(vs);
+-    vnc_flush(vs);
+-}
+-
+-static void vnc_dpy_copy(DisplayChangeListener *dcl,
+-                         int src_x, int src_y,
+-                         int dst_x, int dst_y, int w, int h)
+-{
+-    VncDisplay *vd = container_of(dcl, VncDisplay, dcl);
+-    VncState *vs, *vn;
+-    uint8_t *src_row;
+-    uint8_t *dst_row;
+-    int i, x, y, pitch, inc, w_lim, s;
+-    int cmp_bytes;
+-
+-    vnc_refresh_server_surface(vd);
+-    QTAILQ_FOREACH_SAFE(vs, &vd->clients, next, vn) {
+-        if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
+-            vs->force_update = 1;
+-            vnc_update_client(vs, 1, true);
+-            /* vs might be free()ed here */
+-        }
+-    }
+-
+-    /* do bitblit op on the local surface too */
+-    pitch = vnc_server_fb_stride(vd);
+-    src_row = vnc_server_fb_ptr(vd, src_x, src_y);
+-    dst_row = vnc_server_fb_ptr(vd, dst_x, dst_y);
+-    y = dst_y;
+-    inc = 1;
+-    if (dst_y > src_y) {
+-        /* copy backwards */
+-        src_row += pitch * (h-1);
+-        dst_row += pitch * (h-1);
+-        pitch = -pitch;
+-        y = dst_y + h - 1;
+-        inc = -1;
+-    }
+-    w_lim = w - (VNC_DIRTY_PIXELS_PER_BIT - (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
+-    if (w_lim < 0) {
+-        w_lim = w;
+-    } else {
+-        w_lim = w - (w_lim % VNC_DIRTY_PIXELS_PER_BIT);
+-    }
+-    for (i = 0; i < h; i++) {
+-        for (x = 0; x <= w_lim;
+-                x += s, src_row += cmp_bytes, dst_row += cmp_bytes) {
+-            if (x == w_lim) {
+-                if ((s = w - w_lim) == 0)
+-                    break;
+-            } else if (!x) {
+-                s = (VNC_DIRTY_PIXELS_PER_BIT -
+-                    (dst_x % VNC_DIRTY_PIXELS_PER_BIT));
+-                s = MIN(s, w_lim);
+-            } else {
+-                s = VNC_DIRTY_PIXELS_PER_BIT;
+-            }
+-            cmp_bytes = s * VNC_SERVER_FB_BYTES;
+-            if (memcmp(src_row, dst_row, cmp_bytes) == 0)
+-                continue;
+-            memmove(dst_row, src_row, cmp_bytes);
+-            QTAILQ_FOREACH(vs, &vd->clients, next) {
+-                if (!vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
+-                    set_bit(((x + dst_x) / VNC_DIRTY_PIXELS_PER_BIT),
+-                            vs->dirty[y]);
+-                }
+-            }
+-        }
+-        src_row += pitch - w * VNC_SERVER_FB_BYTES;
+-        dst_row += pitch - w * VNC_SERVER_FB_BYTES;
+-        y += inc;
+-    }
+-
+-    QTAILQ_FOREACH(vs, &vd->clients, next) {
+-        if (vnc_has_feature(vs, VNC_FEATURE_COPYRECT)) {
+-            vnc_copy(vs, src_x, src_y, dst_x, dst_y, w, h);
+-        }
+-    }
+-}
+-
+ static void vnc_mouse_set(DisplayChangeListener *dcl,
+                           int x, int y, int visible)
+ {
+@@ -2948,7 +2858,6 @@ static void vnc_listen_websocket_read(vo
+ static const DisplayChangeListenerOps dcl_ops = {
+     .dpy_name          = "vnc",
+     .dpy_refresh       = vnc_refresh,
+-    .dpy_gfx_copy      = vnc_dpy_copy,
+     .dpy_gfx_update    = vnc_dpy_update,
+     .dpy_gfx_switch    = vnc_dpy_switch,
+     .dpy_mouse_set     = vnc_mouse_set,
+Index: qemu/include/ui/console.h
+===================================================================
+--- qemu.orig/include/ui/console.h
++++ qemu/include/ui/console.h
+@@ -220,8 +220,6 @@ int dpy_set_ui_info(QemuConsole *con, Qe
+ void dpy_gfx_update(QemuConsole *con, int x, int y, int w, int h);
+ void dpy_gfx_replace_surface(QemuConsole *con,
+                              DisplaySurface *surface);
+-void dpy_gfx_copy(QemuConsole *con, int src_x, int src_y,
+-                  int dst_x, int dst_y, int w, int h);
+ void dpy_text_cursor(QemuConsole *con, int x, int y);
+ void dpy_text_update(QemuConsole *con, int x, int y, int w, int h);
+ void dpy_text_resize(QemuConsole *con, int w, int h);
+@@ -305,8 +303,6 @@ void text_consoles_set_display(DisplaySt
+ void console_select(unsigned int index);
+ void console_color_init(DisplayState *ds);
+ void qemu_console_resize(QemuConsole *con, int width, int height);
+-void qemu_console_copy(QemuConsole *con, int src_x, int src_y,
+-                       int dst_x, int dst_y, int w, int h);
+ DisplaySurface *qemu_console_surface(QemuConsole *con);
+ DisplayState *qemu_console_displaystate(QemuConsole *console);
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9776.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9776.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9776.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9776.patch	2018-07-24 19:51:25.000000000 +0200
@@ -0,0 +1,35 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 846797
+
+From 77d54985b85a0cb760330ec2bd92505e0a2a97a9 Mon Sep 17 00:00:00 2001
+From: Prasad J Pandit <pjp@fedoraproject.org>
+Date: Tue, 29 Nov 2016 00:38:39 +0530
+Subject: [PATCH] net: mcf: check receive buffer size register value
+
+ColdFire Fast Ethernet Controller uses a receive buffer size
+register(EMRBR) to hold maximum size of all receive buffers.
+It is set by a user before any operation. If it was set to be
+zero, ColdFire emulator would go into an infinite loop while
+receiving data in mcf_fec_receive. Add check to avoid it.
+
+Reported-by: Wjjzhang <wjjzhang@tencent.com>
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Signed-off-by: Jason Wang <jasowang@redhat.com>
+---
+ hw/net/mcf_fec.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: qemu-2.0.0+dfsg/hw/net/mcf_fec.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/net/mcf_fec.c	2017-04-06 09:43:19.147684514 -0400
++++ qemu-2.0.0+dfsg/hw/net/mcf_fec.c	2017-04-06 09:43:19.143684462 -0400
+@@ -344,7 +344,7 @@
+         s->tx_descriptor = s->etdsr;
+         break;
+     case 0x188:
+-        s->emrbr = value & 0x7f0;
++        s->emrbr = value > 0 ? value & 0x7F0 : 0x7F0;
+         break;
+     default:
+         hw_error("mcf_fec_write Bad address 0x%x\n", (int)addr);
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9907.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9907.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9907.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9907.patch	2018-07-24 19:55:04.000000000 +0200
@@ -0,0 +1,57 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 847953
+
+Backport of:
+
+From 07b026fd82d6cf11baf7d7c603c4f5f6070b35bf Mon Sep 17 00:00:00 2001
+From: Li Qiang <liqiang6-s@360.cn>
+Date: Mon, 7 Nov 2016 21:57:46 -0800
+Subject: [PATCH] usbredir: free vm_change_state_handler in usbredir destroy
+ dispatch
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf8
+Content-Transfer-Encoding: 8bit
+
+In usbredir destroy dispatch function, it doesn't free the vm change
+state handler once registered in usbredir_realize function. This will
+lead a memory leak issue. This patch avoid this.
+
+Signed-off-by: Li Qiang <liqiang6-s@360.cn>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 58216976.d0236b0a.77b99.bcd6@mx.google.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/usb/redirect.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+Index: qemu-2.0.0+dfsg/hw/usb/redirect.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/usb/redirect.c	2017-04-06 09:47:06.502540944 -0400
++++ qemu-2.0.0+dfsg/hw/usb/redirect.c	2017-04-06 09:47:34.630893762 -0400
+@@ -122,6 +122,7 @@
+     struct usbredirfilter_rule *filter_rules;
+     int filter_rules_count;
+     int compatible_speedmask;
++    VMChangeStateEntry *vmstate;
+ };
+ 
+ static void usbredir_hello(void *priv, struct usb_redir_hello_header *h);
+@@ -1313,7 +1314,8 @@
+     qemu_chr_add_handlers(dev->cs, usbredir_chardev_can_read,
+                           usbredir_chardev_read, usbredir_chardev_event, dev);
+ 
+-    qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev);
++    dev->vmstate =
++        qemu_add_vm_change_state_handler(usbredir_vm_state_change, dev);
+     add_boot_device_path(dev->bootindex, &udev->qdev, NULL);
+     return 0;
+ }
+@@ -1351,6 +1353,7 @@
+     }
+ 
+     free(dev->filter_rules);
++    qemu_del_vm_change_state_handler(dev->vmstate);
+ }
+ 
+ static int usbredir_check_filter(USBRedirDevice *dev)
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9911.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9911.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9911.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9911.patch	2018-07-25 12:36:38.000000000 +0200
@@ -0,0 +1,32 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 847951
+
+From 791f97758e223de3290592d169f8e6339c281714 Mon Sep 17 00:00:00 2001
+From: Li Qiang <liqiang6-s@360.cn>
+Date: Tue, 8 Nov 2016 04:11:10 -0800
+Subject: [PATCH] usb: ehci: fix memory leak in ehci_init_transfer
+
+In ehci_init_transfer function, if the 'cpage' is bigger than 4,
+it doesn't free the 'p->sgl' once allocated previously thus leading
+a memory leak issue. This patch avoid this.
+
+Signed-off-by: Li Qiang <liqiang6-s@360.cn>
+Message-id: 5821c0f4.091c6b0a.e0c92.e811@mx.google.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/usb/hcd-ehci.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+Index: qemu-2.0.0+dfsg/hw/usb/hcd-ehci.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/usb/hcd-ehci.c	2017-04-06 10:02:39.414228874 -0400
++++ qemu-2.0.0+dfsg/hw/usb/hcd-ehci.c	2017-04-06 10:02:39.410228824 -0400
+@@ -1270,6 +1270,7 @@
+     while (bytes > 0) {
+         if (cpage > 4) {
+             fprintf(stderr, "cpage out of range (%d)\n", cpage);
++            qemu_sglist_destroy(&p->sgl);
+             return -1;
+         }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9914-1.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9914-1.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9914-1.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9914-1.patch	2018-07-24 16:16:32.000000000 +0200
@@ -0,0 +1,30 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 847496
+
+Index: qemu/fsdev/file-op-9p.h
+===================================================================
+--- qemu.orig/fsdev/file-op-9p.h
++++ qemu/fsdev/file-op-9p.h
+@@ -102,6 +102,7 @@ struct FileOperations
+ {
+     int (*parse_opts)(QemuOpts *, struct FsDriverEntry *);
+     int (*init)(struct FsContext *);
++    void (*cleanup)(struct FsContext *);
+     int (*lstat)(FsContext *, V9fsPath *, struct stat *);
+     ssize_t (*readlink)(FsContext *, V9fsPath *, char *, size_t);
+     int (*chmod)(FsContext *, V9fsPath *, FsCred *);
+Index: qemu/hw/9pfs/virtio-9p-device.c
+===================================================================
+--- qemu.orig/hw/9pfs/virtio-9p-device.c
++++ qemu/hw/9pfs/virtio-9p-device.c
+@@ -131,6 +131,9 @@ static void virtio_9p_device_realize(Dev
+ 
+     return;
+ out:
++    if (s->ops->cleanup && s->ctx.private) {
++        s->ops->cleanup(&s->ctx);
++    }
+     g_free(s->ctx.fs_root);
+     g_free(s->tag);
+     virtio_cleanup(vdev);
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9914-2.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9914-2.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9914-2.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9914-2.patch	2018-07-24 16:16:41.000000000 +0200
@@ -0,0 +1,35 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 847496
+
+Backport of:
+
+From f2b58c43758efc61e2a49b899f5e58848489d0dc Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Tue, 3 Jan 2017 17:28:44 +0100
+Subject: [PATCH] 9pfs: fix crash when fsdev is missing
+
+If the user passes -device virtio-9p without the corresponding -fsdev, QEMU
+dereferences a NULL pointer and crashes.
+
+This is a 2.8 regression introduced by commit 702dbcc274e2c.
+
+Signed-off-by: Greg Kurz <groug@kaod.org>
+Reviewed-by: Li Qiang <liq3ea@gmail.com>
+---
+ hw/9pfs/9p.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: qemu/hw/9pfs/virtio-9p-device.c
+===================================================================
+--- qemu.orig/hw/9pfs/virtio-9p-device.c
++++ qemu/hw/9pfs/virtio-9p-device.c
+@@ -131,7 +131,7 @@ static void virtio_9p_device_realize(Dev
+ 
+     return;
+ out:
+-    if (s->ops->cleanup && s->ctx.private) {
++    if (s->ops && s->ops->cleanup && s->ctx.private) {
+         s->ops->cleanup(&s->ctx);
+     }
+     g_free(s->ctx.fs_root);
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9915.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9915.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9915.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9915.patch	2018-07-24 17:43:36.000000000 +0200
@@ -0,0 +1,49 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 847496
+Backport of:
+
+From 971f406b77a6eb84e0ad27dcc416b663765aee30 Mon Sep 17 00:00:00 2001
+From: Li Qiang <liq3ea@gmail.com>
+Date: Wed, 23 Nov 2016 13:53:34 +0100
+Subject: [PATCH] 9pfs: add cleanup operation for handle backend driver
+
+In the init operation of handle backend dirver, it allocates a
+handle_data struct and opens a mount file. We should free these
+resources when the 9pfs device is unrealized. This is what this
+patch does.
+
+Signed-off-by: Li Qiang <liq3ea@gmail.com>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+Signed-off-by: Greg Kurz <groug@kaod.org>
+---
+ hw/9pfs/9p-handle.c | 9 +++++++++
+ 1 file changed, 9 insertions(+)
+
+Index: qemu-2.5+dfsg/hw/9pfs/virtio-9p-handle.c
+===================================================================
+--- qemu-2.5+dfsg.orig/hw/9pfs/virtio-9p-handle.c	2017-04-04 15:09:45.489743312 -0400
++++ qemu-2.5+dfsg/hw/9pfs/virtio-9p-handle.c	2017-04-04 15:09:45.485743261 -0400
+@@ -650,6 +650,14 @@
+     return ret;
+ }
+ 
++static void handle_cleanup(FsContext *ctx)
++{
++    struct handle_data *data = ctx->private;
++
++    close(data->mountfd);
++    g_free(data);
++}
++
+ static int handle_parse_opts(QemuOpts *opts, struct FsDriverEntry *fse)
+ {
+     const char *sec_model = qemu_opt_get(opts, "security_model");
+@@ -672,6 +680,7 @@
+ FileOperations handle_ops = {
+     .parse_opts   = handle_parse_opts,
+     .init         = handle_init,
++    .cleanup      = handle_cleanup,
+     .lstat        = handle_lstat,
+     .readlink     = handle_readlink,
+     .close        = handle_close,
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9916.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9916.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9916.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9916.patch	2018-07-24 17:56:06.000000000 +0200
@@ -0,0 +1,49 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 847496
+Backport of:
+
+From 898ae90a44551d25b8e956fd87372d303c82fe68 Mon Sep 17 00:00:00 2001
+From: Li Qiang <liq3ea@gmail.com>
+Date: Wed, 23 Nov 2016 13:53:34 +0100
+Subject: [PATCH] 9pfs: add cleanup operation for proxy backend driver
+
+In the init operation of proxy backend dirver, it allocates a
+V9fsProxy struct and some other resources. We should free these
+resources when the 9pfs device is unrealized. This is what this
+patch does.
+
+Signed-off-by: Li Qiang <liq3ea@gmail.com>
+Reviewed-by: Greg Kurz <groug@kaod.org>
+Signed-off-by: Greg Kurz <groug@kaod.org>
+---
+ hw/9pfs/9p-proxy.c | 13 +++++++++++++
+ 1 file changed, 13 insertions(+)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-proxy.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-proxy.c	2017-04-05 11:58:58.092765342 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-proxy.c	2017-04-05 11:58:58.088765291 -0400
+@@ -1175,9 +1175,22 @@
+     return 0;
+ }
+ 
++static void proxy_cleanup(FsContext *ctx)
++{
++    V9fsProxy *proxy = ctx->private;
++
++    g_free(proxy->out_iovec.iov_base);
++    g_free(proxy->in_iovec.iov_base);
++    if (ctx->export_flags & V9FS_PROXY_SOCK_NAME) {
++        close(proxy->sockfd);
++    }
++    g_free(proxy);
++}
++
+ FileOperations proxy_ops = {
+     .parse_opts   = proxy_parse_opts,
+     .init         = proxy_init,
++    .cleanup      = proxy_cleanup,
+     .lstat        = proxy_lstat,
+     .readlink     = proxy_readlink,
+     .close        = proxy_close,
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2016-9921-9922.patch qemu-2.1+dfsg/debian/patches/CVE-2016-9921-9922.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2016-9921-9922.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2016-9921-9922.patch	2018-07-25 00:10:11.000000000 +0200
@@ -0,0 +1,77 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 847960
+
+From 4299b90e9ba9ce5ca9024572804ba751aa1a7e70 Mon Sep 17 00:00:00 2001
+From: Prasad J Pandit <pjp@fedoraproject.org>
+Date: Tue, 18 Oct 2016 13:15:17 +0530
+Subject: [PATCH] display: cirrus: check vga bits per pixel(bpp) value
+
+In Cirrus CLGD 54xx VGA Emulator, if cirrus graphics mode is VGA,
+'cirrus_get_bpp' returns zero(0), which could lead to a divide
+by zero error in while copying pixel data. The same could occur
+via blit pitch values. Add check to avoid it.
+
+Reported-by: Huawei PSIRT <psirt@huawei.com>
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Message-id: 1476776717-24807-1-git-send-email-ppandit@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/display/cirrus_vga.c | 14 ++++++++++----
+ 1 file changed, 10 insertions(+), 4 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/display/cirrus_vga.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/display/cirrus_vga.c	2017-04-06 09:49:10.260092350 -0400
++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga.c	2017-04-06 09:49:10.256092300 -0400
+@@ -267,6 +267,9 @@
+ static bool blit_region_is_unsafe(struct CirrusVGAState *s,
+                                   int32_t pitch, int32_t addr)
+ {
++    if (!pitch) {
++        return true;
++    }
+     if (pitch < 0) {
+         int64_t min = addr
+             + ((int64_t)s->cirrus_blt_height-1) * pitch;
+@@ -710,7 +713,7 @@
+                                             s->cirrus_addr_mask));
+ }
+ 
+-static void cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
++static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
+ {
+     int sx = 0, sy = 0;
+     int dx = 0, dy = 0;
+@@ -724,6 +727,9 @@
+         int width, height;
+ 
+         depth = s->vga.get_bpp(&s->vga) / 8;
++        if (!depth) {
++            return 0;
++        }
+         s->vga.get_resolution(&s->vga, &width, &height);
+ 
+         /* extra x, y */
+@@ -772,6 +778,8 @@
+     cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
+ 				s->cirrus_blt_dstpitch, s->cirrus_blt_width,
+ 				s->cirrus_blt_height);
++
++    return 1;
+ }
+ 
+ static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
+@@ -779,11 +787,9 @@
+     if (blit_is_unsafe(s))
+         return 0;
+ 
+-    cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
++    return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
+             s->cirrus_blt_srcaddr - s->vga.start_addr,
+             s->cirrus_blt_width, s->cirrus_blt_height);
+-
+-    return 1;
+ }
+ 
+ /***************************************
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-10664-Ignore-SIGPIPE.patch qemu-2.1+dfsg/debian/patches/CVE-2017-10664-Ignore-SIGPIPE.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-10664-Ignore-SIGPIPE.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-10664-Ignore-SIGPIPE.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,45 @@
+Origin: debian, 1.1.2+dfsg-6+deb7u23
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 866674
+
+From: Max Reitz <mreitz@redhat.com>
+Date: Sun, 11 Jun 2017 14:37:14 +0200
+Subject: CVE-2017-10664: Ignore SIGPIPE
+
+qemu proper has done so for 13 years
+(8a7ddc38a60648257dc0645ab4a05b33d6040063), qemu-img and qemu-io have
+done so for four years (526eda14a68d5b3596be715505289b541288ef2a).
+Ignoring this signal is especially important in qemu-nbd because
+otherwise a client can easily take down the qemu-nbd server by dropping
+the connection when the server wants to send something, for example:
+
+$ qemu-nbd -x foo -f raw -t null-co:// &
+[1] 12726
+$ qemu-io -c quit nbd://localhost/bar
+can't open device nbd://localhost/bar: No export with name 'bar' available
+[1]  + 12726 broken pipe  qemu-nbd -x foo -f raw -t null-co://
+
+In this case, the client sends an NBD_OPT_ABORT and closes the
+connection (because it is not required to wait for a reply), but the
+server replies with an NBD_REP_ACK (because it is required to reply).
+
+This upstream commit 041e32b8d9d076980b4e35317c0339e57ab888f1
+---
+ qemu-nbd.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+Index: qemu/qemu-nbd.c
+===================================================================
+--- qemu.orig/qemu-nbd.c
++++ qemu/qemu-nbd.c
+@@ -442,6 +442,10 @@ int main(int argc, char **argv)
+     sigaction(SIGTERM, &sa_sigterm, NULL);
+     qemu_init_exec_dir(argv[0]);
+ 
++#ifdef CONFIG_POSIX
++    signal(SIGPIPE, SIG_IGN);
++#endif
++
+     while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) {
+         switch (ch) {
+         case 's':
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-10806.patch qemu-2.1+dfsg/debian/patches/CVE-2017-10806.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-10806.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-10806.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,51 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.35
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 867751
+
+From bd4a683505b27adc1ac809f71e918e58573d851d Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Tue, 9 May 2017 13:01:28 +0200
+Subject: [PATCH] usb-redir: fix stack overflow in usbredir_log_data
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf8
+Content-Transfer-Encoding: 8bit
+
+Don't reinvent a broken wheel, just use the hexdump function we have.
+
+Impact: low, broken code doesn't run unless you have debug logging
+enabled.
+
+Reported-by: æ??强 <liqiang6-s@360.cn>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: 20170509110128.27261-1-kraxel@redhat.com
+---
+ hw/usb/redirect.c | 13 +------------
+ 1 file changed, 1 insertion(+), 12 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/usb/redirect.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/usb/redirect.c	2017-08-22 12:34:43.028840902 -0400
++++ qemu-2.0.0+dfsg/hw/usb/redirect.c	2017-08-22 12:34:43.024840901 -0400
+@@ -216,21 +216,10 @@ static void usbredir_log(void *priv, int
+ static void usbredir_log_data(USBRedirDevice *dev, const char *desc,
+     const uint8_t *data, int len)
+ {
+-    int i, j, n;
+-
+     if (dev->debug < usbredirparser_debug_data) {
+         return;
+     }
+-
+-    for (i = 0; i < len; i += j) {
+-        char buf[128];
+-
+-        n = sprintf(buf, "%s", desc);
+-        for (j = 0; j < 8 && i + j < len; j++) {
+-            n += sprintf(buf + n, " %02X", data[i + j]);
+-        }
+-        error_report("%s", buf);
+-    }
++    qemu_hexdump((char *)data, stderr, desc, len);
+ }
+ 
+ /*
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-11434-slirp-check-len-against-dhcp-options-array.patch qemu-2.1+dfsg/debian/patches/CVE-2017-11434-slirp-check-len-against-dhcp-options-array.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-11434-slirp-check-len-against-dhcp-options-array.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-11434-slirp-check-len-against-dhcp-options-array.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,36 @@
+Origin: debian, 1.1.2+dfsg-6+deb7u23
+Reviewed-by: Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 869171
+
+From: Prasad J Pandit <pjp@fedoraproject.org>
+Date: Mon, 17 Jul 2017 17:33:26 +0530
+Subject: CVE-2017-11434: slirp: check len against dhcp options array end
+
+While parsing dhcp options string in 'dhcp_decode', if an options'
+length 'len' appeared towards the end of 'bp_vend' array, ensuing
+read could lead to an OOB memory access issue. Add check to avoid it.
+
+This is CVE-2017-11434.
+
+Reported-by: Reno Robert <renorobert@gmail.com>
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
+(cherry picked from commit 413d463f43fbc4dd3a601e80a5724aa384a265a0)
+---
+ slirp/bootp.c | 3 +++
+ 1 file changed, 3 insertions(+)
+
+diff --git a/slirp/bootp.c b/slirp/bootp.c
+index 64eac7d..0744135 100644
+--- a/slirp/bootp.c
++++ b/slirp/bootp.c
+@@ -116,6 +116,9 @@ static void dhcp_decode(const struct bootp_t *bp, int *pmsg_type,
+             if (p >= p_end)
+                 break;
+             len = *p++;
++            if (p + len > p_end) {
++                break;
++            }
+             DPRINTF("dhcp: tag=%d len=%d\n", tag, len);
+ 
+             switch(tag) {
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-14167-multiboot-validate-multiboot-header-addres.patch qemu-2.1+dfsg/debian/patches/CVE-2017-14167-multiboot-validate-multiboot-header-addres.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-14167-multiboot-validate-multiboot-header-addres.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-14167-multiboot-validate-multiboot-header-addres.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,64 @@
+Origin: debian, qemu_1.1.2+dfsg-6+deb7u25
+Reviewed-by: Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: https://bugs.debian.org/874606
+
+From: =?utf-8?q?Guido_G=C3=BCnther?= <agx@sigxcpu.org>
+Date: Wed, 4 Oct 2017 08:24:40 +0200
+Subject: CVE-2017-14167: multiboot: validate multiboot header address values
+
+While loading kernel via multiboot-v1 image, (flags & 0x00010000)
+indicates that multiboot header contains valid addresses to load
+the kernel image. These addresses are used to compute kernel
+size and kernel text offset in the OS image. Validate these
+address values to avoid an OOB access issue.
+
+Author: Prasad J Pandit <pjp@fedoraproject.org>
+Reported-by: Thomas Garnier <thgarnie@google.com>
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Message-Id: <20170907063256.7418-1-ppandit@redhat.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+
+This is upstream commit ed4f86e8b6eff8e600c69adee68c7cd34dd2cccb
+---
+ hw/multiboot.c | 19 +++++++++++++++++++
+ 1 file changed, 19 insertions(+)
+
+diff --git a/hw/i386/multiboot.c b/hw/i386/multiboot.c
+index b1e04c5..b9d32a7 100644
+--- a/hw/i386/multiboot.c
++++ b/hw/i386/multiboot.c
+@@ -200,15 +200,34 @@ int load_multiboot(void *fw_cfg,
+         uint32_t mh_header_addr = ldl_p(header+i+12);
+         uint32_t mh_load_end_addr = ldl_p(header+i+20);
+         uint32_t mh_bss_end_addr = ldl_p(header+i+24);
++
+         mh_load_addr = ldl_p(header+i+16);
++        if (mh_header_addr < mh_load_addr) {
++            fprintf(stderr, "invalid mh_load_addr address\n");
++            exit(1);
++        }
++
+         uint32_t mb_kernel_text_offset = i - (mh_header_addr - mh_load_addr);
+         uint32_t mb_load_size = 0;
+         mh_entry_addr = ldl_p(header+i+28);
+ 
+         if (mh_load_end_addr) {
++            if (mh_bss_end_addr < mh_load_addr) {
++                fprintf(stderr, "invalid mh_bss_end_addr address\n");
++                exit(1);
++            }
+             mb_kernel_size = mh_bss_end_addr - mh_load_addr;
++
++            if (mh_load_end_addr < mh_load_addr) {
++                fprintf(stderr, "invalid mh_load_end_addr address\n");
++                exit(1);
++            }
+             mb_load_size = mh_load_end_addr - mh_load_addr;
+         } else {
++            if (kernel_file_size < mb_kernel_text_offset) {
++                fprintf(stderr, "invalid kernel_file_size\n");
++                exit(1);
++            }
+             mb_kernel_size = kernel_file_size - mb_kernel_text_offset;
+             mb_load_size = mb_kernel_size;
+         }
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-15038-9pfs-use-g_malloc0-to-allocate-space-for-x.patch qemu-2.1+dfsg/debian/patches/CVE-2017-15038-9pfs-use-g_malloc0-to-allocate-space-for-x.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-15038-9pfs-use-g_malloc0-to-allocate-space-for-x.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-15038-9pfs-use-g_malloc0-to-allocate-space-for-x.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,43 @@
+Origin: debian, qemu_1.1.2+dfsg-6+deb7u25
+Reviewed-by: Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: https://bugs.debian.org/877890
+
+From: =?utf-8?q?Guido_G=C3=BCnther?= <agx@sigxcpu.org>
+Date: Fri, 6 Oct 2017 16:36:27 +0200
+Subject: CVE-2017-15038: 9pfs: use g_malloc0 to allocate space for xattr
+
+9p back-end first queries the size of an extended attribute,
+allocates space for it via g_malloc() and then retrieves its
+value into allocated buffer. Race between querying attribute
+size and retrieving its could lead to memory bytes disclosure.
+Use g_malloc0() to avoid it.
+
+This is upstream commit cf9c0df3fb3588768034b16f1f836a0ec87da096
+
+Author: Prasad J Pandit
+---
+ hw/9pfs/virtio-9p.c | 4 ++--
+ 1 file changed, 2 insertions(+), 2 deletions(-)
+
+diff --git a/hw/9pfs/virtio-9p.c b/hw/9pfs/virtio-9p.c
+index e270b84..b993139 100644
+--- a/hw/9pfs/virtio-9p.c
++++ b/hw/9pfs/virtio-9p.c
+@@ -3175,7 +3175,7 @@ static void v9fs_xattrwalk(void *opaque)
+         xattr_fidp->fid_type = P9_FID_XATTR;
+         xattr_fidp->fs.xattr.copied_len = -1;
+         if (size) {
+-            xattr_fidp->fs.xattr.value = g_malloc(size);
++            xattr_fidp->fs.xattr.value = g_malloc0(size);
+             err = v9fs_co_llistxattr(pdu, &xattr_fidp->path,
+                                      xattr_fidp->fs.xattr.value,
+                                      xattr_fidp->fs.xattr.len);
+@@ -3208,7 +3208,7 @@ static void v9fs_xattrwalk(void *opaque)
+         xattr_fidp->fid_type = P9_FID_XATTR;
+         xattr_fidp->fs.xattr.copied_len = -1;
+         if (size) {
+-            xattr_fidp->fs.xattr.value = g_malloc(size);
++            xattr_fidp->fs.xattr.value = g_malloc0(size);
+             err = v9fs_co_lgetxattr(pdu, &xattr_fidp->path,
+                                     &name, xattr_fidp->fs.xattr.value,
+                                     xattr_fidp->fs.xattr.len);
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-15289.patch qemu-2.1+dfsg/debian/patches/CVE-2017-15289.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-15289.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-15289.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,59 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.43
+Reviewed-by: Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: https://bugs.debian.org/880832
+
+From eb38e1bc3740725ca29a535351de94107ec58d51 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Wed, 11 Oct 2017 10:43:14 +0200
+Subject: [PATCH] cirrus: fix oob access in mode4and5 write functions
+
+Move dst calculation into the loop, so we apply the mask on each
+interation and will not overflow vga memory.
+
+Cc: Prasad J Pandit <pjp@fedoraproject.org>
+Reported-by: Niu Guoxiang <niuguoxiang@huawei.com>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: 20171011084314.21752-1-kraxel@redhat.com
+---
+ hw/display/cirrus_vga.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/display/cirrus_vga.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/display/cirrus_vga.c	2018-02-15 13:20:27.734984874 -0500
++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga.c	2018-02-15 13:20:27.730984870 -0500
+@@ -2018,15 +2018,14 @@ static void cirrus_mem_writeb_mode4and5_
+     unsigned val = mem_value;
+     uint8_t *dst;
+ 
+-    dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask);
+     for (x = 0; x < 8; x++) {
++        dst = s->vga.vram_ptr + ((offset + x) & s->cirrus_addr_mask);
+ 	if (val & 0x80) {
+ 	    *dst = s->cirrus_shadow_gr1;
+ 	} else if (mode == 5) {
+ 	    *dst = s->cirrus_shadow_gr0;
+ 	}
+ 	val <<= 1;
+-	dst++;
+     }
+     memory_region_set_dirty(&s->vga.vram, offset, 8);
+ }
+@@ -2040,8 +2039,8 @@ static void cirrus_mem_writeb_mode4and5_
+     unsigned val = mem_value;
+     uint8_t *dst;
+ 
+-    dst = s->vga.vram_ptr + (offset &= s->cirrus_addr_mask);
+     for (x = 0; x < 8; x++) {
++        dst = s->vga.vram_ptr + ((offset + 2 * x) & s->cirrus_addr_mask & ~1);
+ 	if (val & 0x80) {
+ 	    *dst = s->cirrus_shadow_gr1;
+ 	    *(dst + 1) = s->vga.gr[0x11];
+@@ -2050,7 +2049,6 @@ static void cirrus_mem_writeb_mode4and5_
+ 	    *(dst + 1) = s->vga.gr[0x10];
+ 	}
+ 	val <<= 1;
+-	dst += 2;
+     }
+     memory_region_set_dirty(&s->vga.vram, offset, 16);
+ }
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-16845.patch qemu-2.1+dfsg/debian/patches/CVE-2017-16845.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-16845.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-16845.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,63 @@
+Origin: debian, 24c3ec9b6367fe3263a0ddd3e7c04a62a38a1970
+Reviewed-By: Santiago R.R. <santiagorr@riseup.net>
+
+From: Prasad J Pandit <pjp@fedoraproject.org>
+Date: Thu, 16 Nov 2017 13:21:55 +0530
+Subject: ps2: check PS2Queue pointers in post_load routine
+Commit-Id: 802cbcb73002b92e6ddc8464d39b668a71b78d74
+Bug-Debian: http://bugs.debian.org/882136
+
+During Qemu guest migration, a destination process invokes ps2
+post_load function. In that, if 'rptr' and 'count' values were
+invalid, it could lead to OOB access or infinite loop issue.
+Add check to avoid it.
+
+Reported-by: Cyrille Chatras <cyrille.chatras@orange.com>
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Message-id: 20171116075155.22378-1-ppandit@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/input/ps2.c | 21 +++++++++------------
+ 1 file changed, 9 insertions(+), 12 deletions(-)
+
+diff --git a/hw/input/ps2.c b/hw/input/ps2.c
+index f388a23c8e..de171a28dd 100644
+--- a/hw/input/ps2.c
++++ b/hw/input/ps2.c
+@@ -1225,24 +1225,21 @@ static void ps2_common_reset(PS2State *s)
+ static void ps2_common_post_load(PS2State *s)
+ {
+     PS2Queue *q = &s->queue;
+-    int size;
+-    int i;
+-    int tmp_data[PS2_QUEUE_SIZE];
++    uint8_t i, size;
++    uint8_t tmp_data[PS2_QUEUE_SIZE];
+ 
+     /* set the useful data buffer queue size, < PS2_QUEUE_SIZE */
+-    size = q->count > PS2_QUEUE_SIZE ? 0 : q->count;
++    size = (q->count < 0 || q->count > PS2_QUEUE_SIZE) ? 0 : q->count;
+ 
+     /* move the queue elements to the start of data array */
+-    if (size > 0) {
+-        for (i = 0; i < size; i++) {
+-            /* move the queue elements to the temporary buffer */
+-            tmp_data[i] = q->data[q->rptr];
+-            if (++q->rptr == 256) {
+-                q->rptr = 0;
+-            }
++    for (i = 0; i < size; i++) {
++        if (q->rptr < 0 || q->rptr >= sizeof(q->data)) {
++            q->rptr = 0;
+         }
+-        memcpy(q->data, tmp_data, size);
++        tmp_data[i] = q->data[q->rptr++];
+     }
++    memcpy(q->data, tmp_data, size);
++
+     /* reset rptr/wptr/count */
+     q->rptr = 0;
+     q->wptr = size;
+-- 
+2.11.0
+
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-18043.patch qemu-2.1+dfsg/debian/patches/CVE-2017-18043.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-18043.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-18043.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,60 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.22
+Reviewed-by: Santiago R.R. <santiagorr@riseup.net>
+
+Backport of:
+
+From 2098b073f398cd628c09c5a78537a6854e85830d Mon Sep 17 00:00:00 2001
+From: Eric Blake <eblake@redhat.com>
+Date: Thu, 14 Sep 2017 08:49:23 -0500
+Subject: [PATCH] osdep: Fix ROUND_UP(64-bit, 32-bit)
+Commit-Id: 2098b073f398cd628c09c5a78537a6854e85830d
+Bug-Debian: https://security-tracker.debian.org/tracker/CVE-2017-18043
+
+When using bit-wise operations that exploit the power-of-two
+nature of the second argument of ROUND_UP(), we still need to
+ensure that the mask is as wide as the first argument (done
+by using a ternary to force proper arithmetic promotion).
+Unpatched, ROUND_UP(2ULL*1024*1024*1024*1024, 512U) produces 0,
+instead of the intended 2TiB, because negation of an unsigned
+32-bit quantity followed by widening to 64-bits does not
+sign-extend the mask.
+
+Broken since its introduction in commit 292c8e50 (v1.5.0).
+Callers that passed the same width type to both macro parameters,
+or that had other code to ensure the first parameter's maximum
+runtime value did not exceed the second parameter's width, are
+unaffected, but I did not audit to see which (if any) existing
+clients of the macro could trigger incorrect behavior (I found
+the bug while adding a new use of the macro).
+
+While preparing the patch, checkpatch complained about poor
+spacing, so I also fixed that here and in the nearby DIV_ROUND_UP.
+
+CC: qemu-trivial@nongnu.org
+CC: qemu-stable@nongnu.org
+Signed-off-by: Eric Blake <eblake@redhat.com>
+Reviewed-by: Laszlo Ersek <lersek@redhat.com>
+Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
+Signed-off-by: Michael Tokarev <mjt@tls.msk.ru>
+---
+ include/qemu/osdep.h | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+Index: qemu-2.0.0+dfsg/include/qemu/osdep.h
+===================================================================
+--- qemu-2.0.0+dfsg.orig/include/qemu/osdep.h	2018-02-15 13:32:59.763152571 -0500
++++ qemu-2.0.0+dfsg/include/qemu/osdep.h	2018-02-15 13:32:59.759152570 -0500
+@@ -70,11 +70,11 @@ typedef signed int              int_fast
+ #endif
+ 
+ #ifndef ROUND_UP
+-#define ROUND_UP(n,d) (((n) + (d) - 1) & -(d))
++#define ROUND_UP(n, d) (((n) + (d) - 1) & -(0 ? (n) : (d)))
+ #endif
+ 
+ #ifndef DIV_ROUND_UP
+-#define DIV_ROUND_UP(n,d) (((n) + (d) - 1) / (d))
++#define DIV_ROUND_UP(n, d) (((n) + (d) - 1) / (d))
+ #endif
+ 
+ #ifndef ARRAY_SIZE
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-2615.patch qemu-2.1+dfsg/debian/patches/CVE-2017-2615.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-2615.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-2615.patch	2018-07-25 12:47:32.000000000 +0200
@@ -0,0 +1,51 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 854731
+
+Backport of:
+
+From 62d4c6bd5263bb8413a06c80144fc678df6dfb64 Mon Sep 17 00:00:00 2001
+From: Li Qiang <liqiang6-s@360.cn>
+Date: Wed, 1 Feb 2017 09:35:01 +0100
+Subject: [PATCH] cirrus: fix oob access issue (CVE-2017-2615)
+
+When doing bitblt copy in backward mode, we should minus the
+blt width first just like the adding in the forward mode. This
+can avoid the oob access of the front of vga's vram.
+
+Signed-off-by: Li Qiang <liqiang6-s@360.cn>
+
+{ kraxel: with backward blits (negative pitch) addr is the topmost
+          address, so check it as-is against vram size ]
+
+Cc: qemu-stable@nongnu.org
+Cc: P J P <ppandit@redhat.com>
+Cc: Laszlo Ersek <lersek@redhat.com>
+Cc: Paolo Bonzini <pbonzini@redhat.com>
+Cc: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Fixes: d3532a0db02296e687711b8cdc7791924efccea0 (CVE-2014-8106)
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: 1485938101-26602-1-git-send-email-kraxel@redhat.com
+Reviewed-by: Laszlo Ersek <lersek@redhat.com>
+---
+ hw/display/cirrus_vga.c | 7 +++----
+ 1 file changed, 3 insertions(+), 4 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/display/cirrus_vga.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/display/cirrus_vga.c	2017-04-06 10:02:47.798333777 -0400
++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga.c	2017-04-06 10:02:47.794333726 -0400
+@@ -272,10 +272,9 @@
+     }
+     if (pitch < 0) {
+         int64_t min = addr
+-            + ((int64_t)s->cirrus_blt_height-1) * pitch;
+-        int32_t max = addr
+-            + s->cirrus_blt_width;
+-        if (min < 0 || max >= s->vga.vram_size) {
++            + ((int64_t)s->cirrus_blt_height - 1) * pitch
++            - s->cirrus_blt_width;
++        if (min < -1 || addr >= s->vga.vram_size) {
+             return true;
+         }
+     } else {
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-2620-cirrus-add-blit_is_unsafe-call-to-cirrus_bi.patch qemu-2.1+dfsg/debian/patches/CVE-2017-2620-cirrus-add-blit_is_unsafe-call-to-cirrus_bi.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-2620-cirrus-add-blit_is_unsafe-call-to-cirrus_bi.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-2620-cirrus-add-blit_is_unsafe-call-to-cirrus_bi.patch	2018-07-25 13:24:47.000000000 +0200
@@ -0,0 +1,47 @@
+Origin: backported, from wheezy release 1.1.2+dfsg-6+deb7u20
+Reviewed-by: Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 855791
+
+From: =?utf-8?q?Guido_G=C3=BCnther?= <agx@sigxcpu.org>
+Date: Thu, 23 Feb 2017 16:58:11 +0100
+Subject: CVE-2017-2620: cirrus: add blit_is_unsafe call to cirrus_bitblt
+
+CIRRUS_BLTMODE_MEMSYSSRC blits do NOT check blit destination
+and blit width, at all.  Oops.  Fix it.
+
+Security impact: high.
+
+The missing blit destination check allows to write to host memory.
+Basically same as CVE-2014-8106 for the other blit variants.
+
+Upstream-URL: https://lists.gnu.org/archive/html/qemu-devel/2017-02/msg05244.html
+---
+ hw/cirrus_vga.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c
+index 6d64c0f..52d9597 100644
+--- a/hw/display/cirrus_vga.c
++++ b/hw/display/cirrus_vga.c
+@@ -862,6 +862,10 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
+ {
+     int w;
+ 
++    if (blit_is_unsafe(s, true)) {
++        return 0;
++    }
++
+     s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC;
+     s->cirrus_srcptr = &s->cirrus_bltbuf[0];
+     s->cirrus_srcptr_end = &s->cirrus_bltbuf[0];
+@@ -887,6 +891,10 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s)
+ 	}
+         s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height;
+     }
++
++    /* the blit_is_unsafe call above should catch this */
++    assert(s->cirrus_blt_srcpitch <= CIRRUS_BLTBUFSIZE);
++
+     s->cirrus_srcptr = s->cirrus_bltbuf;
+     s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch;
+     cirrus_update_memory_access(s);
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-2620-pre.patch qemu-2.1+dfsg/debian/patches/CVE-2017-2620-pre.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-2620-pre.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-2620-pre.patch	2018-07-25 13:24:17.000000000 +0200
@@ -0,0 +1,74 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 855791
+
+
+From 913a87885f589d263e682c2eb6637c6e14538061 Mon Sep 17 00:00:00 2001
+From: Bruce Rogers <brogers@suse.com>
+Date: Mon, 9 Jan 2017 13:35:20 -0700
+Subject: [PATCH] display: cirrus: ignore source pitch value as needed in
+ blit_is_unsafe
+
+Commit 4299b90 added a check which is too broad, given that the source
+pitch value is not required to be initialized for solid fill operations.
+This patch refines the blit_is_unsafe() check to ignore source pitch in
+that case. After applying the above commit as a security patch, we
+noticed the SLES 11 SP4 guest gui failed to initialize properly.
+
+Signed-off-by: Bruce Rogers <brogers@suse.com>
+Message-id: 20170109203520.5619-1-brogers@suse.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/display/cirrus_vga.c | 11 +++++++----
+ 1 file changed, 7 insertions(+), 4 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/display/cirrus_vga.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/display/cirrus_vga.c	2017-04-06 09:53:43.551510499 -0400
++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga.c	2017-04-06 09:53:43.547510449 -0400
+@@ -289,7 +289,7 @@
+     return false;
+ }
+ 
+-static bool blit_is_unsafe(struct CirrusVGAState *s)
++static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only)
+ {
+     /* should be the case, see cirrus_bitblt_start */
+     assert(s->cirrus_blt_width > 0);
+@@ -303,6 +303,9 @@
+                               s->cirrus_blt_dstaddr & s->cirrus_addr_mask)) {
+         return true;
+     }
++    if (dst_only) {
++        return false;
++    }
+     if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch,
+                               s->cirrus_blt_srcaddr & s->cirrus_addr_mask)) {
+         return true;
+@@ -668,7 +671,7 @@
+ 
+     dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
+ 
+-    if (blit_is_unsafe(s))
++    if (blit_is_unsafe(s, false))
+         return 0;
+ 
+     (*s->cirrus_rop) (s, dst, src,
+@@ -686,7 +689,7 @@
+ {
+     cirrus_fill_t rop_func;
+ 
+-    if (blit_is_unsafe(s)) {
++    if (blit_is_unsafe(s, true)) {
+         return 0;
+     }
+     rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
+@@ -784,7 +787,7 @@
+ 
+ static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
+ {
+-    if (blit_is_unsafe(s))
++    if (blit_is_unsafe(s, false))
+         return 0;
+ 
+     return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-5525.patch qemu-2.1+dfsg/debian/patches/CVE-2017-5525.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-5525.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-5525.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,43 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 852021
+
+
+Backport of:
+
+From 12351a91da97b414eec8cdb09f1d9f41e535a401 Mon Sep 17 00:00:00 2001
+From: Li Qiang <liqiang6-s@360.cn>
+Date: Wed, 14 Dec 2016 18:30:21 -0800
+Subject: [PATCH] audio: ac97: add exit function
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf8
+Content-Transfer-Encoding: 8bit
+
+Currently the ac97 device emulation doesn't have a exit function,
+hot unplug this device will leak some memory. Add a exit function to
+avoid this.
+
+Signed-off-by: Li Qiang <liqiang6-s@360.cn>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 58520052.4825ed0a.27a71.6cae@mx.google.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/audio/ac97.c | 11 +++++++++++
+ 1 file changed, 11 insertions(+)
+
+Index: qemu-2.0.0+dfsg/hw/audio/ac97.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/audio/ac97.c	2017-04-06 09:54:00.803725942 -0400
++++ qemu-2.0.0+dfsg/hw/audio/ac97.c	2017-04-06 09:54:42.584247535 -0400
+@@ -1396,6 +1396,11 @@
+ 
+     memory_region_destroy (&s->io_nam);
+     memory_region_destroy (&s->io_nabm);
++
++    AUD_close_in(&s->card, s->voice_pi);
++    AUD_close_out(&s->card, s->voice_po);
++    AUD_close_in(&s->card, s->voice_mc);
++    AUD_remove_card(&s->card);
+ }
+ 
+ static int ac97_init (PCIBus *bus)
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-5526.patch qemu-2.1+dfsg/debian/patches/CVE-2017-5526.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-5526.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-5526.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,45 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 851910
+
+Backport of:
+
+From 069eb7b2b8fc47c7cb52e5a4af23ea98d939e3da Mon Sep 17 00:00:00 2001
+From: Li Qiang <liqiang6-s@360.cn>
+Date: Wed, 14 Dec 2016 18:32:22 -0800
+Subject: [PATCH] audio: es1370: add exit function
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf8
+Content-Transfer-Encoding: 8bit
+
+Currently the es1370 device emulation doesn't have a exit function,
+hot unplug this device will leak some memory. Add a exit function to
+avoid this.
+
+Signed-off-by: Li Qiang <liqiang6-s@360.cn>
+Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 585200c9.a968ca0a.1ab80.4c98@mx.google.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/audio/es1370.c | 14 ++++++++++++++
+ 1 file changed, 14 insertions(+)
+
+Index: qemu-2.0.0+dfsg/hw/audio/es1370.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/audio/es1370.c	2017-04-06 09:55:33.204882790 -0400
++++ qemu-2.0.0+dfsg/hw/audio/es1370.c	2017-04-06 09:56:00.485225815 -0400
+@@ -1047,6 +1047,14 @@
+ static void es1370_exitfn (PCIDevice *dev)
+ {
+     ES1370State *s = DO_UPCAST (ES1370State, dev, dev);
++    int i;
++
++    for (i = 0; i < 2; ++i) {
++        AUD_close_out(&s->card, s->dac_voice[i]);
++    }
++
++    AUD_close_in(&s->card, s->adc_voice);
++    AUD_remove_card(&s->card);
+ 
+     memory_region_destroy (&s->io);
+ }
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-5579.patch qemu-2.1+dfsg/debian/patches/CVE-2017-5579.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-5579.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-5579.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,43 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853002
+
+Backport of:
+
+From 8409dc884a201bf74b30a9d232b6bbdd00cb7e2b Mon Sep 17 00:00:00 2001
+From: Li Qiang <liqiang6-s@360.cn>
+Date: Wed, 4 Jan 2017 00:43:16 -0800
+Subject: [PATCH] serial: fix memory leak in serial exit
+
+The serial_exit_core function doesn't free some resources.
+This can lead memory leak when hotplug and unplug. This
+patch avoid this.
+
+Signed-off-by: Li Qiang <liqiang6-s@360.cn>
+Message-Id: <586cb5ab.f31d9d0a.38ac3.acf2@mx.google.com>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/char/serial.c | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+Index: qemu-2.0.0+dfsg/hw/char/serial.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/char/serial.c	2017-04-06 09:58:00.014727376 -0400
++++ qemu-2.0.0+dfsg/hw/char/serial.c	2017-04-06 09:58:00.010727325 -0400
+@@ -667,6 +667,16 @@
+ void serial_exit_core(SerialState *s)
+ {
+     qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
++
++    timer_del(s->modem_status_poll);
++    timer_free(s->modem_status_poll);
++
++    timer_del(s->fifo_timeout_timer);
++    timer_free(s->fifo_timeout_timer);
++
++    fifo8_destroy(&s->recv_fifo);
++    fifo8_destroy(&s->xmit_fifo);
++
+     qemu_unregister_reset(serial_reset, s);
+ }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-5667.patch qemu-2.1+dfsg/debian/patches/CVE-2017-5667.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-5667.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-5667.patch	2018-07-25 13:34:39.000000000 +0200
@@ -0,0 +1,38 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853996
+
+From 42922105beb14c2fc58185ea022b9f72fb5465e9 Mon Sep 17 00:00:00 2001
+From: Prasad J Pandit <pjp@fedoraproject.org>
+Date: Tue, 7 Feb 2017 18:29:59 +0000
+Subject: [PATCH] sd: sdhci: check data length during dma_memory_read
+
+While doing multi block SDMA transfer in routine
+'sdhci_sdma_transfer_multi_blocks', the 's->fifo_buffer' starting
+index 'begin' and data length 's->data_count' could end up to be same.
+This could lead to an OOB access issue. Correct transfer data length
+to avoid it.
+
+Cc: qemu-stable@nongnu.org
+Reported-by: Jiang Xin <jiangxin1@huawei.com>
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
+Message-id: 20170130064736.9236-1-ppandit@redhat.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+---
+ hw/sd/sdhci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: qemu-2.0.0+dfsg/hw/sd/sdhci.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/sd/sdhci.c	2017-04-06 09:58:14.098904157 -0400
++++ qemu-2.0.0+dfsg/hw/sd/sdhci.c	2017-04-06 09:58:14.094904106 -0400
+@@ -518,7 +518,7 @@
+                 boundary_count -= block_size - begin;
+             }
+             dma_memory_read(&address_space_memory, s->sdmasysad,
+-                            &s->fifo_buffer[begin], s->data_count);
++                            &s->fifo_buffer[begin], s->data_count - begin);
+             s->sdmasysad += s->data_count - begin;
+             if (s->data_count == block_size) {
+                 for (n = 0; n < block_size; n++) {
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-5715-1.patch qemu-2.1+dfsg/debian/patches/CVE-2017-5715-1.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-5715-1.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-5715-1.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,48 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.38
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 886532
+
+Backport of:
+
+From 807e9869b8c4119b81df902625af818519e01759 Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Tue, 9 Jan 2018 13:45:13 -0200
+Subject: [PATCH] i386: Change X86CPUDefinition::model_id to const char*
+
+It is valid to have a 48-character model ID on CPUID, however the
+definition of X86CPUDefinition::model_id is char[48], which can
+make the compiler drop the null terminator from the string.
+
+If a CPU model happens to have 48 bytes on model_id, "-cpu help"
+will print garbage and the object_property_set_str() call at
+x86_cpu_load_def() will read data outside the model_id array.
+
+We could increase the array size to 49, but this would mean the
+compiler would not issue a warning if a 49-char string is used by
+mistake for model_id.
+
+To make things simpler, simply change model_id to be const char*,
+and validate the string length using an assert() on
+x86_register_cpudef_type().
+
+Reported-by: "Dr. David Alan Gilbert" <dgilbert@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Message-Id: <20180109154519.25634-2-ehabkost@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+---
+ target/i386/cpu.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+Index: qemu-2.0.0+dfsg/target-i386/cpu.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/target-i386/cpu.c	2018-01-23 09:07:10.367212408 -0500
++++ qemu-2.0.0+dfsg/target-i386/cpu.c	2018-01-23 09:07:32.771147171 -0500
+@@ -529,7 +529,7 @@ struct X86CPUDefinition {
+     int model;
+     int stepping;
+     FeatureWordArray features;
+-    char model_id[48];
++    char model_id[49];
+     bool cache_info_passthrough;
+ };
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-5715-2.patch qemu-2.1+dfsg/debian/patches/CVE-2017-5715-2.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-5715-2.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-5715-2.patch	2018-07-25 19:13:33.000000000 +0200
@@ -0,0 +1,141 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.38
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 886532
+
+Backport of:
+
+From a33a2cfe2f771b360b3422f6cdf566a560860bfc Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Tue, 9 Jan 2018 13:45:14 -0200
+Subject: [PATCH] i386: Add support for SPEC_CTRL MSR
+
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Message-Id: <20180109154519.25634-3-ehabkost@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+---
+ target/i386/cpu.h     |  3 +++
+ target/i386/kvm.c     | 14 ++++++++++++++
+ target/i386/machine.c | 20 ++++++++++++++++++++
+ 3 files changed, 37 insertions(+)
+
+Index: qemu/target-i386/cpu.h
+===================================================================
+--- qemu.orig/target-i386/cpu.h
++++ qemu/target-i386/cpu.h
+@@ -309,6 +309,7 @@
+ #define MSR_IA32_APICBASE_BASE          (0xfffff<<12)
+ #define MSR_IA32_FEATURE_CONTROL        0x0000003a
+ #define MSR_TSC_ADJUST                  0x0000003b
++#define MSR_IA32_SPEC_CTRL              0x48
+ #define MSR_IA32_TSCDEADLINE            0x6e0
+ 
+ #define MSR_P6_PERFCTR0                 0xc1
+@@ -874,6 +875,8 @@ typedef struct CPUX86State {
+     uint64_t pat;
+     uint32_t smbase;
+ 
++    uint64_t spec_ctrl;
++
+     /* End of state preserved by INIT (dummy marker).  */
+     struct {} end_init_save;
+ 
+Index: qemu/target-i386/kvm.c
+===================================================================
+--- qemu.orig/target-i386/kvm.c
++++ qemu/target-i386/kvm.c
+@@ -80,6 +80,7 @@ static bool has_msr_hv_hypercall;
+ static bool has_msr_hv_vapic;
+ static bool has_msr_hv_tsc;
+ static bool has_msr_mtrr;
++static bool has_msr_spec_ctrl;
+ 
+ static bool has_msr_architectural_pmu;
+ static uint32_t num_architectural_pmu_counters;
+@@ -814,6 +815,10 @@ static int kvm_get_supported_msrs(KVMSta
+                     has_msr_tsc_adjust = true;
+                     continue;
+                 }
++                if (kvm_msr_list->indices[i] == MSR_IA32_SPEC_CTRL) {
++                    has_msr_spec_ctrl = true;
++                    continue;
++                }
+                 if (kvm_msr_list->indices[i] == MSR_IA32_TSCDEADLINE) {
+                     has_msr_tsc_deadline = true;
+                     continue;
+@@ -1213,6 +1218,9 @@ static int kvm_put_msrs(X86CPU *cpu, int
+     if (has_msr_bndcfgs) {
+         kvm_msr_entry_set(&msrs[n++], MSR_IA32_BNDCFGS, env->msr_bndcfgs);
+     }
++    if (has_msr_spec_ctrl) {
++        kvm_msr_entry_set(&msrs[n++], MSR_IA32_SPEC_CTRL, env->spec_ctrl);
++    }
+ #ifdef TARGET_X86_64
+     if (lm_capable_kernel) {
+         kvm_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar);
+@@ -1221,6 +1229,7 @@ static int kvm_put_msrs(X86CPU *cpu, int
+         kvm_msr_entry_set(&msrs[n++], MSR_LSTAR, env->lstar);
+     }
+ #endif
++
+     /*
+      * The following MSRs have side effects on the guest or are too heavy
+      * for normal writeback. Limit them to reset or full state updates.
+@@ -1551,6 +1560,9 @@ static int kvm_get_msrs(X86CPU *cpu)
+     if (has_msr_bndcfgs) {
+         msrs[n++].index = MSR_IA32_BNDCFGS;
+     }
++    if (has_msr_spec_ctrl) {
++        msrs[n++].index = MSR_IA32_SPEC_CTRL;
++    }
+ 
+     if (!env->tsc_valid) {
+         msrs[n++].index = MSR_IA32_TSC;
+@@ -1789,6 +1801,9 @@ static int kvm_get_msrs(X86CPU *cpu)
+                 env->mtrr_var[MSR_MTRRphysIndex(index)].base = msrs[i].data;
+             }
+             break;
++        case MSR_IA32_SPEC_CTRL:
++            env->spec_ctrl = msrs[i].data;
++            break;
+         }
+     }
+ 
+Index: qemu/target-i386/machine.c
+===================================================================
+--- qemu.orig/target-i386/machine.c
++++ qemu/target-i386/machine.c
+@@ -603,6 +603,24 @@ static const VMStateDescription vmstate_
+     }
+ };
+ 
++static bool spec_ctrl_needed(void *opaque)
++{
++    X86CPU *cpu = opaque;
++    CPUX86State *env = &cpu->env;
++
++    return env->spec_ctrl != 0;
++}
++
++static const VMStateDescription vmstate_spec_ctrl = {
++    .name = "cpu/spec_ctrl",
++    .version_id = 1,
++    .minimum_version_id = 1,
++    .fields = (VMStateField[]){
++        VMSTATE_UINT64(env.spec_ctrl, X86CPU),
++        VMSTATE_END_OF_LIST()
++    }
++};
++
+ VMStateDescription vmstate_x86_cpu = {
+     .name = "cpu",
+     .version_id = 12,
+@@ -746,6 +764,9 @@ VMStateDescription vmstate_x86_cpu = {
+             .vmsd = &vmstate_msr_hyperv_time,
+             .needed = hyperv_time_enable_needed,
+         } , {
++            .vmsd = &vmstate_spec_ctrl,
++            .needed = spec_ctrl_needed,
++        } , {
+             /* empty */
+         }
+     }
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-5715-3.patch qemu-2.1+dfsg/debian/patches/CVE-2017-5715-3.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-5715-3.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-5715-3.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,60 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.38
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 886532
+
+Backport of:
+
+From a2381f0934432ef2cd47a335348ba8839632164c Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Tue, 9 Jan 2018 13:45:15 -0200
+Subject: [PATCH] i386: Add spec-ctrl CPUID bit
+
+Add the feature name and a CPUID_7_0_EDX_SPEC_CTRL macro.
+
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Message-Id: <20180109154519.25634-4-ehabkost@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+---
+
+Backport of:
+
+From a2381f0934432ef2cd47a335348ba8839632164c Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Tue, 9 Jan 2018 13:45:15 -0200
+Subject: [PATCH] i386: Add spec-ctrl CPUID bit
+
+Add the feature name and a CPUID_7_0_EDX_SPEC_CTRL macro.
+
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Message-Id: <20180109154519.25634-4-ehabkost@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+---
+ target/i386/cpu.c | 2 +-
+ target/i386/cpu.h | 1 +
+ 2 files changed, 2 insertions(+), 1 deletion(-)
+
+Index: qemu/target-i386/cpu.c
+===================================================================
+--- qemu.orig/target-i386/cpu.c
++++ qemu/target-i386/cpu.c
+@@ -274,7 +274,7 @@ static const char *cpuid_7_0_edx_feature
+     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+-    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++    NULL, NULL, "spec-ctrl", NULL, NULL, NULL, NULL, NULL,
+ };
+ 
+ static const char *cpuid_apm_edx_feature_name[] = {
+Index: qemu/target-i386/cpu.h
+===================================================================
+--- qemu.orig/target-i386/cpu.h
++++ qemu/target-i386/cpu.h
+@@ -566,6 +566,7 @@ typedef uint32_t FeatureWordArray[FEATUR
+ #define CPUID_7_0_EBX_RDSEED   (1U << 18)
+ #define CPUID_7_0_EBX_ADX      (1U << 19)
+ #define CPUID_7_0_EBX_SMAP     (1U << 20)
++#define CPUID_7_0_EDX_SPEC_CTRL     (1U << 26) /* Speculation Control */
+ 
+ /* CPUID[0x80000007].EDX flags: */
+ #define CPUID_APM_INVTSC       (1U << 8)
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-5715-3pre1.patch qemu-2.1+dfsg/debian/patches/CVE-2017-5715-3pre1.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-5715-3pre1.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-5715-3pre1.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,86 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.38
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 886532
+
+Description: add FEAT_7_0_ECX and FEAT_7_0_EDX for backporting reasons
+Author: Marc Deslaurers <marc.deslauriers@canonical.com>
+
+Index: qemu/target-i386/cpu.c
+===================================================================
+--- qemu.orig/target-i386/cpu.c
++++ qemu/target-i386/cpu.c
+@@ -263,6 +263,20 @@ static const char *cpuid_7_0_ebx_feature
+     NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
+ };
+ 
++static const char *cpuid_7_0_ecx_feature_name[] = {
++    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++};
++
++static const char *cpuid_7_0_edx_feature_name[] = {
++    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++    NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
++};
++
+ static const char *cpuid_apm_edx_feature_name[] = {
+     NULL, NULL, NULL, NULL,
+     NULL, NULL, NULL, NULL,
+@@ -328,6 +342,8 @@ static const char *cpuid_apm_edx_feature
+           CPUID_7_0_EBX_FSGSBASE, CPUID_7_0_EBX_HLE, CPUID_7_0_EBX_AVX2,
+           CPUID_7_0_EBX_ERMS, CPUID_7_0_EBX_INVPCID, CPUID_7_0_EBX_RTM,
+           CPUID_7_0_EBX_RDSEED */
++#define TCG_7_0_ECX_FEATURES 0
++#define TCG_7_0_EDX_FEATURES 0
+ #define TCG_APM_FEATURES 0
+ 
+ 
+@@ -377,6 +393,20 @@ static FeatureWordInfo feature_word_info
+         .cpuid_eax = 0x8000000A, .cpuid_reg = R_EDX,
+         .tcg_features = TCG_SVM_FEATURES,
+     },
++    [FEAT_7_0_ECX] = {
++        .feat_names = cpuid_7_0_ecx_feature_name,
++        .cpuid_eax = 7,
++        .cpuid_needs_ecx = true, .cpuid_ecx = 0,
++        .cpuid_reg = R_ECX,
++        .tcg_features = TCG_7_0_ECX_FEATURES,
++    },
++    [FEAT_7_0_EDX] = {
++        .feat_names = cpuid_7_0_edx_feature_name,
++        .cpuid_eax = 7,
++        .cpuid_needs_ecx = true, .cpuid_ecx = 0,
++        .cpuid_reg = R_EDX,
++        .tcg_features = TCG_7_0_EDX_FEATURES,
++    },
+     [FEAT_7_0_EBX] = {
+         .feat_names = cpuid_7_0_ebx_feature_name,
+         .cpuid_eax = 7,
+@@ -2298,8 +2328,8 @@ void cpu_x86_cpuid(CPUX86State *env, uin
+         if (count == 0) {
+             *eax = 0; /* Maximum ECX value for sub-leaves */
+             *ebx = env->features[FEAT_7_0_EBX]; /* Feature flags */
+-            *ecx = 0; /* Reserved */
+-            *edx = 0; /* Reserved */
++            *ecx = env->features[FEAT_7_0_ECX]; /* Feature flags */
++            *edx = env->features[FEAT_7_0_EDX]; /* Feature flags */
+         } else {
+             *eax = 0;
+             *ebx = 0;
+Index: qemu/target-i386/cpu.h
+===================================================================
+--- qemu.orig/target-i386/cpu.h
++++ qemu/target-i386/cpu.h
+@@ -403,6 +403,8 @@ typedef enum FeatureWord {
+     FEAT_1_EDX,         /* CPUID[1].EDX */
+     FEAT_1_ECX,         /* CPUID[1].ECX */
+     FEAT_7_0_EBX,       /* CPUID[EAX=7,ECX=0].EBX */
++    FEAT_7_0_ECX,       /* CPUID[EAX=7,ECX=0].ECX */
++    FEAT_7_0_EDX,       /* CPUID[EAX=7,ECX=0].EDX */
+     FEAT_8000_0001_EDX, /* CPUID[8000_0001].EDX */
+     FEAT_8000_0001_ECX, /* CPUID[8000_0001].ECX */
+     FEAT_8000_0007_EDX, /* CPUID[8000_0007].EDX */
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-5715-4.patch qemu-2.1+dfsg/debian/patches/CVE-2017-5715-4.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-5715-4.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-5715-4.patch	2018-07-25 19:13:33.000000000 +0200
@@ -0,0 +1,87 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.38
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 886532
+
+Backport of:
+
+From 1b3420e1c4d523c49866cca4e7544753201cd43d Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Tue, 9 Jan 2018 13:45:16 -0200
+Subject: [PATCH] i386: Add FEAT_8000_0008_EBX CPUID feature word
+
+Add the new feature word and the "ibpb" feature flag.
+
+Based on a patch by Paolo Bonzini.
+
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Message-Id: <20180109154519.25634-5-ehabkost@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+---
+ target/i386/cpu.c | 19 ++++++++++++++++++-
+ target/i386/cpu.h |  3 +++
+ 2 files changed, 21 insertions(+), 1 deletion(-)
+
+Index: qemu/target-i386/cpu.c
+===================================================================
+--- qemu.orig/target-i386/cpu.c
++++ qemu/target-i386/cpu.c
+@@ -347,6 +347,17 @@ static const char *cpuid_apm_edx_feature
+ #define TCG_APM_FEATURES 0
+ 
+ 
++static const char *cpuid_8000_0008_ebx_feature_name[] = {
++    NULL, NULL, NULL, NULL,
++    NULL, NULL, NULL, NULL,
++    NULL, NULL, NULL, NULL,
++    "ibpb", NULL, NULL, NULL,
++    NULL, NULL, NULL, NULL,
++    NULL, NULL, NULL, NULL,
++    NULL, NULL, NULL, NULL,
++    NULL, NULL, NULL, NULL,
++};
++
+ typedef struct FeatureWordInfo {
+     const char **feat_names;
+     uint32_t cpuid_eax;   /* Input EAX for CPUID */
+@@ -421,6 +432,11 @@ static FeatureWordInfo feature_word_info
+         .tcg_features = TCG_APM_FEATURES,
+         .unmigratable_flags = CPUID_APM_INVTSC,
+     },
++    [FEAT_8000_0008_EBX] = {
++        .feat_names = cpuid_8000_0008_ebx_feature_name,
++        .cpuid_eax = 0x80000008,
++        .cpuid_reg = R_EBX,
++    },
+ };
+ 
+ typedef struct X86RegisterInfo32 {
+@@ -2495,7 +2511,7 @@ void cpu_x86_cpuid(CPUX86State *env, uin
+                 *eax = 0x00000020; /* 32 bits physical */
+             }
+         }
+-        *ebx = 0;
++        *ebx = env->features[FEAT_8000_0008_EBX];
+         *ecx = 0;
+         *edx = 0;
+         if (cs->nr_cores * cs->nr_threads > 1) {
+Index: qemu/target-i386/cpu.h
+===================================================================
+--- qemu.orig/target-i386/cpu.h
++++ qemu/target-i386/cpu.h
+@@ -408,6 +408,7 @@ typedef enum FeatureWord {
+     FEAT_8000_0001_EDX, /* CPUID[8000_0001].EDX */
+     FEAT_8000_0001_ECX, /* CPUID[8000_0001].ECX */
+     FEAT_8000_0007_EDX, /* CPUID[8000_0007].EDX */
++    FEAT_8000_0008_EBX, /* CPUID[8000_0008].EBX */
+     FEAT_C000_0001_EDX, /* CPUID[C000_0001].EDX */
+     FEAT_KVM,           /* CPUID[4000_0001].EAX (KVM_CPUID_FEATURES) */
+     FEAT_SVM,           /* CPUID[8000_000A].EDX */
+@@ -571,6 +572,8 @@ typedef uint32_t FeatureWordArray[FEATUR
+ /* CPUID[0x80000007].EDX flags: */
+ #define CPUID_APM_INVTSC       (1U << 8)
+ 
++#define CPUID_8000_0008_EBX_IBPB    (1U << 12) /* Indirect Branch Prediction Barrier */
++
+ #define CPUID_VENDOR_SZ      12
+ 
+ #define CPUID_VENDOR_INTEL_1 0x756e6547 /* "Genu" */
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-5715-5.patch qemu-2.1+dfsg/debian/patches/CVE-2017-5715-5.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-5715-5.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-5715-5.patch	2018-07-25 19:13:33.000000000 +0200
@@ -0,0 +1,176 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.38
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 886532
+
+Backport of:
+
+From ac96c41354b7e4c70b756342d9b686e31ab87458 Mon Sep 17 00:00:00 2001
+From: Eduardo Habkost <ehabkost@redhat.com>
+Date: Tue, 9 Jan 2018 13:45:17 -0200
+Subject: [PATCH] i386: Add new -IBRS versions of Intel CPU models
+
+The new MSR IA32_SPEC_CTRL MSR was introduced by a recent Intel
+microcode updated and can be used by OSes to mitigate
+CVE-2017-5715.  Unfortunately we can't change the existing CPU
+models without breaking existing setups, so users need to
+explicitly update their VM configuration to use the new *-IBRS
+CPU model if they want to expose IBRS to guests.
+
+The new CPU models are simple copies of the existing CPU models,
+with just CPUID_7_0_EDX_SPEC_CTRL added and model_id updated.
+
+Cc: Jiri Denemark <jdenemar@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+Message-Id: <20180109154519.25634-6-ehabkost@redhat.com>
+Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
+---
+ target/i386/cpu.c | 379 +++++++++++++++++++++++++++++++++++++++++++++++++++++-
+ 1 file changed, 378 insertions(+), 1 deletion(-)
+
+Index: qemu/target-i386/cpu.c
+===================================================================
+--- qemu.orig/target-i386/cpu.c
++++ qemu/target-i386/cpu.c
+@@ -1004,6 +1004,31 @@ static X86CPUDefinition builtin_x86_defs
+         .model_id = "Intel Core i7 9xx (Nehalem Class Core i7)",
+     },
+     {
++        .name = "Nehalem-IBRS",
++        .level = 4,
++        .vendor = CPUID_VENDOR_INTEL,
++        .family = 6,
++        .model = 26,
++        .stepping = 3,
++        .features[FEAT_1_EDX] =
++            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
++             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
++             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
++             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
++             CPUID_DE | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_POPCNT | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
++             CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_SSE3,
++        .features[FEAT_7_0_EDX] =
++            CPUID_7_0_EDX_SPEC_CTRL,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_LAHF_LM,
++        .xlevel = 0x8000000A,
++        .model_id = "Intel Core i7 9xx (Nehalem Core i7, IBRS update)",
++    },
++    {
+         .name = "Westmere",
+         .level = 11,
+         .vendor = CPUID_VENDOR_INTEL,
+@@ -1028,6 +1053,32 @@ static X86CPUDefinition builtin_x86_defs
+         .model_id = "Westmere E56xx/L56xx/X56xx (Nehalem-C)",
+     },
+     {
++        .name = "Westmere-IBRS",
++        .level = 11,
++        .vendor = CPUID_VENDOR_INTEL,
++        .family = 6,
++        .model = 44,
++        .stepping = 1,
++        .features[FEAT_1_EDX] =
++            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
++             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
++             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
++             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
++             CPUID_DE | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_AES | CPUID_EXT_POPCNT | CPUID_EXT_SSE42 |
++             CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
++             CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_SYSCALL | CPUID_EXT2_NX,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_LAHF_LM,
++        .features[FEAT_7_0_EDX] =
++            CPUID_7_0_EDX_SPEC_CTRL,
++        .xlevel = 0x8000000A,
++        .model_id = "Westmere E56xx/L56xx/X56xx (IBRS update)",
++    },
++    {
+         .name = "SandyBridge",
+         .level = 0xd,
+         .vendor = CPUID_VENDOR_INTEL,
+@@ -1055,6 +1106,35 @@ static X86CPUDefinition builtin_x86_defs
+         .model_id = "Intel Xeon E312xx (Sandy Bridge)",
+     },
+     {
++        .name = "SandyBridge-IBRS",
++        .level = 0xd,
++        .vendor = CPUID_VENDOR_INTEL,
++        .family = 6,
++        .model = 42,
++        .stepping = 1,
++        .features[FEAT_1_EDX] =
++            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
++             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
++             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
++             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
++             CPUID_DE | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
++             CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_POPCNT |
++             CPUID_EXT_X2APIC | CPUID_EXT_SSE42 | CPUID_EXT_SSE41 |
++             CPUID_EXT_CX16 | CPUID_EXT_SSSE3 | CPUID_EXT_PCLMULQDQ |
++             CPUID_EXT_SSE3,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
++             CPUID_EXT2_SYSCALL,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_LAHF_LM,
++        .features[FEAT_7_0_EDX] =
++            CPUID_7_0_EDX_SPEC_CTRL,
++        .xlevel = 0x8000000A,
++        .model_id = "Intel Xeon E312xx (Sandy Bridge, IBRS update)",
++    },
++    {
+         .name = "Haswell",
+         .level = 0xd,
+         .vendor = CPUID_VENDOR_INTEL,
+@@ -1122,6 +1202,41 @@ static X86CPUDefinition builtin_x86_defs
+         .model_id = "Intel Core Processor (Broadwell)",
+     },
+     {
++        .name = "Haswell-IBRS",
++        .level = 0xd,
++        .vendor = CPUID_VENDOR_INTEL,
++        .family = 6,
++        .model = 60,
++        .stepping = 1,
++        .features[FEAT_1_EDX] =
++            CPUID_SSE2 | CPUID_SSE | CPUID_FXSR | CPUID_MMX |
++             CPUID_CLFLUSH | CPUID_PSE36 | CPUID_PAT | CPUID_CMOV | CPUID_MCA |
++             CPUID_PGE | CPUID_MTRR | CPUID_SEP | CPUID_APIC | CPUID_CX8 |
++             CPUID_MCE | CPUID_PAE | CPUID_MSR | CPUID_TSC | CPUID_PSE |
++             CPUID_DE | CPUID_FP87,
++        .features[FEAT_1_ECX] =
++            CPUID_EXT_AVX | CPUID_EXT_XSAVE | CPUID_EXT_AES |
++             CPUID_EXT_POPCNT | CPUID_EXT_X2APIC | CPUID_EXT_SSE42 |
++             CPUID_EXT_SSE41 | CPUID_EXT_CX16 | CPUID_EXT_SSSE3 |
++             CPUID_EXT_PCLMULQDQ | CPUID_EXT_SSE3 |
++             CPUID_EXT_TSC_DEADLINE_TIMER | CPUID_EXT_FMA | CPUID_EXT_MOVBE |
++             CPUID_EXT_PCID,
++        .features[FEAT_8000_0001_EDX] =
++            CPUID_EXT2_LM | CPUID_EXT2_RDTSCP | CPUID_EXT2_NX |
++             CPUID_EXT2_SYSCALL,
++        .features[FEAT_8000_0001_ECX] =
++            CPUID_EXT3_LAHF_LM,
++        .features[FEAT_7_0_EDX] =
++            CPUID_7_0_EDX_SPEC_CTRL,
++        .features[FEAT_7_0_EBX] =
++            CPUID_7_0_EBX_FSGSBASE | CPUID_7_0_EBX_BMI1 |
++            CPUID_7_0_EBX_HLE | CPUID_7_0_EBX_AVX2 | CPUID_7_0_EBX_SMEP |
++            CPUID_7_0_EBX_BMI2 | CPUID_7_0_EBX_ERMS | CPUID_7_0_EBX_INVPCID |
++            CPUID_7_0_EBX_RTM,
++        .xlevel = 0x8000000A,
++        .model_id = "Intel Core Processor (Haswell, IBRS)",
++    },
++    {
+         .name = "Opteron_G1",
+         .level = 5,
+         .vendor = CPUID_VENDOR_AMD,
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-5856.patch qemu-2.1+dfsg/debian/patches/CVE-2017-5856.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-5856.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-5856.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,65 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 853996
+
+From 765a707000e838c30b18d712fe6cb3dd8e0435f3 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Mon, 2 Jan 2017 11:03:33 +0100
+Subject: [PATCH] megasas: fix guest-triggered memory leak
+
+If the guest sets the sglist size to a value >=2GB, megasas_handle_dcmd
+will return MFI_STAT_MEMORY_NOT_AVAILABLE without freeing the memory.
+Avoid this by returning only the status from map_dcmd, and loading
+cmd->iov_size in the caller.
+
+Reported-by: Li Qiang <liqiang6-s@360.cn>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/scsi/megasas.c | 11 ++++++-----
+ 1 file changed, 6 insertions(+), 5 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/scsi/megasas.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/scsi/megasas.c	2017-04-06 09:58:28.055079302 -0400
++++ qemu-2.0.0+dfsg/hw/scsi/megasas.c	2017-04-06 09:58:28.051079252 -0400
+@@ -640,14 +640,14 @@
+         trace_megasas_dcmd_invalid_sge(cmd->index,
+                                        cmd->frame->header.sge_count);
+         cmd->iov_size = 0;
+-        return -1;
++        return -EINVAL;
+     }
+     iov_pa = megasas_sgl_get_addr(cmd, &cmd->frame->dcmd.sgl);
+     iov_size = megasas_sgl_get_len(cmd, &cmd->frame->dcmd.sgl);
+     pci_dma_sglist_init(&cmd->qsg, PCI_DEVICE(s), 1);
+     qemu_sglist_add(&cmd->qsg, iov_pa, iov_size);
+     cmd->iov_size = iov_size;
+-    return cmd->iov_size;
++    return 0;
+ }
+ 
+ static void megasas_finish_dcmd(MegasasCmd *cmd, uint32_t iov_size)
+@@ -1449,19 +1449,20 @@
+ 
+ static int megasas_handle_dcmd(MegasasState *s, MegasasCmd *cmd)
+ {
+-    int opcode, len;
++    int opcode;
+     int retval = 0;
++    size_t len;
+     const struct dcmd_cmd_tbl_t *cmdptr = dcmd_cmd_tbl;
+ 
+     opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
+     trace_megasas_handle_dcmd(cmd->index, opcode);
+-    len = megasas_map_dcmd(s, cmd);
+-    if (len < 0) {
++    if (megasas_map_dcmd(s, cmd) < 0) {
+         return MFI_STAT_MEMORY_NOT_AVAILABLE;
+     }
+     while (cmdptr->opcode != -1 && cmdptr->opcode != opcode) {
+         cmdptr++;
+     }
++    len = cmd->iov_size;
+     if (cmdptr->opcode == -1) {
+         trace_megasas_dcmd_unhandled(cmd->index, opcode, len);
+         retval = megasas_dcmd_dummy(s, cmd);
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-5973.patch qemu-2.1+dfsg/debian/patches/CVE-2017-5973.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-5973.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-5973.patch	2018-07-26 00:21:11.000000000 +0200
@@ -0,0 +1,99 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by: Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 855611
+
+Backport of:
+
+From f89b60f6e5fee3923bedf80e82b4e5efc1bb156b Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Mon, 6 Feb 2017 13:21:09 +0100
+Subject: [PATCH] xhci: apply limits to loops
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf8
+Content-Transfer-Encoding: 8bit
+
+Limits should be big enough that normal guest should not hit it.
+Add a tracepoint to log them, just in case.  Also, while being
+at it, log the existing link trb limit too.
+
+Reported-by: æ??强 <liqiang6-s@360.cn>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: 1486383669-6421-1-git-send-email-kraxel@redhat.com
+---
+ hw/usb/hcd-xhci.c   | 15 ++++++++++++++-
+ hw/usb/trace-events |  1 +
+ 2 files changed, 15 insertions(+), 1 deletion(-)
+
+Index: qemu/hw/usb/hcd-xhci.c
+===================================================================
+--- qemu.orig/hw/usb/hcd-xhci.c
++++ qemu/hw/usb/hcd-xhci.c
+@@ -53,6 +53,8 @@
+ #define ER_FULL_HACK
+ 
+ #define TRB_LINK_LIMIT  4
++#define COMMAND_LIMIT   256
++#define TRANSFER_LIMIT  256
+ 
+ #define LEN_CAP         0x40
+ #define LEN_OPER        (0x400 + 0x10 * MAXPORTS)
+@@ -1024,6 +1026,7 @@ static TRBType xhci_ring_fetch(XHCIState
+             return type;
+         } else {
+             if (++link_cnt > TRB_LINK_LIMIT) {
++                trace_usb_xhci_enforced_limit("trb-link");
+                 return 0;
+             }
+             ring->dequeue = xhci_mask64(trb->parameter);
+@@ -2093,6 +2096,7 @@ static void xhci_kick_ep(XHCIState *xhci
+     XHCIRing *ring;
+     USBEndpoint *ep = NULL;
+     uint64_t mfindex;
++    unsigned int count = 0;
+     int length;
+     int i;
+ 
+@@ -2231,6 +2235,10 @@ static void xhci_kick_ep(XHCIState *xhci
+             epctx->retry = xfer;
+             break;
+         }
++        if (count++ > TRANSFER_LIMIT) {
++            trace_usb_xhci_enforced_limit("transfers");
++            break;
++        }
+     }
+ 
+     ep = xhci_epid_to_usbep(xhci, slotid, epid);
+@@ -2698,7 +2706,7 @@ static void xhci_process_commands(XHCISt
+     TRBType type;
+     XHCIEvent event = {ER_COMMAND_COMPLETE, CC_SUCCESS};
+     dma_addr_t addr;
+-    unsigned int i, slotid = 0;
++    unsigned int i, slotid = 0, count = 0;
+ 
+     DPRINTF("xhci_process_commands()\n");
+     if (!xhci_running(xhci)) {
+@@ -2812,6 +2820,11 @@ static void xhci_process_commands(XHCISt
+         }
+         event.slotid = slotid;
+         xhci_event(xhci, &event, 0);
++
++        if (count++ > COMMAND_LIMIT) {
++            trace_usb_xhci_enforced_limit("commands");
++            return;
++        }
+     }
+ }
+ 
+Index: qemu/trace-events
+===================================================================
+--- qemu.orig/trace-events
++++ qemu/trace-events
+@@ -394,6 +394,7 @@ usb_xhci_xfer_retry(void *xfer) "%p"
+ usb_xhci_xfer_success(void *xfer, uint32_t bytes) "%p: len %d"
+ usb_xhci_xfer_error(void *xfer, uint32_t ret) "%p: ret %d"
+ usb_xhci_unimplemented(const char *item, int nr) "%s (0x%x)"
++usb_xhci_enforced_limit(const char *item) "%s"
+ 
+ # hw/usb/desc.c
+ usb_desc_device(int addr, int len, int ret) "dev %d query device, len %d, ret %d"
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-5987-1.patch qemu-2.1+dfsg/debian/patches/CVE-2017-5987-1.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-5987-1.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-5987-1.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,42 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 855159
+
+From 8b20aefac4ee8874bb9c8826e4b30e1dc8cd7511 Mon Sep 17 00:00:00 2001
+From: Prasad J Pandit <pjp@fedoraproject.org>
+Date: Tue, 28 Feb 2017 12:08:14 +0000
+Subject: [PATCH] sd: sdhci: mask transfer mode register value
+
+In SDHCI protocol, the transfer mode register is defined
+to be of 6 bits. Mask its value with '0x0037' so that an
+invalid value could not be assigned.
+
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
+Message-id: 20170214185225.7994-2-ppandit@redhat.com
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+---
+ hw/sd/sdhci.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+Index: qemu-2.0.0+dfsg/hw/sd/sdhci.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/sd/sdhci.c	2017-04-06 10:00:01.628252853 -0400
++++ qemu-2.0.0+dfsg/hw/sd/sdhci.c	2017-04-06 10:00:01.628252853 -0400
+@@ -114,6 +114,7 @@
+     (SDHC_CAPAB_BASECLKFREQ << 8) | (SDHC_CAPAB_TOUNIT << 7) | \
+     (SDHC_CAPAB_TOCLKFREQ))
+ 
++#define MASK_TRNMOD     0x0037
+ #define MASKED_WRITE(reg, mask, val)  (reg = (reg & (mask)) | (val))
+ 
+ static uint8_t sdhci_slotint(SDHCIState *s)
+@@ -1016,7 +1017,7 @@
+         if (!(s->capareg & SDHC_CAN_DO_DMA)) {
+             value &= ~SDHC_TRNS_DMA;
+         }
+-        MASKED_WRITE(s->trnmod, mask, value);
++        MASKED_WRITE(s->trnmod, mask, value & MASK_TRNMOD);
+         MASKED_WRITE(s->cmdreg, mask >> 16, value >> 16);
+ 
+         /* Writing to the upper byte of CMDREG triggers SD command generation */
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-5987-2.patch qemu-2.1+dfsg/debian/patches/CVE-2017-5987-2.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-5987-2.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-5987-2.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,55 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 855159
+
+From 6e86d90352adf6cb08295255220295cf23c4286e Mon Sep 17 00:00:00 2001
+From: Prasad J Pandit <pjp@fedoraproject.org>
+Date: Tue, 28 Feb 2017 12:08:14 +0000
+Subject: [PATCH] sd: sdhci: check transfer mode register in multi block
+ transfer
+
+In the SDHCI protocol, the transfer mode register value
+is used during multi block transfer to check if block count
+register is enabled and should be updated. Transfer mode
+register could be set such that, block count register would
+not be updated, thus leading to an infinite loop. Add check
+to avoid it.
+
+Reported-by: Wjjzhang <wjjzhang@tencent.com>
+Reported-by: Jiang Xin <jiangxin1@huawei.com>
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Message-id: 20170214185225.7994-3-ppandit@redhat.com
+Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+---
+ hw/sd/sdhci.c | 10 +++++-----
+ 1 file changed, 5 insertions(+), 5 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/sd/sdhci.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/sd/sdhci.c	2017-04-06 10:00:09.128346859 -0400
++++ qemu-2.0.0+dfsg/hw/sd/sdhci.c	2017-04-06 10:00:09.124346809 -0400
+@@ -469,6 +469,11 @@
+     uint32_t boundary_chk = 1 << (((s->blksize & 0xf000) >> 12) + 12);
+     uint32_t boundary_count = boundary_chk - (s->sdmasysad % boundary_chk);
+ 
++    if (!(s->trnmod & SDHC_TRNS_BLK_CNT_EN) || !s->blkcnt) {
++        qemu_log_mask(LOG_UNIMP, "infinite transfer is not supported\n");
++        return;
++    }
++
+     /* XXX: Some sd/mmc drivers (for example, u-boot-slp) do not account for
+      * possible stop at page boundary if initial address is not page aligned,
+      * allow them to work properly */
+@@ -777,11 +782,6 @@
+     if (s->trnmod & SDHC_TRNS_DMA) {
+         switch (SDHC_DMA_TYPE(s->hostctl)) {
+         case SDHC_CTRL_SDMA:
+-            if ((s->trnmod & SDHC_TRNS_MULTI) &&
+-                    (!(s->trnmod & SDHC_TRNS_BLK_CNT_EN) || s->blkcnt == 0)) {
+-                break;
+-            }
+-
+             if ((s->blkcnt == 1) || !(s->trnmod & SDHC_TRNS_MULTI)) {
+                 k->do_sdma_single(s);
+             } else {
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-5987-3.patch qemu-2.1+dfsg/debian/patches/CVE-2017-5987-3.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-5987-3.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-5987-3.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,39 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 855159
+
+Backport of:
+
+From 45ba9f761bde329cc5ef276b571bd4f3c41a044e Mon Sep 17 00:00:00 2001
+From: Prasad J Pandit <pjp@fedoraproject.org>
+Date: Tue, 28 Feb 2017 12:08:14 +0000
+Subject: [PATCH] sd: sdhci: conditionally invoke multi block transfer
+
+In sdhci_write invoke multi block transfer if it is enabled
+in the transfer mode register 's->trnmod'.
+
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Message-id: 20170214185225.7994-4-ppandit@redhat.com
+Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+---
+ hw/sd/sdhci.c | 6 +++++-
+ 1 file changed, 5 insertions(+), 1 deletion(-)
+
+Index: qemu-2.0.0+dfsg/hw/sd/sdhci.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/sd/sdhci.c	2017-04-06 10:00:16.620440758 -0400
++++ qemu-2.0.0+dfsg/hw/sd/sdhci.c	2017-04-06 10:01:48.933597061 -0400
+@@ -999,7 +999,11 @@
+         /* Writing to last byte of sdmasysad might trigger transfer */
+         if (!(mask & 0xFF000000) && TRANSFERRING_DATA(s->prnsts) && s->blkcnt &&
+                 s->blksize && SDHC_DMA_TYPE(s->hostctl) == SDHC_CTRL_SDMA) {
+-            SDHCI_GET_CLASS(s)->do_sdma_multi(s);
++            if (s->trnmod & SDHC_TRNS_MULTI) {
++                SDHCI_GET_CLASS(s)->do_sdma_multi(s);
++            } else {
++                SDHCI_GET_CLASS(s)->do_sdma_single(s);
++            }
+         }
+         break;
+     case SDHC_BLKSIZE:
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-5987-4.patch qemu-2.1+dfsg/debian/patches/CVE-2017-5987-4.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-5987-4.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-5987-4.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,46 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 855159
+
+From 241999bf4c0dd75d300ceee46f7ad28b3a39fe97 Mon Sep 17 00:00:00 2001
+From: Prasad J Pandit <pjp@fedoraproject.org>
+Date: Tue, 28 Feb 2017 12:08:15 +0000
+Subject: [PATCH] sd: sdhci: Remove block count enable check in single block
+ transfers
+
+In SDHCI protocol, the 'Block count enable' bit of the Transfer
+Mode register is relevant only in multi block transfers. We need
+not check it in single block transfers.
+
+Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
+Message-id: 20170214185225.7994-5-ppandit@redhat.com
+Reviewed-by: Alistair Francis <alistair.francis@xilinx.com>
+Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+---
+ hw/sd/sdhci.c | 6 +-----
+ 1 file changed, 1 insertion(+), 5 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/sd/sdhci.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/sd/sdhci.c	2017-04-06 10:02:18.973973088 -0400
++++ qemu-2.0.0+dfsg/hw/sd/sdhci.c	2017-04-06 10:02:18.969973037 -0400
+@@ -552,7 +552,6 @@
+ }
+ 
+ /* single block SDMA transfer */
+-
+ static void sdhci_sdma_transfer_single_block(SDHCIState *s)
+ {
+     int n;
+@@ -571,10 +570,7 @@
+             sd_write_data(s->card, s->fifo_buffer[n]);
+         }
+     }
+-
+-    if (s->trnmod & SDHC_TRNS_BLK_CNT_EN) {
+-        s->blkcnt--;
+-    }
++    s->blkcnt--;
+ 
+     SDHCI_GET_CLASS(s)->end_data_transfer(s);
+ }
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-6505.patch qemu-2.1+dfsg/debian/patches/CVE-2017-6505.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-6505.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-6505.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,53 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.33
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 856969
+
+From 95ed56939eb2eaa4e2f349fe6dcd13ca4edfd8fb Mon Sep 17 00:00:00 2001
+From: Li Qiang <liqiang6-s@360.cn>
+Date: Tue, 7 Feb 2017 02:23:33 -0800
+Subject: [PATCH] usb: ohci: limit the number of link eds
+
+The guest may builds an infinite loop with link eds. This patch
+limit the number of linked ed to avoid this.
+
+Signed-off-by: Li Qiang <liqiang6-s@360.cn>
+Message-id: 5899a02e.45ca240a.6c373.93c1@mx.google.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/usb/hcd-ohci.c | 9 ++++++++-
+ 1 file changed, 8 insertions(+), 1 deletion(-)
+
+Index: qemu-2.0.0+dfsg/hw/usb/hcd-ohci.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/usb/hcd-ohci.c	2017-04-06 10:02:27.030073908 -0400
++++ qemu-2.0.0+dfsg/hw/usb/hcd-ohci.c	2017-04-06 10:02:27.026073858 -0400
+@@ -49,6 +49,8 @@
+ 
+ #define OHCI_MAX_PORTS 15
+ 
++#define ED_LINK_LIMIT 4
++
+ static int64_t usb_frame_time;
+ static int64_t usb_bit_time;
+ 
+@@ -1190,7 +1192,7 @@
+     uint32_t next_ed;
+     uint32_t cur;
+     int active;
+-
++    uint32_t link_cnt = 0;
+     active = 0;
+ 
+     if (head == 0)
+@@ -1205,6 +1207,11 @@
+ 
+         next_ed = ed.next & OHCI_DPTR_MASK;
+ 
++        if (++link_cnt > ED_LINK_LIMIT) {
++            ohci_die(ohci);
++            return 0;
++        }
++
+         if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) {
+             uint32_t addr;
+             /* Cancel pending packets for ED that have been paused.  */
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-7377.patch qemu-2.1+dfsg/debian/patches/CVE-2017-7377.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-7377.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-7377.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,52 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.34
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 859854
+
+Backport of:
+
+From d63fb193e71644a073b77ff5ac6f1216f2f6cf6e Mon Sep 17 00:00:00 2001
+From: Li Qiang <liq3ea@gmail.com>
+Date: Mon, 27 Mar 2017 21:13:19 +0200
+Subject: [PATCH] 9pfs: fix file descriptor leak
+
+The v9fs_create() and v9fs_lcreate() functions are used to create a file
+on the backend and to associate it to a fid. The fid shouldn't be already
+in-use, otherwise both functions may silently leak a file descriptor or
+allocated memory. The current code doesn't check that.
+
+This patch ensures that the fid isn't already associated to anything
+before using it.
+
+Signed-off-by: Li Qiang <liqiang6-s@360.cn>
+(reworded the changelog, Greg Kurz)
+Signed-off-by: Greg Kurz <groug@kaod.org>
+---
+ hw/9pfs/9p.c | 8 ++++++++
+ 1 file changed, 8 insertions(+)
+
+Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p.c	2017-05-10 15:35:09.642553470 -0400
++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c	2017-05-10 15:35:09.626553317 -0400
+@@ -1500,6 +1500,10 @@ static void v9fs_lcreate(void *opaque)
+         err = -ENOENT;
+         goto out_nofid;
+     }
++    if (fidp->fid_type != P9_FID_NONE) {
++        err = -EINVAL;
++        goto out;
++    }
+ 
+     flags = get_dotl_openflags(pdu->s, flags);
+     err = v9fs_co_open2(pdu, fidp, &name, gid,
+@@ -2092,6 +2096,10 @@ static void v9fs_create(void *opaque)
+         err = -EINVAL;
+         goto out_nofid;
+     }
++    if (fidp->fid_type != P9_FID_NONE) {
++        err = -EINVAL;
++        goto out;
++    }
+     if (perm & P9_STAT_MODE_DIR) {
+         err = v9fs_co_mkdir(pdu, fidp, &name, perm & 0777,
+                             fidp->uid, -1, &stbuf);
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-7471.patch qemu-2.1+dfsg/debian/patches/CVE-2017-7471.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-7471.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-7471.patch	2018-07-24 16:08:46.000000000 +0200
@@ -0,0 +1,60 @@
+Origin: backported, http://git.qemu-project.org/?p=qemu.git;a=commitdiff;h=9c6b899f7a46893ab3b671e341a2234e9c0c060e
+Reviewed-by: Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 860785
+
+commit 9c6b899f7a46893ab3b671e341a2234e9c0c060e
+Author: Greg Kurz <groug@kaod.org>
+Date:   Mon Apr 17 10:53:23 2017 +0200
+
+    9pfs: local: set the path of the export root to "."
+    
+    The local backend was recently converted to using "at*()" syscalls in order
+    to ensure all accesses happen below the shared directory. This requires that
+    we only pass relative paths, otherwise the dirfd argument to the "at*()"
+    syscalls is ignored and the path is treated as an absolute path in the host.
+    This is actually the case for paths in all fids, with the notable exception
+    of the root fid, whose path is "/". This causes the following backend ops to
+    act on the "/" directory of the host instead of the virtfs shared directory
+    when the export root is involved:
+    - lstat
+    - chmod
+    - chown
+    - utimensat
+    
+    ie, chmod /9p_mount_point in the guest will be converted to chmod / in the
+    host for example. This could cause security issues with a privileged QEMU.
+    
+    All "*at()" syscalls are being passed an open file descriptor. In the case
+    of the export root, this file descriptor points to the path in the host that
+    was passed to -fsdev.
+    
+    The fix is thus as simple as changing the path of the export root fid to be
+    "." instead of "/".
+    
+    This is CVE-2017-7471.
+    
+    Cc: qemu-stable@nongnu.org
+    Reported-by: Léo Gaspard <leo@gaspard.io>
+    Signed-off-by: Greg Kurz <groug@kaod.org>
+    Reviewed-by: Eric Blake <eblake@redhat.com>
+    Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
+
+Index: qemu/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu.orig/hw/9pfs/virtio-9p-local.c
++++ qemu/hw/9pfs/virtio-9p-local.c
+@@ -1094,8 +1094,13 @@ static int local_name_to_path(FsContext
+     if (dir_path) {
+         v9fs_string_sprintf((V9fsString *)target, "%s/%s",
+                             dir_path->data, name);
+-    } else {
++    } else if (strcmp(name, "/")) {
+         v9fs_string_sprintf((V9fsString *)target, "%s", name);
++    } else {
++        /* We want the path of the export root to be relative, otherwise
++         * "*at()" syscalls would treat it as "/" in the host.
++         */
++        v9fs_string_sprintf((V9fsString *)target, "%s", ".");
+     }
+     /* Bump the size for including terminating NULL */
+     target->size++;
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-7493.patch qemu-2.1+dfsg/debian/patches/CVE-2017-7493.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-7493.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-7493.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,176 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.35
+Reviewed-by: Santiago R.R. <santiagorr@riseup.net>
+
+Backport of:
+
+From 7a95434e0ca8a037fd8aa1a2e2461f92585eb77b Mon Sep 17 00:00:00 2001
+From: Greg Kurz <groug@kaod.org>
+Date: Fri, 5 May 2017 14:48:08 +0200
+Subject: [PATCH] 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(-)
+
+Index: qemu/hw/9pfs/virtio-9p-local.c
+===================================================================
+--- qemu.orig/hw/9pfs/virtio-9p-local.c
++++ qemu/hw/9pfs/virtio-9p-local.c
+@@ -451,6 +451,11 @@ static off_t local_telldir(FsContext *ct
+     return telldir(fs->dir);
+ }
+ 
++static bool local_is_mapped_file_metadata(FsContext *fs_ctx, const char *name)
++{
++    return !strcmp(name, VIRTFS_META_DIR);
++}
++
+ static int local_readdir_r(FsContext *ctx, V9fsFidOpenState *fs,
+                            struct dirent *entry,
+                            struct dirent **result)
+@@ -464,8 +469,8 @@ again:
+     }
+     else if (ctx->export_flags & V9FS_SM_MAPPED_FILE) {
+         if (!ret && *result != NULL &&
+-            !strcmp(entry->d_name, VIRTFS_META_DIR)) {
+-            /* skp the meta data directory */
++            local_is_mapped_file_metadata(ctx, entry->d_name)) {
++            /* skip the meta data directory */
+             goto again;
+         }
+         entry->d_type = DT_UNKNOWN;
+@@ -558,6 +563,12 @@ static int local_mknod(FsContext *fs_ctx
+     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;
+@@ -603,6 +614,12 @@ static int local_mkdir(FsContext *fs_ctx
+     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;
+@@ -692,6 +709,12 @@ static int local_open2(FsContext *fs_ctx
+     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
+      */
+@@ -750,6 +773,12 @@ static int local_symlink(FsContext *fs_c
+     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;
+@@ -824,6 +853,12 @@ static int local_link(FsContext *ctx, V9
+     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;
+@@ -1091,6 +1126,12 @@ static int local_lremovexattr(FsContext
+ 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_string_sprintf((V9fsString *)target, "%s/%s",
+                             dir_path->data, name);
+@@ -1114,6 +1155,13 @@ static int local_renameat(FsContext *ctx
+     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;
+@@ -1204,6 +1252,12 @@ static int local_unlinkat(FsContext *ctx
+     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;
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-7718.patch qemu-2.1+dfsg/debian/patches/CVE-2017-7718.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-7718.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-7718.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,51 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.34
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+
+From 215902d7b6fb50c6fc216fc74f770858278ed904 Mon Sep 17 00:00:00 2001
+From: hangaohuai <hangaohuai@huawei.com>
+Date: Tue, 14 Mar 2017 14:39:19 +0800
+Subject: [PATCH] fix :cirrus_vga fix OOB read case qemu Segmentation fault
+
+check the validity of parameters in cirrus_bitblt_rop_fwd_transp_xxx
+and cirrus_bitblt_rop_fwd_xxx to avoid the OOB read which causes qemu Segmentation fault.
+
+After the fix, we will touch the assert in
+cirrus_invalidate_region:
+assert(off_cur_end >= off_cur);
+
+Signed-off-by: fangying <fangying1@huawei.com>
+Signed-off-by: hangaohuai <hangaohuai@huawei.com>
+Message-id: 20170314063919.16200-1-hangaohuai@huawei.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/display/cirrus_vga_rop.h | 10 ++++++++++
+ 1 file changed, 10 insertions(+)
+
+Index: qemu-2.0.0+dfsg/hw/display/cirrus_vga_rop.h
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/display/cirrus_vga_rop.h	2017-05-10 15:35:19.158644318 -0400
++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga_rop.h	2017-05-10 15:35:19.154644279 -0400
+@@ -98,6 +98,11 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_,
+     uint8_t p;
+     dstpitch -= bltwidth;
+     srcpitch -= bltwidth;
++
++    if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) {
++        return;
++    }
++
+     for (y = 0; y < bltheight; y++) {
+         for (x = 0; x < bltwidth; x++) {
+ 	    p = *dst;
+@@ -144,6 +149,11 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_,
+     uint8_t p1, p2;
+     dstpitch -= bltwidth;
+     srcpitch -= bltwidth;
++
++    if (bltheight > 1 && (dstpitch < 0 || srcpitch < 0)) {
++        return;
++    }
++
+     for (y = 0; y < bltheight; y++) {
+         for (x = 0; x < bltwidth; x+=2) {
+ 	    p1 = *dst;
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-7980-1-CVE-2017-18030.patch qemu-2.1+dfsg/debian/patches/CVE-2017-7980-1-CVE-2017-18030.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-7980-1-CVE-2017-18030.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-7980-1-CVE-2017-18030.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,50 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.34
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+
+From f153b563f8cf121aebf5a2fff5f0110faf58ccb3 Mon Sep 17 00:00:00 2001
+From: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Date: Wed, 25 Jan 2017 14:48:57 +0100
+Subject: [PATCH] cirrus: handle negative pitch in cirrus_invalidate_region()
+
+cirrus_invalidate_region() calls memory_region_set_dirty()
+on a per-line basis, always ranging from off_begin to
+off_begin+bytesperline. With a negative pitch off_begin
+marks the top most used address and thus we need to do an
+initial shift backwards by a line for negative pitches of
+backward blits, otherwise the first iteration covers the
+line going from the start offset forwards instead of
+backwards.
+Additionally since the start address is inclusive, if we
+shift by a full `bytesperline` we move to the first address
+*not* included in the blit, so we only shift by one less
+than bytesperline.
+
+Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Message-id: 1485352137-29367-1-git-send-email-w.bumiller@proxmox.com
+
+[ kraxel: codestyle fixes ]
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/display/cirrus_vga.c | 5 +++++
+ 1 file changed, 5 insertions(+)
+
+Index: qemu-2.0.0+dfsg/hw/display/cirrus_vga.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/display/cirrus_vga.c	2017-05-10 15:47:48.281796009 -0400
++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga.c	2017-05-10 15:47:48.277795970 -0400
+@@ -655,9 +655,14 @@ static void cirrus_invalidate_region(Cir
+     int off_cur;
+     int off_cur_end;
+ 
++    if (off_pitch < 0) {
++        off_begin -= bytesperline - 1;
++    }
++
+     for (y = 0; y < lines; y++) {
+ 	off_cur = off_begin;
+ 	off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask;
++        assert(off_cur_end >= off_cur);
+         memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur);
+ 	off_begin += off_pitch;
+     }
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-7980-2.patch qemu-2.1+dfsg/debian/patches/CVE-2017-7980-2.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-7980-2.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-7980-2.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,102 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.34
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+
+From 5858dd1801883309bdd208d72ddb81c4e9fee30c Mon Sep 17 00:00:00 2001
+From: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Date: Tue, 24 Jan 2017 16:35:38 +0100
+Subject: [PATCH] cirrus: allow zero source pitch in pattern fill rops
+
+The rops used by cirrus_bitblt_common_patterncopy only use
+the destination pitch, so the source pitch shoul allowed to
+be zero and the blit with used for the range check around the
+source address.
+
+Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Message-id: 1485272138-23249-1-git-send-email-w.bumiller@proxmox.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/display/cirrus_vga.c | 27 +++++++++++++++++++--------
+ 1 file changed, 19 insertions(+), 8 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/display/cirrus_vga.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/display/cirrus_vga.c	2017-05-10 15:47:55.761867419 -0400
++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga.c	2017-05-10 15:47:55.757867381 -0400
+@@ -267,9 +267,6 @@ static void cirrus_update_memory_access(
+ static bool blit_region_is_unsafe(struct CirrusVGAState *s,
+                                   int32_t pitch, int32_t addr)
+ {
+-    if (!pitch) {
+-        return true;
+-    }
+     if (pitch < 0) {
+         int64_t min = addr
+             + ((int64_t)s->cirrus_blt_height - 1) * pitch
+@@ -288,8 +285,11 @@ static bool blit_region_is_unsafe(struct
+     return false;
+ }
+ 
+-static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only)
++static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only,
++                           bool zero_src_pitch_ok)
+ {
++    int32_t check_pitch;
++
+     /* should be the case, see cirrus_bitblt_start */
+     assert(s->cirrus_blt_width > 0);
+     assert(s->cirrus_blt_height > 0);
+@@ -298,6 +298,10 @@ static bool blit_is_unsafe(struct Cirrus
+         return true;
+     }
+ 
++    if (!s->cirrus_blt_dstpitch) {
++        return true;
++    }
++
+     if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch,
+                               s->cirrus_blt_dstaddr & s->cirrus_addr_mask)) {
+         return true;
+@@ -305,7 +309,13 @@ static bool blit_is_unsafe(struct Cirrus
+     if (dst_only) {
+         return false;
+     }
+-    if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch,
++
++    check_pitch = s->cirrus_blt_srcpitch;
++    if (!zero_src_pitch_ok && !check_pitch) {
++        check_pitch = s->cirrus_blt_width;
++    }
++
++    if (blit_region_is_unsafe(s, check_pitch,
+                               s->cirrus_blt_srcaddr & s->cirrus_addr_mask)) {
+         return true;
+     }
+@@ -675,8 +685,9 @@ static int cirrus_bitblt_common_patternc
+ 
+     dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
+ 
+-    if (blit_is_unsafe(s, false))
++    if (blit_is_unsafe(s, false, true)) {
+         return 0;
++    }
+ 
+     (*s->cirrus_rop) (s, dst, src,
+                       s->cirrus_blt_dstpitch, 0,
+@@ -693,7 +704,7 @@ static int cirrus_bitblt_solidfill(Cirru
+ {
+     cirrus_fill_t rop_func;
+ 
+-    if (blit_is_unsafe(s, true)) {
++    if (blit_is_unsafe(s, true, true)) {
+         return 0;
+     }
+     rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
+@@ -791,7 +802,7 @@ static int cirrus_do_copy(CirrusVGAState
+ 
+ static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
+ {
+-    if (blit_is_unsafe(s, false))
++    if (blit_is_unsafe(s, false, false))
+         return 0;
+ 
+     return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-7980-3.patch qemu-2.1+dfsg/debian/patches/CVE-2017-7980-3.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-7980-3.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-7980-3.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,104 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.34
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+
+From 60cd23e85151525ab26591394c4e7e06fa07d216 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Wed, 25 Jan 2017 11:09:56 +0100
+Subject: [PATCH] cirrus: fix blit address mask handling
+
+Apply the cirrus_addr_mask to cirrus_blt_dstaddr and cirrus_blt_srcaddr
+right after assigning them, in cirrus_bitblt_start(), instead of having
+this all over the place in the cirrus code, and missing a few places.
+
+Reported-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: 1485338996-17095-1-git-send-email-kraxel@redhat.com
+---
+ hw/display/cirrus_vga.c | 25 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/display/cirrus_vga.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/display/cirrus_vga.c	2017-05-10 15:48:00.989917330 -0400
++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga.c	2017-05-10 15:48:00.985917292 -0400
+@@ -303,7 +303,7 @@ static bool blit_is_unsafe(struct Cirrus
+     }
+ 
+     if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch,
+-                              s->cirrus_blt_dstaddr & s->cirrus_addr_mask)) {
++                              s->cirrus_blt_dstaddr)) {
+         return true;
+     }
+     if (dst_only) {
+@@ -316,7 +316,7 @@ static bool blit_is_unsafe(struct Cirrus
+     }
+ 
+     if (blit_region_is_unsafe(s, check_pitch,
+-                              s->cirrus_blt_srcaddr & s->cirrus_addr_mask)) {
++                              s->cirrus_blt_srcaddr)) {
+         return true;
+     }
+ 
+@@ -683,7 +683,7 @@ static int cirrus_bitblt_common_patternc
+ {
+     uint8_t *dst;
+ 
+-    dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask);
++    dst = s->vga.vram_ptr + s->cirrus_blt_dstaddr;
+ 
+     if (blit_is_unsafe(s, false, true)) {
+         return 0;
+@@ -708,7 +708,7 @@ static int cirrus_bitblt_solidfill(Cirru
+         return 0;
+     }
+     rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
+-    rop_func(s, s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
++    rop_func(s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
+              s->cirrus_blt_dstpitch,
+              s->cirrus_blt_width, s->cirrus_blt_height);
+     cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
+@@ -726,9 +726,8 @@ static int cirrus_bitblt_solidfill(Cirru
+ 
+ static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
+ {
+-    return cirrus_bitblt_common_patterncopy(s,
+-					    s->vga.vram_ptr + ((s->cirrus_blt_srcaddr & ~7) &
+-                                            s->cirrus_addr_mask));
++    return cirrus_bitblt_common_patterncopy(s, s->vga.vram_ptr +
++                                            (s->cirrus_blt_srcaddr & ~7));
+ }
+ 
+ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
+@@ -777,10 +776,8 @@ static int cirrus_do_copy(CirrusVGAState
+         }
+     }
+ 
+-    (*s->cirrus_rop) (s, s->vga.vram_ptr +
+-		      (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
+-		      s->vga.vram_ptr +
+-		      (s->cirrus_blt_srcaddr & s->cirrus_addr_mask),
++    (*s->cirrus_rop) (s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
++                      s->vga.vram_ptr + s->cirrus_blt_srcaddr,
+ 		      s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
+ 		      s->cirrus_blt_width, s->cirrus_blt_height);
+ 
+@@ -830,8 +827,7 @@ static void cirrus_bitblt_cputovideo_nex
+         } else {
+             /* at least one scan line */
+             do {
+-                (*s->cirrus_rop)(s, s->vga.vram_ptr +
+-                                 (s->cirrus_blt_dstaddr & s->cirrus_addr_mask),
++                (*s->cirrus_rop)(s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
+                                   s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
+                 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
+                                          s->cirrus_blt_width, 1);
+@@ -958,6 +954,9 @@ static void cirrus_bitblt_start(CirrusVG
+     s->cirrus_blt_modeext = s->vga.gr[0x33];
+     blt_rop = s->vga.gr[0x32];
+ 
++    s->cirrus_blt_dstaddr &= s->cirrus_addr_mask;
++    s->cirrus_blt_srcaddr &= s->cirrus_addr_mask;
++
+ #ifdef DEBUG_BITBLT
+     printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spitch=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n",
+            blt_rop,
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-7980-4.patch qemu-2.1+dfsg/debian/patches/CVE-2017-7980-4.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-7980-4.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-7980-4.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,104 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.34
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+
+From 95280c31cda79bb1d0968afc7b19a220b3a9d986 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Thu, 9 Feb 2017 14:02:20 +0100
+Subject: [PATCH] cirrus: fix patterncopy checks
+
+The blit_region_is_unsafe checks don't work correctly for the
+patterncopy source.  It's a fixed-sized region, which doesn't
+depend on cirrus_blt_{width,height}.  So go do the check in
+cirrus_bitblt_common_patterncopy instead, then tell blit_is_unsafe that
+it doesn't need to verify the source.  Also handle the case where we
+blit from cirrus_bitbuf correctly.
+
+This patch replaces 5858dd1801883309bdd208d72ddb81c4e9fee30c.
+
+Security impact:  I think for the most part error on the safe side this
+time, refusing blits which should have been allowed.
+
+Only exception is placing the blit source at the end of the video ram,
+so cirrus_blt_srcaddr + 256 goes beyond the end of video memory.  But
+even in that case I'm not fully sure this actually allows read access to
+host memory.  To trick the commit 5858dd18 security checks one has to
+pick very small cirrus_blt_{width,height} values, which in turn implies
+only a fraction of the blit source will actually be used.
+
+Cc: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Reviewed-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Reviewed-by: Laurent Vivier <lvivier@redhat.com>
+Message-id: 1486645341-5010-1-git-send-email-kraxel@redhat.com
+---
+ hw/display/cirrus_vga.c | 36 ++++++++++++++++++++++++++++++------
+ 1 file changed, 30 insertions(+), 6 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/display/cirrus_vga.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/display/cirrus_vga.c	2017-05-10 15:48:06.709971937 -0400
++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga.c	2017-05-10 15:48:06.709971937 -0400
+@@ -678,14 +678,39 @@ static void cirrus_invalidate_region(Cir
+     }
+ }
+ 
+-static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s,
+-					    const uint8_t * src)
++static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videosrc)
+ {
++    uint32_t patternsize;
+     uint8_t *dst;
++    uint8_t *src;
+ 
+     dst = s->vga.vram_ptr + s->cirrus_blt_dstaddr;
+ 
+-    if (blit_is_unsafe(s, false, true)) {
++    if (videosrc) {
++        switch (s->vga.get_bpp(&s->vga)) {
++        case 8:
++            patternsize = 64;
++            break;
++        case 15:
++        case 16:
++            patternsize = 128;
++            break;
++        case 24:
++        case 32:
++        default:
++            patternsize = 256;
++            break;
++        }
++        s->cirrus_blt_srcaddr &= ~(patternsize - 1);
++        if (s->cirrus_blt_srcaddr + patternsize > s->vga.vram_size) {
++            return 0;
++        }
++        src = s->vga.vram_ptr + s->cirrus_blt_srcaddr;
++    } else {
++        src = s->cirrus_bltbuf;
++    }
++
++    if (blit_is_unsafe(s, true, true)) {
+         return 0;
+     }
+ 
+@@ -726,8 +751,7 @@ static int cirrus_bitblt_solidfill(Cirru
+ 
+ static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
+ {
+-    return cirrus_bitblt_common_patterncopy(s, s->vga.vram_ptr +
+-                                            (s->cirrus_blt_srcaddr & ~7));
++    return cirrus_bitblt_common_patterncopy(s, true);
+ }
+ 
+ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
+@@ -820,7 +844,7 @@ static void cirrus_bitblt_cputovideo_nex
+ 
+     if (s->cirrus_srccounter > 0) {
+         if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
+-            cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf);
++            cirrus_bitblt_common_patterncopy(s, false);
+         the_end:
+             s->cirrus_srccounter = 0;
+             cirrus_bitblt_reset(s);
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-7980-5.patch qemu-2.1+dfsg/debian/patches/CVE-2017-7980-5.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-7980-5.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-7980-5.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,103 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.34
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+
+From 12e97ec39931e5321645fd483ab761319d48bf16 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Thu, 9 Feb 2017 14:02:21 +0100
+Subject: [PATCH] Revert "cirrus: allow zero source pitch in pattern fill rops"
+
+This reverts commit 5858dd1801883309bdd208d72ddb81c4e9fee30c.
+
+Conflicts:
+	hw/display/cirrus_vga.c
+
+Cc: Wolfgang Bumiller <w.bumiller@proxmox.com>
+Cc: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Reviewed-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
+Reviewed-by: Laurent Vivier <lvivier@redhat.com>
+Message-id: 1486645341-5010-2-git-send-email-kraxel@redhat.com
+---
+ hw/display/cirrus_vga.c | 26 ++++++++------------------
+ 1 file changed, 8 insertions(+), 18 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/display/cirrus_vga.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/display/cirrus_vga.c	2017-05-10 15:48:14.878049916 -0400
++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga.c	2017-05-10 15:48:14.874049878 -0400
+@@ -267,6 +267,9 @@ static void cirrus_update_memory_access(
+ static bool blit_region_is_unsafe(struct CirrusVGAState *s,
+                                   int32_t pitch, int32_t addr)
+ {
++    if (!pitch) {
++        return true;
++    }
+     if (pitch < 0) {
+         int64_t min = addr
+             + ((int64_t)s->cirrus_blt_height - 1) * pitch
+@@ -285,11 +288,8 @@ static bool blit_region_is_unsafe(struct
+     return false;
+ }
+ 
+-static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only,
+-                           bool zero_src_pitch_ok)
++static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only)
+ {
+-    int32_t check_pitch;
+-
+     /* should be the case, see cirrus_bitblt_start */
+     assert(s->cirrus_blt_width > 0);
+     assert(s->cirrus_blt_height > 0);
+@@ -298,10 +298,6 @@ static bool blit_is_unsafe(struct Cirrus
+         return true;
+     }
+ 
+-    if (!s->cirrus_blt_dstpitch) {
+-        return true;
+-    }
+-
+     if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch,
+                               s->cirrus_blt_dstaddr)) {
+         return true;
+@@ -309,13 +305,7 @@ static bool blit_is_unsafe(struct Cirrus
+     if (dst_only) {
+         return false;
+     }
+-
+-    check_pitch = s->cirrus_blt_srcpitch;
+-    if (!zero_src_pitch_ok && !check_pitch) {
+-        check_pitch = s->cirrus_blt_width;
+-    }
+-
+-    if (blit_region_is_unsafe(s, check_pitch,
++    if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch,
+                               s->cirrus_blt_srcaddr)) {
+         return true;
+     }
+@@ -710,7 +700,7 @@ static int cirrus_bitblt_common_patternc
+         src = s->cirrus_bltbuf;
+     }
+ 
+-    if (blit_is_unsafe(s, true, true)) {
++    if (blit_is_unsafe(s, true)) {
+         return 0;
+     }
+ 
+@@ -729,7 +719,7 @@ static int cirrus_bitblt_solidfill(Cirru
+ {
+     cirrus_fill_t rop_func;
+ 
+-    if (blit_is_unsafe(s, true, true)) {
++    if (blit_is_unsafe(s, true)) {
+         return 0;
+     }
+     rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
+@@ -823,7 +813,7 @@ static int cirrus_do_copy(CirrusVGAState
+ 
+ static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s)
+ {
+-    if (blit_is_unsafe(s, false, false))
++    if (blit_is_unsafe(s, false))
+         return 0;
+ 
+     return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr,
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-7980-6.patch qemu-2.1+dfsg/debian/patches/CVE-2017-7980-6.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-7980-6.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-7980-6.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,619 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.34
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+
+From 026aeffcb4752054830ba203020ed6eb05bcaba8 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Wed, 15 Mar 2017 11:47:52 +0100
+Subject: [PATCH] cirrus: stop passing around dst pointers in the blitter
+
+Instead pass around the address (aka offset into vga memory).  Calculate
+the pointer in the rop_* functions, after applying the mask to the
+address, to make sure the address stays within the valid range.
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: 1489574872-8679-1-git-send-email-kraxel@redhat.com
+---
+ hw/display/cirrus_vga.c      |  20 +++---
+ hw/display/cirrus_vga_rop.h  | 161 +++++++++++++++++++++++++------------------
+ hw/display/cirrus_vga_rop2.h |  97 +++++++++++++-------------
+ 3 files changed, 153 insertions(+), 125 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/display/cirrus_vga.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/display/cirrus_vga.c	2017-05-10 15:48:20.602104562 -0400
++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga.c	2017-05-10 15:48:20.594104486 -0400
+@@ -174,11 +174,12 @@
+ 
+ struct CirrusVGAState;
+ typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
+-                                     uint8_t * dst, const uint8_t * src,
++                                     uint32_t dstaddr, const uint8_t *src,
+ 				     int dstpitch, int srcpitch,
+ 				     int bltwidth, int bltheight);
+ typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
+-                              uint8_t *dst, int dst_pitch, int width, int height);
++                              uint32_t dstaddr, int dst_pitch,
++                              int width, int height);
+ 
+ typedef struct CirrusVGAState {
+     VGACommonState vga;
+@@ -314,14 +315,14 @@ static bool blit_is_unsafe(struct Cirrus
+ }
+ 
+ static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
+-                                  uint8_t *dst,const uint8_t *src,
++                                  uint32_t dstaddr, const uint8_t *src,
+                                   int dstpitch,int srcpitch,
+                                   int bltwidth,int bltheight)
+ {
+ }
+ 
+ static void cirrus_bitblt_fill_nop(CirrusVGAState *s,
+-                                   uint8_t *dst,
++                                   uint32_t dstaddr,
+                                    int dstpitch, int bltwidth,int bltheight)
+ {
+ }
+@@ -671,11 +672,8 @@ static void cirrus_invalidate_region(Cir
+ static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videosrc)
+ {
+     uint32_t patternsize;
+-    uint8_t *dst;
+     uint8_t *src;
+ 
+-    dst = s->vga.vram_ptr + s->cirrus_blt_dstaddr;
+-
+     if (videosrc) {
+         switch (s->vga.get_bpp(&s->vga)) {
+         case 8:
+@@ -704,7 +702,7 @@ static int cirrus_bitblt_common_patternc
+         return 0;
+     }
+ 
+-    (*s->cirrus_rop) (s, dst, src,
++    (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr, src,
+                       s->cirrus_blt_dstpitch, 0,
+                       s->cirrus_blt_width, s->cirrus_blt_height);
+     cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
+@@ -723,7 +721,7 @@ static int cirrus_bitblt_solidfill(Cirru
+         return 0;
+     }
+     rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1];
+-    rop_func(s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
++    rop_func(s, s->cirrus_blt_dstaddr,
+              s->cirrus_blt_dstpitch,
+              s->cirrus_blt_width, s->cirrus_blt_height);
+     cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
+@@ -790,7 +788,7 @@ static int cirrus_do_copy(CirrusVGAState
+         }
+     }
+ 
+-    (*s->cirrus_rop) (s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
++    (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr,
+                       s->vga.vram_ptr + s->cirrus_blt_srcaddr,
+ 		      s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
+ 		      s->cirrus_blt_width, s->cirrus_blt_height);
+@@ -841,7 +839,7 @@ static void cirrus_bitblt_cputovideo_nex
+         } else {
+             /* at least one scan line */
+             do {
+-                (*s->cirrus_rop)(s, s->vga.vram_ptr + s->cirrus_blt_dstaddr,
++                (*s->cirrus_rop)(s, s->cirrus_blt_dstaddr,
+                                   s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
+                 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
+                                          s->cirrus_blt_width, 1);
+Index: qemu-2.0.0+dfsg/hw/display/cirrus_vga_rop.h
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/display/cirrus_vga_rop.h	2017-05-10 15:48:20.602104562 -0400
++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga_rop.h	2017-05-10 15:48:20.598104524 -0400
+@@ -22,31 +22,65 @@
+  * THE SOFTWARE.
+  */
+ 
+-static inline void glue(rop_8_,ROP_NAME)(uint8_t *dst, uint8_t src)
++static inline void glue(rop_8_, ROP_NAME)(CirrusVGAState *s,
++                                          uint32_t dstaddr, uint8_t src)
+ {
++    uint8_t *dst = &s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask];
+     *dst = ROP_FN(*dst, src);
+ }
+ 
+-static inline void glue(rop_16_,ROP_NAME)(uint16_t *dst, uint16_t src)
++static inline void glue(rop_tr_8_, ROP_NAME)(CirrusVGAState *s,
++                                             uint32_t dstaddr, uint8_t src,
++                                             uint8_t transp)
+ {
++    uint8_t *dst = &s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask];
++    uint8_t pixel = ROP_FN(*dst, src);
++    if (pixel != transp) {
++        *dst = pixel;
++    }
++}
++
++static inline void glue(rop_16_, ROP_NAME)(CirrusVGAState *s,
++                                           uint32_t dstaddr, uint16_t src)
++{
++    uint16_t *dst = (uint16_t *)
++        (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~1]);
+     *dst = ROP_FN(*dst, src);
+ }
+ 
+-static inline void glue(rop_32_,ROP_NAME)(uint32_t *dst, uint32_t src)
++static inline void glue(rop_tr_16_, ROP_NAME)(CirrusVGAState *s,
++                                              uint32_t dstaddr, uint16_t src,
++                                              uint16_t transp)
++{
++    uint16_t *dst = (uint16_t *)
++        (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~1]);
++    uint16_t pixel = ROP_FN(*dst, src);
++    if (pixel != transp) {
++        *dst = pixel;
++    }
++}
++
++static inline void glue(rop_32_, ROP_NAME)(CirrusVGAState *s,
++                                           uint32_t dstaddr, uint32_t src)
+ {
++    uint32_t *dst = (uint32_t *)
++        (&s->vga.vram_ptr[dstaddr & s->cirrus_addr_mask & ~3]);
+     *dst = ROP_FN(*dst, src);
+ }
+ 
+-#define ROP_OP(d, s) glue(rop_8_,ROP_NAME)(d, s)
+-#define ROP_OP_16(d, s) glue(rop_16_,ROP_NAME)(d, s)
+-#define ROP_OP_32(d, s) glue(rop_32_,ROP_NAME)(d, s)
++#define ROP_OP(st, d, s)           glue(rop_8_, ROP_NAME)(st, d, s)
++#define ROP_OP_TR(st, d, s, t)     glue(rop_tr_8_, ROP_NAME)(st, d, s, t)
++#define ROP_OP_16(st, d, s)        glue(rop_16_, ROP_NAME)(st, d, s)
++#define ROP_OP_TR_16(st, d, s, t)  glue(rop_tr_16_, ROP_NAME)(st, d, s, t)
++#define ROP_OP_32(st, d, s)        glue(rop_32_, ROP_NAME)(st, d, s)
+ #undef ROP_FN
+ 
+ static void
+ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
+-                             uint8_t *dst,const uint8_t *src,
+-                             int dstpitch,int srcpitch,
+-                             int bltwidth,int bltheight)
++                                       uint32_t dstaddr,
++                                       const uint8_t *src,
++                                       int dstpitch, int srcpitch,
++                                       int bltwidth, int bltheight)
+ {
+     int x,y;
+     dstpitch -= bltwidth;
+@@ -59,43 +93,47 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(C
+ 
+     for (y = 0; y < bltheight; y++) {
+         for (x = 0; x < bltwidth; x++) {
+-            ROP_OP(dst, *src);
+-            dst++;
++            ROP_OP(s, dstaddr, *src);
++            dstaddr++;
+             src++;
+         }
+-        dst += dstpitch;
++        dstaddr += dstpitch;
+         src += srcpitch;
+     }
+ }
+ 
+ static void
+ glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
+-                                        uint8_t *dst,const uint8_t *src,
+-                                        int dstpitch,int srcpitch,
+-                                        int bltwidth,int bltheight)
++                                        uint32_t dstaddr,
++                                        const uint8_t *src,
++                                        int dstpitch, int srcpitch,
++                                        int bltwidth, int bltheight)
+ {
+     int x,y;
+     dstpitch += bltwidth;
+     srcpitch += bltwidth;
+     for (y = 0; y < bltheight; y++) {
+         for (x = 0; x < bltwidth; x++) {
+-            ROP_OP(dst, *src);
+-            dst--;
++            ROP_OP(s, dstaddr, *src);
++            dstaddr--;
+             src--;
+         }
+-        dst += dstpitch;
++        dstaddr += dstpitch;
+         src += srcpitch;
+     }
+ }
+ 
+ static void
+ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
+-						       uint8_t *dst,const uint8_t *src,
+-						       int dstpitch,int srcpitch,
+-						       int bltwidth,int bltheight)
++                                                       uint32_t dstaddr,
++                                                       const uint8_t *src,
++                                                       int dstpitch,
++                                                       int srcpitch,
++                                                       int bltwidth,
++                                                       int bltheight)
+ {
+     int x,y;
+-    uint8_t p;
++    uint8_t transp = s->vga.gr[0x34];
+     dstpitch -= bltwidth;
+     srcpitch -= bltwidth;
+ 
+@@ -105,48 +143,50 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_,
+ 
+     for (y = 0; y < bltheight; y++) {
+         for (x = 0; x < bltwidth; x++) {
+-	    p = *dst;
+-            ROP_OP(&p, *src);
+-	    if (p != s->vga.gr[0x34]) *dst = p;
+-            dst++;
++            ROP_OP_TR(s, dstaddr, *src, transp);
++            dstaddr++;
+             src++;
+         }
+-        dst += dstpitch;
++        dstaddr += dstpitch;
+         src += srcpitch;
+     }
+ }
+ 
+ static void
+ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
+-							uint8_t *dst,const uint8_t *src,
+-							int dstpitch,int srcpitch,
+-							int bltwidth,int bltheight)
++                                                        uint32_t dstaddr,
++                                                        const uint8_t *src,
++                                                        int dstpitch,
++                                                        int srcpitch,
++                                                        int bltwidth,
++                                                        int bltheight)
+ {
+     int x,y;
+-    uint8_t p;
++    uint8_t transp = s->vga.gr[0x34];
+     dstpitch += bltwidth;
+     srcpitch += bltwidth;
+     for (y = 0; y < bltheight; y++) {
+         for (x = 0; x < bltwidth; x++) {
+-	    p = *dst;
+-            ROP_OP(&p, *src);
+-	    if (p != s->vga.gr[0x34]) *dst = p;
+-            dst--;
++            ROP_OP_TR(s, dstaddr, *src, transp);
++            dstaddr--;
+             src--;
+         }
+-        dst += dstpitch;
++        dstaddr += dstpitch;
+         src += srcpitch;
+     }
+ }
+ 
+ static void
+ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
+-							uint8_t *dst,const uint8_t *src,
+-							int dstpitch,int srcpitch,
+-							int bltwidth,int bltheight)
++                                                        uint32_t dstaddr,
++                                                        const uint8_t *src,
++                                                        int dstpitch,
++                                                        int srcpitch,
++                                                        int bltwidth,
++                                                        int bltheight)
+ {
+     int x,y;
+-    uint8_t p1, p2;
++    uint16_t transp = s->vga.gr[0x34] | (uint16_t)s->vga.gr[0x35] << 8;
+     dstpitch -= bltwidth;
+     srcpitch -= bltwidth;
+ 
+@@ -156,46 +196,35 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_,
+ 
+     for (y = 0; y < bltheight; y++) {
+         for (x = 0; x < bltwidth; x+=2) {
+-	    p1 = *dst;
+-	    p2 = *(dst+1);
+-            ROP_OP(&p1, *src);
+-            ROP_OP(&p2, *(src + 1));
+-	    if ((p1 != s->vga.gr[0x34]) || (p2 != s->vga.gr[0x35])) {
+-		*dst = p1;
+-		*(dst+1) = p2;
+-	    }
+-            dst+=2;
+-            src+=2;
++            ROP_OP_TR_16(s, dstaddr, *(uint16_t *)src, transp);
++            dstaddr += 2;
++            src += 2;
+         }
+-        dst += dstpitch;
++        dstaddr += dstpitch;
+         src += srcpitch;
+     }
+ }
+ 
+ static void
+ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
+-							 uint8_t *dst,const uint8_t *src,
+-							 int dstpitch,int srcpitch,
+-							 int bltwidth,int bltheight)
++                                                         uint32_t dstaddr,
++                                                         const uint8_t *src,
++                                                         int dstpitch,
++                                                         int srcpitch,
++                                                         int bltwidth,
++                                                         int bltheight)
+ {
+     int x,y;
+-    uint8_t p1, p2;
++    uint16_t transp = s->vga.gr[0x34] | (uint16_t)s->vga.gr[0x35] << 8;
+     dstpitch += bltwidth;
+     srcpitch += bltwidth;
+     for (y = 0; y < bltheight; y++) {
+         for (x = 0; x < bltwidth; x+=2) {
+-	    p1 = *(dst-1);
+-	    p2 = *dst;
+-            ROP_OP(&p1, *(src - 1));
+-            ROP_OP(&p2, *src);
+-	    if ((p1 != s->vga.gr[0x34]) || (p2 != s->vga.gr[0x35])) {
+-		*(dst-1) = p1;
+-		*dst = p2;
+-	    }
+-            dst-=2;
+-            src-=2;
++            ROP_OP_TR_16(s, dstaddr, *(uint16_t *)src, transp);
++            dstaddr -= 2;
++            src -= 2;
+         }
+-        dst += dstpitch;
++        dstaddr += dstpitch;
+         src += srcpitch;
+     }
+ }
+Index: qemu-2.0.0+dfsg/hw/display/cirrus_vga_rop2.h
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/display/cirrus_vga_rop2.h	2017-05-10 15:48:20.602104562 -0400
++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga_rop2.h	2017-05-10 15:48:20.598104524 -0400
+@@ -23,27 +23,29 @@
+  */
+ 
+ #if DEPTH == 8
+-#define PUTPIXEL()    ROP_OP(&d[0], col)
++#define PUTPIXEL(s, a, c)    ROP_OP(s, a, c)
+ #elif DEPTH == 16
+-#define PUTPIXEL()    ROP_OP_16((uint16_t *)&d[0], col)
++#define PUTPIXEL(s, a, c)    ROP_OP_16(s, a, c)
+ #elif DEPTH == 24
+-#define PUTPIXEL()    ROP_OP(&d[0], col);        \
+-                      ROP_OP(&d[1], (col >> 8)); \
+-                      ROP_OP(&d[2], (col >> 16))
++#define PUTPIXEL(s, a, c)    do {          \
++        ROP_OP(s, a,     c);               \
++        ROP_OP(s, a + 1, (col >> 8));      \
++        ROP_OP(s, a + 2, (col >> 16));     \
++    } while (0)
+ #elif DEPTH == 32
+-#define PUTPIXEL()    ROP_OP_32(((uint32_t *)&d[0]), col)
++#define PUTPIXEL(s, a, c)    ROP_OP_32(s, a, c)
+ #else
+ #error unsupported DEPTH
+ #endif
+ 
+ static void
+ glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
+-     (CirrusVGAState * s, uint8_t * dst,
+-      const uint8_t * src,
++     (CirrusVGAState *s, uint32_t dstaddr,
++      const uint8_t *src,
+       int dstpitch, int srcpitch,
+       int bltwidth, int bltheight)
+ {
+-    uint8_t *d;
++    uint32_t addr;
+     int x, y, pattern_y, pattern_pitch, pattern_x;
+     unsigned int col;
+     const uint8_t *src1;
+@@ -63,7 +65,7 @@ glue(glue(glue(cirrus_patternfill_, ROP_
+     pattern_y = s->cirrus_blt_srcaddr & 7;
+     for(y = 0; y < bltheight; y++) {
+         pattern_x = skipleft;
+-        d = dst + skipleft;
++        addr = dstaddr + skipleft;
+         src1 = src + pattern_y * pattern_pitch;
+         for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) {
+ #if DEPTH == 8
+@@ -82,23 +84,23 @@ glue(glue(glue(cirrus_patternfill_, ROP_
+             col = ((uint32_t *)(src1 + pattern_x))[0];
+             pattern_x = (pattern_x + 4) & 31;
+ #endif
+-            PUTPIXEL();
+-            d += (DEPTH / 8);
++            PUTPIXEL(s, addr, col);
++            addr += (DEPTH / 8);
+         }
+         pattern_y = (pattern_y + 1) & 7;
+-        dst += dstpitch;
++        dstaddr += dstpitch;
+     }
+ }
+ 
+ /* NOTE: srcpitch is ignored */
+ static void
+ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
+-     (CirrusVGAState * s, uint8_t * dst,
+-      const uint8_t * src,
++     (CirrusVGAState *s, uint32_t dstaddr,
++      const uint8_t *src,
+       int dstpitch, int srcpitch,
+       int bltwidth, int bltheight)
+ {
+-    uint8_t *d;
++    uint32_t addr;
+     int x, y;
+     unsigned bits, bits_xor;
+     unsigned int col;
+@@ -123,7 +125,7 @@ glue(glue(glue(cirrus_colorexpand_transp
+     for(y = 0; y < bltheight; y++) {
+         bitmask = 0x80 >> srcskipleft;
+         bits = *src++ ^ bits_xor;
+-        d = dst + dstskipleft;
++        addr = dstaddr + dstskipleft;
+         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
+             if ((bitmask & 0xff) == 0) {
+                 bitmask = 0x80;
+@@ -131,24 +133,24 @@ glue(glue(glue(cirrus_colorexpand_transp
+             }
+             index = (bits & bitmask);
+             if (index) {
+-                PUTPIXEL();
++                PUTPIXEL(s, addr, col);
+             }
+-            d += (DEPTH / 8);
++            addr += (DEPTH / 8);
+             bitmask >>= 1;
+         }
+-        dst += dstpitch;
++        dstaddr += dstpitch;
+     }
+ }
+ 
+ static void
+ glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
+-     (CirrusVGAState * s, uint8_t * dst,
+-      const uint8_t * src,
++     (CirrusVGAState *s, uint32_t dstaddr,
++      const uint8_t *src,
+       int dstpitch, int srcpitch,
+       int bltwidth, int bltheight)
+ {
+     uint32_t colors[2];
+-    uint8_t *d;
++    uint32_t addr;
+     int x, y;
+     unsigned bits;
+     unsigned int col;
+@@ -161,29 +163,29 @@ glue(glue(glue(cirrus_colorexpand_, ROP_
+     for(y = 0; y < bltheight; y++) {
+         bitmask = 0x80 >> srcskipleft;
+         bits = *src++;
+-        d = dst + dstskipleft;
++        addr = dstaddr + dstskipleft;
+         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
+             if ((bitmask & 0xff) == 0) {
+                 bitmask = 0x80;
+                 bits = *src++;
+             }
+             col = colors[!!(bits & bitmask)];
+-            PUTPIXEL();
+-            d += (DEPTH / 8);
++            PUTPIXEL(s, addr, col);
++            addr += (DEPTH / 8);
+             bitmask >>= 1;
+         }
+-        dst += dstpitch;
++        dstaddr += dstpitch;
+     }
+ }
+ 
+ static void
+ glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
+-     (CirrusVGAState * s, uint8_t * dst,
+-      const uint8_t * src,
++     (CirrusVGAState *s, uint32_t dstaddr,
++      const uint8_t *src,
+       int dstpitch, int srcpitch,
+       int bltwidth, int bltheight)
+ {
+-    uint8_t *d;
++    uint32_t addr;
+     int x, y, bitpos, pattern_y;
+     unsigned int bits, bits_xor;
+     unsigned int col;
+@@ -207,28 +209,28 @@ glue(glue(glue(cirrus_colorexpand_patter
+     for(y = 0; y < bltheight; y++) {
+         bits = src[pattern_y] ^ bits_xor;
+         bitpos = 7 - srcskipleft;
+-        d = dst + dstskipleft;
++        addr = dstaddr + dstskipleft;
+         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
+             if ((bits >> bitpos) & 1) {
+-                PUTPIXEL();
++                PUTPIXEL(s, addr, col);
+             }
+-            d += (DEPTH / 8);
++            addr += (DEPTH / 8);
+             bitpos = (bitpos - 1) & 7;
+         }
+         pattern_y = (pattern_y + 1) & 7;
+-        dst += dstpitch;
++        dstaddr += dstpitch;
+     }
+ }
+ 
+ static void
+ glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
+-     (CirrusVGAState * s, uint8_t * dst,
+-      const uint8_t * src,
++     (CirrusVGAState *s, uint32_t dstaddr,
++      const uint8_t *src,
+       int dstpitch, int srcpitch,
+       int bltwidth, int bltheight)
+ {
+     uint32_t colors[2];
+-    uint8_t *d;
++    uint32_t addr;
+     int x, y, bitpos, pattern_y;
+     unsigned int bits;
+     unsigned int col;
+@@ -242,38 +244,37 @@ glue(glue(glue(cirrus_colorexpand_patter
+     for(y = 0; y < bltheight; y++) {
+         bits = src[pattern_y];
+         bitpos = 7 - srcskipleft;
+-        d = dst + dstskipleft;
++        addr = dstaddr + dstskipleft;
+         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
+             col = colors[(bits >> bitpos) & 1];
+-            PUTPIXEL();
+-            d += (DEPTH / 8);
++            PUTPIXEL(s, addr, col);
++            addr += (DEPTH / 8);
+             bitpos = (bitpos - 1) & 7;
+         }
+         pattern_y = (pattern_y + 1) & 7;
+-        dst += dstpitch;
++        dstaddr += dstpitch;
+     }
+ }
+ 
+ static void
+ glue(glue(glue(cirrus_fill_, ROP_NAME), _),DEPTH)
+      (CirrusVGAState *s,
+-      uint8_t *dst, int dst_pitch,
++      uint32_t dstaddr, int dst_pitch,
+       int width, int height)
+ {
+-    uint8_t *d, *d1;
++    uint32_t addr;
+     uint32_t col;
+     int x, y;
+ 
+     col = s->cirrus_blt_fgcol;
+ 
+-    d1 = dst;
+     for(y = 0; y < height; y++) {
+-        d = d1;
++        addr = dstaddr;
+         for(x = 0; x < width; x += (DEPTH / 8)) {
+-            PUTPIXEL();
+-            d += (DEPTH / 8);
++            PUTPIXEL(s, addr, col);
++            addr += (DEPTH / 8);
+         }
+-        d1 += dst_pitch;
++        dstaddr += dst_pitch;
+     }
+ }
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-7980-7.patch qemu-2.1+dfsg/debian/patches/CVE-2017-7980-7.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-7980-7.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-7980-7.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,444 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.34
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+
+From ffaf857778286ca54e3804432a2369a279e73aa7 Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Wed, 15 Mar 2017 14:28:07 +0100
+Subject: [PATCH] cirrus: stop passing around src pointers in the blitter
+
+Does basically the same as "cirrus: stop passing around dst pointers in
+the blitter", just for the src pointer instead of the dst pointer.
+
+For the src we have to care about cputovideo blits though and fetch the
+data from s->cirrus_bltbuf instead of vga memory.  The cirrus_src*()
+helper functions handle that.
+
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+Message-id: 1489584487-3489-1-git-send-email-kraxel@redhat.com
+---
+ hw/display/cirrus_vga.c      | 61 +++++++++++++++++++++++++++++++++++---------
+ hw/display/cirrus_vga_rop.h  | 48 +++++++++++++++++-----------------
+ hw/display/cirrus_vga_rop2.h | 38 ++++++++++++++-------------
+ 3 files changed, 93 insertions(+), 54 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/display/cirrus_vga.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/display/cirrus_vga.c	2017-05-10 15:48:25.734153557 -0400
++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga.c	2017-05-10 15:48:25.730153519 -0400
+@@ -174,7 +174,7 @@
+ 
+ struct CirrusVGAState;
+ typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s,
+-                                     uint32_t dstaddr, const uint8_t *src,
++                                     uint32_t dstaddr, uint32_t srcaddr,
+ 				     int dstpitch, int srcpitch,
+ 				     int bltwidth, int bltheight);
+ typedef void (*cirrus_fill_t)(struct CirrusVGAState *s,
+@@ -315,7 +315,7 @@ static bool blit_is_unsafe(struct Cirrus
+ }
+ 
+ static void cirrus_bitblt_rop_nop(CirrusVGAState *s,
+-                                  uint32_t dstaddr, const uint8_t *src,
++                                  uint32_t dstaddr, uint32_t srcaddr,
+                                   int dstpitch,int srcpitch,
+                                   int bltwidth,int bltheight)
+ {
+@@ -327,6 +327,45 @@ static void cirrus_bitblt_fill_nop(Cirru
+ {
+ }
+ 
++static inline uint8_t cirrus_src(CirrusVGAState *s, uint32_t srcaddr)
++{
++    if (s->cirrus_srccounter) {
++        /* cputovideo */
++        return s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1)];
++    } else {
++        /* videotovideo */
++        return s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask];
++    }
++}
++
++static inline uint16_t cirrus_src16(CirrusVGAState *s, uint32_t srcaddr)
++{
++    uint16_t *src;
++
++    if (s->cirrus_srccounter) {
++        /* cputovideo */
++        src = (void *)&s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1) & ~1];
++    } else {
++        /* videotovideo */
++        src = (void *)&s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask & ~1];
++    }
++    return *src;
++}
++
++static inline uint32_t cirrus_src32(CirrusVGAState *s, uint32_t srcaddr)
++{
++    uint32_t *src;
++
++    if (s->cirrus_srccounter) {
++        /* cputovideo */
++        src = (void *)&s->cirrus_bltbuf[srcaddr & (CIRRUS_BLTBUFSIZE - 1) & ~3];
++    } else {
++        /* videotovideo */
++        src = (void *)&s->vga.vram_ptr[srcaddr & s->cirrus_addr_mask & ~3];
++    }
++    return *src;
++}
++
+ #define ROP_NAME 0
+ #define ROP_FN(d, s) 0
+ #include "cirrus_vga_rop.h"
+@@ -669,10 +708,10 @@ static void cirrus_invalidate_region(Cir
+     }
+ }
+ 
+-static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videosrc)
++static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s)
+ {
+     uint32_t patternsize;
+-    uint8_t *src;
++    bool videosrc = !s->cirrus_srccounter;
+ 
+     if (videosrc) {
+         switch (s->vga.get_bpp(&s->vga)) {
+@@ -693,16 +732,14 @@ static int cirrus_bitblt_common_patternc
+         if (s->cirrus_blt_srcaddr + patternsize > s->vga.vram_size) {
+             return 0;
+         }
+-        src = s->vga.vram_ptr + s->cirrus_blt_srcaddr;
+-    } else {
+-        src = s->cirrus_bltbuf;
+     }
+ 
+     if (blit_is_unsafe(s, true)) {
+         return 0;
+     }
+ 
+-    (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr, src,
++    (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr,
++                      videosrc ? s->cirrus_blt_srcaddr : 0,
+                       s->cirrus_blt_dstpitch, 0,
+                       s->cirrus_blt_width, s->cirrus_blt_height);
+     cirrus_invalidate_region(s, s->cirrus_blt_dstaddr,
+@@ -739,7 +776,7 @@ static int cirrus_bitblt_solidfill(Cirru
+ 
+ static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s)
+ {
+-    return cirrus_bitblt_common_patterncopy(s, true);
++    return cirrus_bitblt_common_patterncopy(s);
+ }
+ 
+ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h)
+@@ -789,7 +826,7 @@ static int cirrus_do_copy(CirrusVGAState
+     }
+ 
+     (*s->cirrus_rop) (s, s->cirrus_blt_dstaddr,
+-                      s->vga.vram_ptr + s->cirrus_blt_srcaddr,
++                      s->cirrus_blt_srcaddr,
+ 		      s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch,
+ 		      s->cirrus_blt_width, s->cirrus_blt_height);
+ 
+@@ -832,7 +869,7 @@ static void cirrus_bitblt_cputovideo_nex
+ 
+     if (s->cirrus_srccounter > 0) {
+         if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) {
+-            cirrus_bitblt_common_patterncopy(s, false);
++            cirrus_bitblt_common_patterncopy(s);
+         the_end:
+             s->cirrus_srccounter = 0;
+             cirrus_bitblt_reset(s);
+@@ -840,7 +877,7 @@ static void cirrus_bitblt_cputovideo_nex
+             /* at least one scan line */
+             do {
+                 (*s->cirrus_rop)(s, s->cirrus_blt_dstaddr,
+-                                  s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1);
++                                 0, 0, 0, s->cirrus_blt_width, 1);
+                 cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0,
+                                          s->cirrus_blt_width, 1);
+                 s->cirrus_blt_dstaddr += s->cirrus_blt_dstpitch;
+Index: qemu-2.0.0+dfsg/hw/display/cirrus_vga_rop.h
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/display/cirrus_vga_rop.h	2017-05-10 15:48:25.734153557 -0400
++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga_rop.h	2017-05-10 15:48:25.734153557 -0400
+@@ -78,7 +78,7 @@ static inline void glue(rop_32_, ROP_NAM
+ static void
+ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(CirrusVGAState *s,
+                                        uint32_t dstaddr,
+-                                       const uint8_t *src,
++                                       uint32_t srcaddr,
+                                        int dstpitch, int srcpitch,
+                                        int bltwidth, int bltheight)
+ {
+@@ -93,19 +93,19 @@ glue(cirrus_bitblt_rop_fwd_, ROP_NAME)(C
+ 
+     for (y = 0; y < bltheight; y++) {
+         for (x = 0; x < bltwidth; x++) {
+-            ROP_OP(s, dstaddr, *src);
++            ROP_OP(s, dstaddr, cirrus_src(s, srcaddr));
+             dstaddr++;
+-            src++;
++            srcaddr++;
+         }
+         dstaddr += dstpitch;
+-        src += srcpitch;
++        srcaddr += srcpitch;
+     }
+ }
+ 
+ static void
+ glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(CirrusVGAState *s,
+                                         uint32_t dstaddr,
+-                                        const uint8_t *src,
++                                        uint32_t srcaddr,
+                                         int dstpitch, int srcpitch,
+                                         int bltwidth, int bltheight)
+ {
+@@ -114,19 +114,19 @@ glue(cirrus_bitblt_rop_bkwd_, ROP_NAME)(
+     srcpitch += bltwidth;
+     for (y = 0; y < bltheight; y++) {
+         for (x = 0; x < bltwidth; x++) {
+-            ROP_OP(s, dstaddr, *src);
++            ROP_OP(s, dstaddr, cirrus_src(s, srcaddr));
+             dstaddr--;
+-            src--;
++            srcaddr--;
+         }
+         dstaddr += dstpitch;
+-        src += srcpitch;
++        srcaddr += srcpitch;
+     }
+ }
+ 
+ static void
+ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
+                                                        uint32_t dstaddr,
+-                                                       const uint8_t *src,
++                                                       uint32_t srcaddr,
+                                                        int dstpitch,
+                                                        int srcpitch,
+                                                        int bltwidth,
+@@ -143,19 +143,19 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_,
+ 
+     for (y = 0; y < bltheight; y++) {
+         for (x = 0; x < bltwidth; x++) {
+-            ROP_OP_TR(s, dstaddr, *src, transp);
++            ROP_OP_TR(s, dstaddr, cirrus_src(s, srcaddr), transp);
+             dstaddr++;
+-            src++;
++            srcaddr++;
+         }
+         dstaddr += dstpitch;
+-        src += srcpitch;
++        srcaddr += srcpitch;
+     }
+ }
+ 
+ static void
+ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_8)(CirrusVGAState *s,
+                                                         uint32_t dstaddr,
+-                                                        const uint8_t *src,
++                                                        uint32_t srcaddr,
+                                                         int dstpitch,
+                                                         int srcpitch,
+                                                         int bltwidth,
+@@ -167,19 +167,19 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_
+     srcpitch += bltwidth;
+     for (y = 0; y < bltheight; y++) {
+         for (x = 0; x < bltwidth; x++) {
+-            ROP_OP_TR(s, dstaddr, *src, transp);
++            ROP_OP_TR(s, dstaddr, cirrus_src(s, srcaddr), transp);
+             dstaddr--;
+-            src--;
++            srcaddr--;
+         }
+         dstaddr += dstpitch;
+-        src += srcpitch;
++        srcaddr += srcpitch;
+     }
+ }
+ 
+ static void
+ glue(glue(cirrus_bitblt_rop_fwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
+                                                         uint32_t dstaddr,
+-                                                        const uint8_t *src,
++                                                        uint32_t srcaddr,
+                                                         int dstpitch,
+                                                         int srcpitch,
+                                                         int bltwidth,
+@@ -196,19 +196,19 @@ glue(glue(cirrus_bitblt_rop_fwd_transp_,
+ 
+     for (y = 0; y < bltheight; y++) {
+         for (x = 0; x < bltwidth; x+=2) {
+-            ROP_OP_TR_16(s, dstaddr, *(uint16_t *)src, transp);
++            ROP_OP_TR_16(s, dstaddr, cirrus_src16(s, srcaddr), transp);
+             dstaddr += 2;
+-            src += 2;
++            srcaddr += 2;
+         }
+         dstaddr += dstpitch;
+-        src += srcpitch;
++        srcaddr += srcpitch;
+     }
+ }
+ 
+ static void
+ glue(glue(cirrus_bitblt_rop_bkwd_transp_, ROP_NAME),_16)(CirrusVGAState *s,
+                                                          uint32_t dstaddr,
+-                                                         const uint8_t *src,
++                                                         uint32_t srcaddr,
+                                                          int dstpitch,
+                                                          int srcpitch,
+                                                          int bltwidth,
+@@ -220,12 +220,12 @@ glue(glue(cirrus_bitblt_rop_bkwd_transp_
+     srcpitch += bltwidth;
+     for (y = 0; y < bltheight; y++) {
+         for (x = 0; x < bltwidth; x+=2) {
+-            ROP_OP_TR_16(s, dstaddr, *(uint16_t *)src, transp);
++            ROP_OP_TR_16(s, dstaddr, cirrus_src16(s, srcaddr), transp);
+             dstaddr -= 2;
+-            src -= 2;
++            srcaddr -= 2;
+         }
+         dstaddr += dstpitch;
+-        src += srcpitch;
++        srcaddr += srcpitch;
+     }
+ }
+ 
+Index: qemu-2.0.0+dfsg/hw/display/cirrus_vga_rop2.h
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/display/cirrus_vga_rop2.h	2017-05-10 15:48:25.734153557 -0400
++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga_rop2.h	2017-05-10 15:48:25.734153557 -0400
+@@ -41,14 +41,14 @@
+ static void
+ glue(glue(glue(cirrus_patternfill_, ROP_NAME), _),DEPTH)
+      (CirrusVGAState *s, uint32_t dstaddr,
+-      const uint8_t *src,
++      uint32_t srcaddr,
+       int dstpitch, int srcpitch,
+       int bltwidth, int bltheight)
+ {
+     uint32_t addr;
+     int x, y, pattern_y, pattern_pitch, pattern_x;
+     unsigned int col;
+-    const uint8_t *src1;
++    uint32_t src1addr;
+ #if DEPTH == 24
+     int skipleft = s->vga.gr[0x2f] & 0x1f;
+ #else
+@@ -66,22 +66,24 @@ glue(glue(glue(cirrus_patternfill_, ROP_
+     for(y = 0; y < bltheight; y++) {
+         pattern_x = skipleft;
+         addr = dstaddr + skipleft;
+-        src1 = src + pattern_y * pattern_pitch;
++        src1addr = srcaddr + pattern_y * pattern_pitch;
+         for (x = skipleft; x < bltwidth; x += (DEPTH / 8)) {
+ #if DEPTH == 8
+-            col = src1[pattern_x];
++            col = cirrus_src(s, src1addr + pattern_x);
+             pattern_x = (pattern_x + 1) & 7;
+ #elif DEPTH == 16
+-            col = ((uint16_t *)(src1 + pattern_x))[0];
++            col = cirrus_src16(s, src1addr + pattern_x);
+             pattern_x = (pattern_x + 2) & 15;
+ #elif DEPTH == 24
+             {
+-                const uint8_t *src2 = src1 + pattern_x * 3;
+-                col = src2[0] | (src2[1] << 8) | (src2[2] << 16);
++                uint32_t src2addr = src1addr + pattern_x * 3;
++                col = cirrus_src(s, src2addr) |
++                    (cirrus_src(s, src2addr + 1) << 8) |
++                    (cirrus_src(s, src2addr + 2) << 16);
+                 pattern_x = (pattern_x + 1) & 7;
+             }
+ #else
+-            col = ((uint32_t *)(src1 + pattern_x))[0];
++            col = cirrus_src32(s, src1addr + pattern_x);
+             pattern_x = (pattern_x + 4) & 31;
+ #endif
+             PUTPIXEL(s, addr, col);
+@@ -96,7 +98,7 @@ glue(glue(glue(cirrus_patternfill_, ROP_
+ static void
+ glue(glue(glue(cirrus_colorexpand_transp_, ROP_NAME), _),DEPTH)
+      (CirrusVGAState *s, uint32_t dstaddr,
+-      const uint8_t *src,
++      uint32_t srcaddr,
+       int dstpitch, int srcpitch,
+       int bltwidth, int bltheight)
+ {
+@@ -124,12 +126,12 @@ glue(glue(glue(cirrus_colorexpand_transp
+ 
+     for(y = 0; y < bltheight; y++) {
+         bitmask = 0x80 >> srcskipleft;
+-        bits = *src++ ^ bits_xor;
++        bits = cirrus_src(s, srcaddr++) ^ bits_xor;
+         addr = dstaddr + dstskipleft;
+         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
+             if ((bitmask & 0xff) == 0) {
+                 bitmask = 0x80;
+-                bits = *src++ ^ bits_xor;
++                bits = cirrus_src(s, srcaddr++) ^ bits_xor;
+             }
+             index = (bits & bitmask);
+             if (index) {
+@@ -145,7 +147,7 @@ glue(glue(glue(cirrus_colorexpand_transp
+ static void
+ glue(glue(glue(cirrus_colorexpand_, ROP_NAME), _),DEPTH)
+      (CirrusVGAState *s, uint32_t dstaddr,
+-      const uint8_t *src,
++      uint32_t srcaddr,
+       int dstpitch, int srcpitch,
+       int bltwidth, int bltheight)
+ {
+@@ -162,12 +164,12 @@ glue(glue(glue(cirrus_colorexpand_, ROP_
+     colors[1] = s->cirrus_blt_fgcol;
+     for(y = 0; y < bltheight; y++) {
+         bitmask = 0x80 >> srcskipleft;
+-        bits = *src++;
++        bits = cirrus_src(s, srcaddr++);
+         addr = dstaddr + dstskipleft;
+         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
+             if ((bitmask & 0xff) == 0) {
+                 bitmask = 0x80;
+-                bits = *src++;
++                bits = cirrus_src(s, srcaddr++);
+             }
+             col = colors[!!(bits & bitmask)];
+             PUTPIXEL(s, addr, col);
+@@ -181,7 +183,7 @@ glue(glue(glue(cirrus_colorexpand_, ROP_
+ static void
+ glue(glue(glue(cirrus_colorexpand_pattern_transp_, ROP_NAME), _),DEPTH)
+      (CirrusVGAState *s, uint32_t dstaddr,
+-      const uint8_t *src,
++      uint32_t srcaddr,
+       int dstpitch, int srcpitch,
+       int bltwidth, int bltheight)
+ {
+@@ -207,7 +209,7 @@ glue(glue(glue(cirrus_colorexpand_patter
+     pattern_y = s->cirrus_blt_srcaddr & 7;
+ 
+     for(y = 0; y < bltheight; y++) {
+-        bits = src[pattern_y] ^ bits_xor;
++        bits = cirrus_src(s, srcaddr + pattern_y) ^ bits_xor;
+         bitpos = 7 - srcskipleft;
+         addr = dstaddr + dstskipleft;
+         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
+@@ -225,7 +227,7 @@ glue(glue(glue(cirrus_colorexpand_patter
+ static void
+ glue(glue(glue(cirrus_colorexpand_pattern_, ROP_NAME), _),DEPTH)
+      (CirrusVGAState *s, uint32_t dstaddr,
+-      const uint8_t *src,
++      uint32_t srcaddr,
+       int dstpitch, int srcpitch,
+       int bltwidth, int bltheight)
+ {
+@@ -242,7 +244,7 @@ glue(glue(glue(cirrus_colorexpand_patter
+     pattern_y = s->cirrus_blt_srcaddr & 7;
+ 
+     for(y = 0; y < bltheight; y++) {
+-        bits = src[pattern_y];
++        bits = cirrus_src(s, srcaddr + pattern_y);
+         bitpos = 7 - srcskipleft;
+         addr = dstaddr + dstskipleft;
+         for (x = dstskipleft; x < bltwidth; x += (DEPTH / 8)) {
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-8086.patch qemu-2.1+dfsg/debian/patches/CVE-2017-8086.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-8086.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-8086.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,34 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.34
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 861348
+
+Backport of:
+
+From 4ffcdef4277a91af15a3c09f7d16af072c29f3f2 Mon Sep 17 00:00:00 2001
+From: Li Qiang <liq3ea@gmail.com>
+Date: Fri, 7 Apr 2017 03:48:52 -0700
+Subject: [PATCH] 9pfs: xattr: fix memory leak in v9fs_list_xattr
+
+Free 'orig_value' in error path.
+
+Signed-off-by: Li Qiang <liqiang6-s@360.cn>
+Signed-off-by: Greg Kurz <groug@kaod.org>
+---
+ hw/9pfs/9p-xattr.c | 1 +
+ 1 file changed, 1 insertion(+)
+
+diff --git a/hw/9pfs/virtio-9p-xattr.c b/hw/9pfs/virtio-9p-xattr.c
+index eec160b..d05c1a1 100644
+--- a/hw/9pfs/virtio-9p-xattr.c
++++ b/hw/9pfs/virtio-9p-xattr.c
+@@ -108,6 +108,7 @@ ssize_t v9fs_list_xattr(FsContext *ctx, const char *path,
+     g_free(name);
+     close_preserve_errno(dirfd);
+     if (xattr_len < 0) {
++        g_free(orig_value);
+         return -1;
+     }
+ 
+-- 
+1.8.3.1
+
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-8112.patch qemu-2.1+dfsg/debian/patches/CVE-2017-8112.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-8112.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-8112.patch	2018-07-26 16:49:17.000000000 +0200
@@ -0,0 +1,35 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.35
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 861351
+
+From f68826989cd4d1217797251339579c57b3c0934e 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] 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(-)
+
+Index: qemu/hw/scsi/vmw_pvscsi.c
+===================================================================
+--- qemu.orig/hw/scsi/vmw_pvscsi.c
++++ qemu/hw/scsi/vmw_pvscsi.c
+@@ -174,6 +174,9 @@ pvscsi_ring_init_msg(PVSCSIRingInfo *m,
+     uint32_t len_log2;
+     uint32_t ring_size;
+ 
++    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;
+     len_log2 = pvscsi_log2(ring_size - 1);
+ 
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-8309-audio-release-capture-buffers.patch qemu-2.1+dfsg/debian/patches/CVE-2017-8309-audio-release-capture-buffers.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-8309-audio-release-capture-buffers.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-8309-audio-release-capture-buffers.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,32 @@
+Origin: debian, 1.1.2+dfsg-6+deb7u23
+Reviewed-by: Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 862280
+
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Fri, 28 Apr 2017 09:56:12 +0200
+Subject: CVE-2017-8309: 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.
+
+Upstream-Commit: 3268a845f41253fb55852a8429c32b50f36f349a
+---
+ audio/audio.c | 2 ++
+ 1 file changed, 2 insertions(+)
+
+diff --git a/audio/audio.c b/audio/audio.c
+index 583ee51..cf9c80d 100644
+--- a/audio/audio.c
++++ b/audio/audio.c
+@@ -2052,6 +2052,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;
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-8379-1.patch qemu-2.1+dfsg/debian/patches/CVE-2017-8379-1.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-8379-1.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-8379-1.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,91 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/1:2.5+dfsg-5ubuntu10.31
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 862289
+
+From fa18f36a461984eae50ab957e47ec78dae3c14fc Mon Sep 17 00:00:00 2001
+From: Gerd Hoffmann <kraxel@redhat.com>
+Date: Fri, 28 Apr 2017 10:42:37 +0200
+Subject: [PATCH] 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(-)
+
+Index: qemu/ui/input.c
+===================================================================
+--- qemu.orig/ui/input.c
++++ qemu/ui/input.c
+@@ -38,6 +38,8 @@ static QTAILQ_HEAD(QemuInputEventQueueHe
+     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)
+@@ -218,6 +220,7 @@ static void qemu_input_queue_process(voi
+             break;
+         }
+         QTAILQ_REMOVE(queue, item, node);
++        queue_count--;
+         g_free(item);
+     }
+ }
+@@ -232,6 +235,7 @@ static void qemu_input_queue_delay(struc
+     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)
+@@ -248,6 +252,7 @@ static void qemu_input_queue_event(struc
+     item->src = src;
+     item->evt = evt;
+     QTAILQ_INSERT_TAIL(queue, item, node);
++    queue_count++;
+ }
+ 
+ static void qemu_input_queue_sync(struct QemuInputEventQueueHead *queue)
+@@ -256,6 +261,7 @@ static void qemu_input_queue_sync(struct
+ 
+     item->type = QEMU_INPUT_QUEUE_SYNC;
+     QTAILQ_INSERT_TAIL(queue, item, node);
++    queue_count++;
+ }
+ 
+ void qemu_input_event_send(QemuConsole *src, InputEvent *evt)
+@@ -321,7 +327,7 @@ void qemu_input_event_send_key(QemuConso
+         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);
+     }
+@@ -349,8 +355,10 @@ void qemu_input_event_send_key_delay(uin
+         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)
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-8379-2.patch qemu-2.1+dfsg/debian/patches/CVE-2017-8379-2.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-8379-2.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-8379-2.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,51 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/1:2.5+dfsg-5ubuntu10.31
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 862289
+
+From 05c6638b203fd7d8bbfa88ac6e6198e32ed0506f Mon Sep 17 00:00:00 2001
+From: =?utf8?q?Marc-Andr=C3=A9=20Lureau?= <marcandre.lureau@redhat.com>
+Date: Tue, 25 Apr 2017 17:05:20 +0400
+Subject: [PATCH] input: don't queue delay if paused
+MIME-Version: 1.0
+Content-Type: text/plain; charset=utf8
+Content-Transfer-Encoding: 8bit
+
+qemu_input_event_send() discards key event when the guest is paused,
+but not the delay.
+
+The delay ends up in the input queue, and qemu_input_event_send_key()
+will further fill the queue with upcoming events.
+
+VNC uses qemu_input_event_send_key_delay(), not SPICE, which results
+in a different input behaviour on pause: VNC will queue the events
+(except the first that is discarded), SPICE will discard all events.
+
+Don't queue delay if paused, and provide same behaviour on SPICE and
+VNC clients on resume (and potentially avoid over-allocating the
+buffer queue)
+
+Fixes:
+https://bugzilla.redhat.com/show_bug.cgi?id=1444326
+
+Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
+Message-id: 20170425130520.31819-1-marcandre.lureau@redhat.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ ui/input.c | 4 ++++
+ 1 file changed, 4 insertions(+)
+
+Index: qemu-2.5+dfsg/ui/input.c
+===================================================================
+--- qemu-2.5+dfsg.orig/ui/input.c	2017-05-10 10:08:03.231185049 -0400
++++ qemu-2.5+dfsg/ui/input.c	2017-05-10 10:08:03.211184858 -0400
+@@ -404,6 +404,10 @@ void qemu_input_event_send_key_qcode(Qem
+ 
+ void qemu_input_event_send_key_delay(uint32_t delay_ms)
+ {
++    if (!runstate_is_running() && !runstate_check(RUN_STATE_SUSPENDED)) {
++        return;
++    }
++
+     if (!kbd_timer) {
+         kbd_timer = timer_new_ms(QEMU_CLOCK_VIRTUAL, qemu_input_queue_process,
+                                  &kbd_queue);
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-9330.patch qemu-2.1+dfsg/debian/patches/CVE-2017-9330.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-9330.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-9330.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,34 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.35
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 863943
+
+Backport of:
+
+From 26f670a244982335cc08943fb1ec099a2c81e42d Mon Sep 17 00:00:00 2001
+From: Li Qiang <liqiang6-s@360.cn>
+Date: Tue, 7 Feb 2017 03:15:03 -0800
+Subject: [PATCH] usb: ohci: fix error return code in servicing iso td
+
+It should return 1 if an error occurs when reading iso td.
+This will avoid an infinite loop issue in ohci_service_ed_list.
+
+Signed-off-by: Li Qiang <liqiang6-s@360.cn>
+Message-id: 5899ac3e.1033240a.944d5.9a2d@mx.google.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/usb/hcd-ohci.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+Index: qemu-2.0.0+dfsg/hw/usb/hcd-ohci.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/usb/hcd-ohci.c	2017-08-22 10:19:26.528462419 -0400
++++ qemu-2.0.0+dfsg/hw/usb/hcd-ohci.c	2017-08-22 10:19:26.500462418 -0400
+@@ -727,7 +727,7 @@ static int ohci_service_iso_td(OHCIState
+     if (ohci_read_iso_td(ohci, addr, &iso_td)) {
+         printf("usb-ohci: ISO_TD read error at %x\n", addr);
+         ohci_die(ohci);
+-        return 0;
++        return 1;
+     }
+ 
+     starting_frame = OHCI_BM(iso_td.flags, TD_SF);
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-9373-1.patch qemu-2.1+dfsg/debian/patches/CVE-2017-9373-1.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-9373-1.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-9373-1.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,54 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.35
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 864216
+
+Backport of:
+
+From c9f086418a255f386e1c4d2c1418c032eb349537 Mon Sep 17 00:00:00 2001
+From: Li Qiang <liq3ea@gmail.com>
+Date: Wed, 15 Mar 2017 20:50:14 -0400
+Subject: [PATCH] ide: core: add cleanup function
+
+As the pci ahci can be hotplug and unplug, in the ahci unrealize
+function it should free all the resource once allocated in the
+realized function. This patch add ide_exit to free the resource.
+
+Signed-off-by: Li Qiang <liqiang6-s@360.cn>
+Message-id: 1488449293-80280-3-git-send-email-liqiang6-s@360.cn
+Signed-off-by: John Snow <jsnow@redhat.com>
+---
+ hw/ide/core.c             | 8 ++++++++
+ include/hw/ide/internal.h | 1 +
+ 2 files changed, 9 insertions(+)
+
+Index: qemu-2.0.0+dfsg/hw/ide/core.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/ide/core.c	2017-08-22 10:19:58.548463912 -0400
++++ qemu-2.0.0+dfsg/hw/ide/core.c	2017-08-22 10:19:58.528463911 -0400
+@@ -2246,6 +2246,14 @@ void ide_init2(IDEBus *bus, qemu_irq irq
+     bus->dma = &ide_dma_nop;
+ }
+ 
++void ide_exit(IDEState *s)
++{
++    timer_del(s->sector_write_timer);
++    timer_free(s->sector_write_timer);
++    qemu_vfree(s->smart_selftest_data);
++    qemu_vfree(s->io_buffer);
++}
++
+ static const MemoryRegionPortio ide_portio_list[] = {
+     { 0, 8, 1, .read = ide_ioport_read, .write = ide_ioport_write },
+     { 0, 2, 2, .read = ide_data_readw, .write = ide_data_writew },
+Index: qemu-2.0.0+dfsg/hw/ide/internal.h
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/ide/internal.h	2017-08-22 10:19:58.548463912 -0400
++++ qemu-2.0.0+dfsg/hw/ide/internal.h	2017-08-22 10:19:58.532463911 -0400
+@@ -554,6 +554,7 @@ int ide_init_drive(IDEState *s, BlockDri
+                    uint32_t cylinders, uint32_t heads, uint32_t secs,
+                    int chs_trans);
+ void ide_init2(IDEBus *bus, qemu_irq irq);
++void ide_exit(IDEState *s);
+ void ide_init_ioport(IDEBus *bus, ISADevice *isa, int iobase, int iobase2);
+ 
+ void ide_exec_cmd(IDEBus *bus, uint32_t val);
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-9373-2.patch qemu-2.1+dfsg/debian/patches/CVE-2017-9373-2.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-9373-2.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-9373-2.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,43 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.35
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 864216
+
+Backport of:
+
+From d68f0f778e7f4fbd674627274267f269e40f0b04 Mon Sep 17 00:00:00 2001
+From: Li Qiang <liq3ea@gmail.com>
+Date: Wed, 15 Mar 2017 20:50:14 -0400
+Subject: [PATCH] ide: ahci: call cleanup function in ahci unit
+
+This can avoid memory leak when hotunplug the ahci device.
+
+Signed-off-by: Li Qiang <liqiang6-s@360.cn>
+Message-id: 1488449293-80280-4-git-send-email-liqiang6-s@360.cn
+Signed-off-by: John Snow <jsnow@redhat.com>
+---
+ hw/ide/ahci.c | 12 ++++++++++++
+ 1 file changed, 12 insertions(+)
+
+Index: qemu-2.0.0+dfsg/hw/ide/ahci.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/ide/ahci.c	2017-08-22 10:20:33.300465533 -0400
++++ qemu-2.0.0+dfsg/hw/ide/ahci.c	2017-08-22 10:21:18.236467628 -0400
+@@ -1211,6 +1211,18 @@ void ahci_init(AHCIState *s, DeviceState
+ 
+ void ahci_uninit(AHCIState *s)
+ {
++    int i, j;
++
++    for (i = 0; i < s->ports; i++) {
++        AHCIDevice *ad = &s->dev[i];
++
++        for (j = 0; j < 2; j++) {
++            IDEState *s = &ad->port.ifs[j];
++
++            ide_exit(s);
++        }
++    }
++
+     memory_region_destroy(&s->mem);
+     memory_region_destroy(&s->idp);
+     g_free(s->dev);
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-9374.patch qemu-2.1+dfsg/debian/patches/CVE-2017-9374.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-9374.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-9374.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,81 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.35
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 864568
+
+Backport of:
+
+From d710e1e7bd3d5bfc26b631f02ae87901ebe646b0 Mon Sep 17 00:00:00 2001
+From: Li Qiang <liqiang6-s@360.cn>
+Date: Tue, 7 Feb 2017 18:42:55 -0800
+Subject: [PATCH] usb: ehci: fix memory leak in ehci
+
+In usb_ehci_init function, it initializes 's->ipacket', but there
+is no corresponding function to free this. As the ehci can be hotplug
+and unplug, this will leak host memory leak. In order to make the
+hierarchy clean, we should add a ehci pci finalize function, then call
+the clean function in ehci device.
+
+Signed-off-by: Li Qiang <liqiang6-s@360.cn>
+Message-id: 589a85b8.3c2b9d0a.b8e6.1434@mx.google.com
+Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
+---
+ hw/usb/hcd-ehci-pci.c | 9 +++++++++
+ hw/usb/hcd-ehci.c     | 5 +++++
+ hw/usb/hcd-ehci.h     | 1 +
+ 3 files changed, 15 insertions(+)
+
+Index: qemu-2.0.0+dfsg/hw/usb/hcd-ehci-pci.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/usb/hcd-ehci-pci.c	2017-08-22 10:22:04.788469799 -0400
++++ qemu-2.0.0+dfsg/hw/usb/hcd-ehci-pci.c	2017-08-22 10:22:42.276471547 -0400
+@@ -84,6 +84,14 @@ static void usb_ehci_pci_init(Object *ob
+     usb_ehci_init(s, DEVICE(obj));
+ }
+ 
++static void usb_ehci_pci_finalize(Object *obj)
++{
++    EHCIPCIState *i = PCI_EHCI(obj);
++    EHCIState *s = &i->ehci;
++
++    usb_ehci_finalize(s);
++}
++
+ static void usb_ehci_pci_write_config(PCIDevice *dev, uint32_t addr,
+                                       uint32_t val, int l)
+ {
+@@ -133,6 +141,7 @@ static const TypeInfo ehci_pci_type_info
+     .parent = TYPE_PCI_DEVICE,
+     .instance_size = sizeof(EHCIPCIState),
+     .instance_init = usb_ehci_pci_init,
++    .instance_finalize = usb_ehci_pci_finalize,
+     .abstract = true,
+     .class_init = ehci_class_init,
+ };
+Index: qemu-2.0.0+dfsg/hw/usb/hcd-ehci.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/usb/hcd-ehci.c	2017-08-22 10:22:04.788469799 -0400
++++ qemu-2.0.0+dfsg/hw/usb/hcd-ehci.c	2017-08-22 10:22:04.768469798 -0400
+@@ -2593,6 +2593,11 @@ void usb_ehci_init(EHCIState *s, DeviceS
+                                 &s->mem_ports);
+ }
+ 
++void usb_ehci_finalize(EHCIState *s)
++{
++    usb_packet_cleanup(&s->ipacket);
++}
++
+ /*
+  * vim: expandtab ts=4
+  */
+Index: qemu-2.0.0+dfsg/hw/usb/hcd-ehci.h
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/usb/hcd-ehci.h	2017-08-22 10:22:04.788469799 -0400
++++ qemu-2.0.0+dfsg/hw/usb/hcd-ehci.h	2017-08-22 10:22:04.768469798 -0400
+@@ -321,6 +321,7 @@ struct EHCIState {
+ extern const VMStateDescription vmstate_ehci;
+ 
+ void usb_ehci_init(EHCIState *s, DeviceState *dev);
++void usb_ehci_finalize(EHCIState *s);
+ void usb_ehci_realize(EHCIState *s, DeviceState *dev, Error **errp);
+ 
+ #define TYPE_PCI_EHCI "pci-ehci-usb"
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-9503-1.patch qemu-2.1+dfsg/debian/patches/CVE-2017-9503-1.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-9503-1.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-9503-1.patch	2018-07-26 19:10:42.000000000 +0200
@@ -0,0 +1,102 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.35
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 865754
+
+Backport of:
+
+From 660174fc1b346803b3f1d7c260e2a36329b66435 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Thu, 1 Jun 2017 16:45:16 +0200
+Subject: [PATCH] megasas: add qtest
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ tests/Makefile.include |  3 +++
+ tests/megasas-test.c   | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++
+ 2 files changed, 54 insertions(+)
+ create mode 100644 tests/megasas-test.c
+
+Index: qemu/tests/Makefile
+===================================================================
+--- qemu.orig/tests/Makefile
++++ qemu/tests/Makefile
+@@ -121,12 +121,14 @@ check-qtest-pci-y += tests/tpci200-test$
+ gcov-files-pci-y += hw/ipack/tpci200.c
+ check-qtest-pci-y += $(check-qtest-ipack-y)
+ gcov-files-pci-y += $(gcov-files-ipack-y)
++check-qtest-pci-y += tests/megasas-test$(EXESUF)
++gcov-files-pci-y += hw/scsi/megasas.c
+ check-qtest-pci-y += tests/display-vga-test$(EXESUF)
+ gcov-files-pci-y += hw/display/vga.c
+ gcov-files-pci-y += hw/display/cirrus_vga.c
+ gcov-files-pci-y += hw/display/vga-pci.c
+ check-qtest-pci-y += tests/intel-hda-test$(EXESUF)
+-gcov-files-pci-y += hw/audio/intel-hda.c hw/audio/hda-codec.c
++GCOV-files-pci-y += hw/audio/intel-hda.c hw/audio/hda-codec.c
+ 
+ check-qtest-i386-y = tests/endianness-test$(EXESUF)
+ check-qtest-i386-y += tests/fdc-test$(EXESUF)
+@@ -339,6 +341,7 @@ tests/usb-hcd-ehci-test$(EXESUF): tests/
+ tests/vhost-user-test$(EXESUF): tests/vhost-user-test.o qemu-char.o qemu-timer.o $(qtest-obj-y)
+ tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o
+ tests/test-qemu-opts$(EXESUF): tests/test-qemu-opts.o libqemuutil.a libqemustub.a
++tests/megasas-test$(EXESUF): tests/megasas-test.o $(libqos-spapr-obj-y) $(libqos-pc-obj-y)
+ 
+ ifeq ($(CONFIG_POSIX),y)
+ LIBS += -lutil
+Index: qemu/tests/megasas-test.c
+===================================================================
+--- /dev/null
++++ qemu/tests/megasas-test.c
+@@ -0,0 +1,51 @@
++/*
++ * QTest testcase for LSI MegaRAID
++ *
++ * Copyright (c) 2017 Red Hat Inc.
++ *
++ * This work is licensed under the terms of the GNU GPL, version 2 or later.
++ * See the COPYING file in the top-level directory.
++ */
++
++#include "qemu/osdep.h"
++#include "libqtest.h"
++#include "qemu/bswap.h"
++#include "libqos/libqos-pc.h"
++#include "libqos/libqos-spapr.h"
++
++static QOSState *qmegasas_start(const char *extra_opts)
++{
++    const char *arch = qtest_get_arch();
++    const char *cmd = "-drive id=hd0,if=none,file=null-co://,format=raw "
++                      "-device megasas,id=scsi0,addr=04.0 "
++                      "-device scsi-hd,bus=scsi0.0,drive=hd0 %s";
++
++    if (strcmp(arch, "i386") == 0 || strcmp(arch, "x86_64") == 0) {
++        return qtest_pc_boot(cmd, extra_opts ? : "");
++    }
++
++    g_printerr("virtio-scsi tests are only available on x86 or ppc64\n");
++    exit(EXIT_FAILURE);
++}
++
++static void qmegasas_stop(QOSState *qs)
++{
++    qtest_shutdown(qs);
++}
++
++/* Tests only initialization so far. TODO: Replace with functional tests */
++static void pci_nop(void)
++{
++    QOSState *qs;
++
++    qs = qmegasas_start(NULL);
++    qmegasas_stop(qs);
++}
++
++int main(int argc, char **argv)
++{
++    g_test_init(&argc, &argv, NULL);
++    qtest_add_func("/megasas/pci/nop", pci_nop);
++
++    return g_test_run();
++}
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-9503-2.patch qemu-2.1+dfsg/debian/patches/CVE-2017-9503-2.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-9503-2.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-9503-2.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,34 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.35
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 865754
+
+From 134550bf81a026e18cf58b81e2c2cceaf516f92e Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Thu, 1 Jun 2017 17:18:39 +0200
+Subject: [PATCH] megasas: do not read sense length more than once from frame
+
+Avoid TOC-TOU bugs depending on how the compiler behaves.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/scsi/megasas.c | 6 ++++--
+ 1 file changed, 4 insertions(+), 2 deletions(-)
+
+Index: qemu/hw/scsi/megasas.c
+===================================================================
+--- qemu.orig/hw/scsi/megasas.c
++++ qemu/hw/scsi/megasas.c
+@@ -297,9 +297,11 @@ static int megasas_build_sense(MegasasCm
+     PCIDevice *pcid = PCI_DEVICE(cmd->state);
+     uint32_t pa_hi = 0, pa_lo;
+     hwaddr pa;
++    int frame_sense_len;
+ 
+-    if (sense_len > cmd->frame->header.sense_len) {
+-        sense_len = cmd->frame->header.sense_len;
++    frame_sense_len = cmd->frame->header.sense_len;
++    if (sense_len > frame_sense_len) {
++        sense_len = frame_sense_len;
+     }
+     if (sense_len) {
+         pa_lo = le32_to_cpu(cmd->frame->pass.sense_addr_lo);
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-9503-3.patch qemu-2.1+dfsg/debian/patches/CVE-2017-9503-3.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-9503-3.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-9503-3.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,41 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.35
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 865754
+
+From 24c0c77af515acbf0f9705e8096f33ef24d37430 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Thu, 1 Jun 2017 17:18:57 +0200
+Subject: [PATCH] megasas: do not read iovec count more than once from frame
+
+Avoid TOC-TOU bugs depending on how the compiler behaves.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/scsi/megasas.c | 9 +++++----
+ 1 file changed, 5 insertions(+), 4 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/scsi/megasas.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/scsi/megasas.c	2017-08-22 12:28:37.844823873 -0400
++++ qemu-2.0.0+dfsg/hw/scsi/megasas.c	2017-08-22 12:28:37.844823873 -0400
+@@ -632,15 +632,16 @@ out:
+ static int megasas_map_dcmd(MegasasState *s, MegasasCmd *cmd)
+ {
+     dma_addr_t iov_pa, iov_size;
++    int iov_count;
+ 
+     cmd->flags = le16_to_cpu(cmd->frame->header.flags);
+-    if (!cmd->frame->header.sge_count) {
++    iov_count = cmd->frame->header.sge_count;
++    if (!iov_count) {
+         trace_megasas_dcmd_zero_sge(cmd->index);
+         cmd->iov_size = 0;
+         return 0;
+-    } else if (cmd->frame->header.sge_count > 1) {
+-        trace_megasas_dcmd_invalid_sge(cmd->index,
+-                                       cmd->frame->header.sge_count);
++    } else if (iov_count > 1) {
++        trace_megasas_dcmd_invalid_sge(cmd->index, iov_count);
+         cmd->iov_size = 0;
+         return -EINVAL;
+     }
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-9503-4.patch qemu-2.1+dfsg/debian/patches/CVE-2017-9503-4.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-9503-4.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-9503-4.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,119 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.35
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 865754
+
+Backport of:
+
+From 5104fac8539eaf155fc6de93e164be43e1e62242 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Thu, 1 Jun 2017 17:18:23 +0200
+Subject: [PATCH] megasas: do not read DCMD opcode more than once from frame
+
+Avoid TOC-TOU bugs by storing the DCMD opcode in the MegasasCmd
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/scsi/megasas.c | 25 +++++++++++--------------
+ 1 file changed, 11 insertions(+), 14 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/scsi/megasas.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/scsi/megasas.c	2017-08-22 12:28:43.408824132 -0400
++++ qemu-2.0.0+dfsg/hw/scsi/megasas.c	2017-08-22 12:28:43.408824132 -0400
+@@ -60,6 +60,7 @@ typedef struct MegasasCmd {
+ 
+     hwaddr pa;
+     hwaddr pa_size;
++    uint32_t dcmd_opcode;
+     union mfi_frame *frame;
+     SCSIRequest *req;
+     QEMUSGList qsg;
+@@ -496,6 +497,7 @@ static MegasasCmd *megasas_enqueue_frame
+         }
+     }
+     cmd->count = count;
++    cmd->dcmd_opcode = -1;
+     s->busy++;
+ 
+     trace_megasas_qf_enqueue(cmd->index, cmd->count, cmd->context,
+@@ -1461,22 +1463,21 @@ static const struct dcmd_cmd_tbl_t {
+ 
+ static int megasas_handle_dcmd(MegasasState *s, MegasasCmd *cmd)
+ {
+-    int opcode;
+     int retval = 0;
+     size_t len;
+     const struct dcmd_cmd_tbl_t *cmdptr = dcmd_cmd_tbl;
+ 
+-    opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
+-    trace_megasas_handle_dcmd(cmd->index, opcode);
++    cmd->dcmd_opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
++    trace_megasas_handle_dcmd(cmd->index, cmd->dcmd_opcode);
+     if (megasas_map_dcmd(s, cmd) < 0) {
+         return MFI_STAT_MEMORY_NOT_AVAILABLE;
+     }
+-    while (cmdptr->opcode != -1 && cmdptr->opcode != opcode) {
++    while (cmdptr->opcode != -1 && cmdptr->opcode != cmd->dcmd_opcode) {
+         cmdptr++;
+     }
+     len = cmd->iov_size;
+     if (cmdptr->opcode == -1) {
+-        trace_megasas_dcmd_unhandled(cmd->index, opcode, len);
++        trace_megasas_dcmd_unhandled(cmd->index, cmd->dcmd_opcode, len);
+         retval = megasas_dcmd_dummy(s, cmd);
+     } else {
+         trace_megasas_dcmd_enter(cmd->index, cmdptr->desc, len);
+@@ -1491,14 +1492,13 @@ static int megasas_handle_dcmd(MegasasSt
+ static int megasas_finish_internal_dcmd(MegasasCmd *cmd,
+                                         SCSIRequest *req)
+ {
+-    int opcode;
+     int retval = MFI_STAT_OK;
+     int lun = req->lun;
+ 
+-    opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
+     scsi_req_unref(req);
+-    trace_megasas_dcmd_internal_finish(cmd->index, opcode, lun);
+-    switch (opcode) {
++
++    trace_megasas_dcmd_internal_finish(cmd->index, cmd->dcmd_opcode, lun);
++    switch (cmd->dcmd_opcode) {
+     case MFI_DCMD_PD_GET_INFO:
+         retval = megasas_pd_get_info_submit(req->dev, lun, cmd);
+         break;
+@@ -1506,7 +1506,7 @@ static int megasas_finish_internal_dcmd(
+         retval = megasas_ld_get_info_submit(req->dev, lun, cmd);
+         break;
+     default:
+-        trace_megasas_dcmd_internal_invalid(cmd->index, opcode);
++        trace_megasas_dcmd_internal_invalid(cmd->index, cmd->dcmd_opcode);
+         retval = MFI_STAT_INVALID_DCMD;
+         break;
+     }
+@@ -1728,7 +1728,6 @@ static void megasas_xfer_complete(SCSIRe
+ {
+     MegasasCmd *cmd = req->hba_private;
+     uint8_t *buf;
+-    uint32_t opcode;
+ 
+     trace_megasas_io_complete(cmd->index, len);
+ 
+@@ -1738,8 +1737,7 @@ static void megasas_xfer_complete(SCSIRe
+     }
+ 
+     buf = scsi_req_get_buf(req);
+-    opcode = le32_to_cpu(cmd->frame->dcmd.opcode);
+-    if (opcode == MFI_DCMD_PD_GET_INFO && cmd->iov_buf) {
++    if (cmd->dcmd_opcode == MFI_DCMD_PD_GET_INFO && cmd->iov_buf) {
+         struct mfi_pd_info *info = cmd->iov_buf;
+ 
+         if (info->inquiry_data[0] == 0x7f) {
+@@ -1750,7 +1748,7 @@ static void megasas_xfer_complete(SCSIRe
+             memcpy(info->vpd_page83, buf, len);
+         }
+         scsi_req_continue(req);
+-    } else if (opcode == MFI_DCMD_LD_GET_INFO) {
++    } else if (cmd->dcmd_opcode == MFI_DCMD_LD_GET_INFO) {
+         struct mfi_ld_info *info = cmd->iov_buf;
+ 
+         if (cmd->iov_buf) {
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-9503-5.patch qemu-2.1+dfsg/debian/patches/CVE-2017-9503-5.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-9503-5.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-9503-5.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,227 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.35
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 865754
+
+Backport of:
+
+From 36c327a69d723571f02a7691631667cdb1865ee1 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Thu, 1 Jun 2017 17:23:13 +0200
+Subject: [PATCH] megasas: do not read command more than once from frame
+
+Avoid TOC-TOU bugs by passing the frame_cmd down, and checking
+cmd->dcmd_opcode instead of cmd->frame->header.frame_cmd.
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/scsi/megasas.c | 60 +++++++++++++++++++++++--------------------------------
+ 1 file changed, 25 insertions(+), 35 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/scsi/megasas.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/scsi/megasas.c	2017-08-22 12:28:54.104824631 -0400
++++ qemu-2.0.0+dfsg/hw/scsi/megasas.c	2017-08-22 12:29:16.792825689 -0400
+@@ -1490,7 +1490,7 @@ static int megasas_handle_dcmd(MegasasSt
+ }
+ 
+ static int megasas_finish_internal_dcmd(MegasasCmd *cmd,
+-                                        SCSIRequest *req)
++                                        SCSIRequest *req, size_t resid)
+ {
+     int retval = MFI_STAT_OK;
+     int lun = req->lun;
+@@ -1498,6 +1498,7 @@ static int megasas_finish_internal_dcmd(
+     scsi_req_unref(req);
+ 
+     trace_megasas_dcmd_internal_finish(cmd->index, cmd->dcmd_opcode, lun);
++    cmd->iov_size -= resid;
+     switch (cmd->dcmd_opcode) {
+     case MFI_DCMD_PD_GET_INFO:
+         retval = megasas_pd_get_info_submit(req->dev, lun, cmd);
+@@ -1550,12 +1551,13 @@ static int megasas_enqueue_req(MegasasCm
+ }
+ 
+ static int megasas_handle_scsi(MegasasState *s, MegasasCmd *cmd,
+-                               bool is_logical)
++                               int frame_cmd)
+ {
+     uint8_t *cdb;
+     int len;
+     bool is_write;
+     struct SCSIDevice *sdev = NULL;
++    bool is_logical = (frame_cmd == MFI_CMD_LD_SCSI_IO);
+ 
+     cdb = cmd->frame->pass.cdb;
+ 
+@@ -1563,7 +1565,7 @@ static int megasas_handle_scsi(MegasasSt
+         if (cmd->frame->header.target_id >= MFI_MAX_LD ||
+             cmd->frame->header.lun_id != 0) {
+             trace_megasas_scsi_target_not_present(
+-                mfi_frame_desc[cmd->frame->header.frame_cmd], is_logical,
++                mfi_frame_desc[frame_cmd], is_logical,
+                 cmd->frame->header.target_id, cmd->frame->header.lun_id);
+             return MFI_STAT_DEVICE_NOT_FOUND;
+         }
+@@ -1573,19 +1575,20 @@ static int megasas_handle_scsi(MegasasSt
+ 
+     cmd->iov_size = le32_to_cpu(cmd->frame->header.data_len);
+     trace_megasas_handle_scsi(mfi_frame_desc[cmd->frame->header.frame_cmd],
+-                              is_logical, cmd->frame->header.target_id,
++    trace_megasas_handle_scsi(mfi_frame_desc[frame_cmd], is_logical,
++                              cmd->frame->header.target_id,
+                               cmd->frame->header.lun_id, sdev, cmd->iov_size);
+ 
+     if (!sdev || (megasas_is_jbod(s) && is_logical)) {
+         trace_megasas_scsi_target_not_present(
+-            mfi_frame_desc[cmd->frame->header.frame_cmd], is_logical,
++            mfi_frame_desc[frame_cmd], is_logical,
+             cmd->frame->header.target_id, cmd->frame->header.lun_id);
+         return MFI_STAT_DEVICE_NOT_FOUND;
+     }
+ 
+     if (cmd->frame->header.cdb_len > 16) {
+         trace_megasas_scsi_invalid_cdb_len(
+-                mfi_frame_desc[cmd->frame->header.frame_cmd], is_logical,
++                mfi_frame_desc[frame_cmd], is_logical,
+                 cmd->frame->header.target_id, cmd->frame->header.lun_id,
+                 cmd->frame->header.cdb_len);
+         megasas_write_sense(cmd, SENSE_CODE(INVALID_OPCODE));
+@@ -1605,7 +1608,7 @@ static int megasas_handle_scsi(MegasasSt
+                             cmd->frame->header.lun_id, cdb, cmd);
+     if (!cmd->req) {
+         trace_megasas_scsi_req_alloc_failed(
+-                mfi_frame_desc[cmd->frame->header.frame_cmd],
++                mfi_frame_desc[frame_cmd],
+                 cmd->frame->header.target_id, cmd->frame->header.lun_id);
+         megasas_write_sense(cmd, SENSE_CODE(NO_SENSE));
+         cmd->frame->header.scsi_status = BUSY;
+@@ -1627,11 +1630,11 @@ static int megasas_handle_scsi(MegasasSt
+     return MFI_STAT_INVALID_STATUS;
+ }
+ 
+-static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd)
++static int megasas_handle_io(MegasasState *s, MegasasCmd *cmd, int frame_cmd)
+ {
+     uint32_t lba_count, lba_start_hi, lba_start_lo;
+     uint64_t lba_start;
+-    bool is_write = (cmd->frame->header.frame_cmd == MFI_CMD_LD_WRITE);
++    bool is_write = (frame_cmd == MFI_CMD_LD_WRITE);
+     uint8_t cdb[16];
+     int len;
+     struct SCSIDevice *sdev = NULL;
+@@ -1648,20 +1651,20 @@ static int megasas_handle_io(MegasasStat
+     }
+ 
+     trace_megasas_handle_io(cmd->index,
+-                            mfi_frame_desc[cmd->frame->header.frame_cmd],
++                            mfi_frame_desc[frame_cmd],
+                             cmd->frame->header.target_id,
+                             cmd->frame->header.lun_id,
+                             (unsigned long)lba_start, (unsigned long)lba_count);
+     if (!sdev) {
+         trace_megasas_io_target_not_present(cmd->index,
+-            mfi_frame_desc[cmd->frame->header.frame_cmd],
++            mfi_frame_desc[frame_cmd],
+             cmd->frame->header.target_id, cmd->frame->header.lun_id);
+         return MFI_STAT_DEVICE_NOT_FOUND;
+     }
+ 
+     if (cmd->frame->header.cdb_len > 16) {
+         trace_megasas_scsi_invalid_cdb_len(
+-            mfi_frame_desc[cmd->frame->header.frame_cmd], 1,
++            mfi_frame_desc[frame_cmd], 1,
+             cmd->frame->header.target_id, cmd->frame->header.lun_id,
+             cmd->frame->header.cdb_len);
+         megasas_write_sense(cmd, SENSE_CODE(INVALID_OPCODE));
+@@ -1683,7 +1686,7 @@ static int megasas_handle_io(MegasasStat
+                             cmd->frame->header.lun_id, cdb, cmd);
+     if (!cmd->req) {
+         trace_megasas_scsi_req_alloc_failed(
+-            mfi_frame_desc[cmd->frame->header.frame_cmd],
++            mfi_frame_desc[frame_cmd],
+             cmd->frame->header.target_id, cmd->frame->header.lun_id);
+         megasas_write_sense(cmd, SENSE_CODE(NO_SENSE));
+         cmd->frame->header.scsi_status = BUSY;
+@@ -1701,23 +1704,11 @@ static int megasas_handle_io(MegasasStat
+     return MFI_STAT_INVALID_STATUS;
+ }
+ 
+-static int megasas_finish_internal_command(MegasasCmd *cmd,
+-                                           SCSIRequest *req, size_t resid)
+-{
+-    int retval = MFI_STAT_INVALID_CMD;
+-
+-    if (cmd->frame->header.frame_cmd == MFI_CMD_DCMD) {
+-        cmd->iov_size -= resid;
+-        retval = megasas_finish_internal_dcmd(cmd, req);
+-    }
+-    return retval;
+-}
+-
+ static QEMUSGList *megasas_get_sg_list(SCSIRequest *req)
+ {
+     MegasasCmd *cmd = req->hba_private;
+ 
+-    if (cmd->frame->header.frame_cmd == MFI_CMD_DCMD) {
++    if (cmd->dcmd_opcode != -1) {
+         return NULL;
+     } else {
+         return &cmd->qsg;
+@@ -1731,7 +1722,7 @@ static void megasas_xfer_complete(SCSIRe
+ 
+     trace_megasas_io_complete(cmd->index, len);
+ 
+-    if (cmd->frame->header.frame_cmd != MFI_CMD_DCMD) {
++    if (cmd->dcmd_opcode != -1) {
+         scsi_req_continue(req);
+         return;
+     }
+@@ -1770,7 +1761,7 @@ static void megasas_command_complete(SCS
+         /*
+          * Internal command complete
+          */
+-        cmd_status = megasas_finish_internal_command(cmd, req, resid);
++        cmd_status = megasas_finish_internal_dcmd(cmd, req, resid);
+         if (cmd_status == MFI_STAT_INVALID_STATUS) {
+             return;
+         }
+@@ -1844,6 +1835,7 @@ static void megasas_handle_frame(Megasas
+ {
+     uint8_t frame_status = MFI_STAT_INVALID_CMD;
+     uint64_t frame_context;
++    int frame_cmd;
+     MegasasCmd *cmd;
+ 
+     /*
+@@ -1862,7 +1854,8 @@ static void megasas_handle_frame(Megasas
+         s->event_count++;
+         return;
+     }
+-    switch (cmd->frame->header.frame_cmd) {
++    frame_cmd = cmd->frame->header.frame_cmd;
++    switch (frame_cmd) {
+     case MFI_CMD_INIT:
+         frame_status = megasas_init_firmware(s, cmd);
+         break;
+@@ -1873,18 +1866,15 @@ static void megasas_handle_frame(Megasas
+         frame_status = megasas_handle_abort(s, cmd);
+         break;
+     case MFI_CMD_PD_SCSI_IO:
+-        frame_status = megasas_handle_scsi(s, cmd, 0);
+-        break;
+     case MFI_CMD_LD_SCSI_IO:
+-        frame_status = megasas_handle_scsi(s, cmd, 1);
++        frame_status = megasas_handle_scsi(s, cmd, frame_cmd);
+         break;
+     case MFI_CMD_LD_READ:
+     case MFI_CMD_LD_WRITE:
+-        frame_status = megasas_handle_io(s, cmd);
++        frame_status = megasas_handle_io(s, cmd, frame_cmd);
+         break;
+     default:
+-        trace_megasas_unhandled_frame_cmd(cmd->index,
+-                                          cmd->frame->header.frame_cmd);
++        trace_megasas_unhandled_frame_cmd(cmd->index, frame_cmd);
+         s->event_count++;
+         break;
+     }
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-9503-6.patch qemu-2.1+dfsg/debian/patches/CVE-2017-9503-6.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-9503-6.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-9503-6.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,152 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.35
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 865754
+
+Backport of:
+
+From b356807fcdfc45583c437f761fc579ab2a8eab11 Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Thu, 1 Jun 2017 17:25:03 +0200
+Subject: [PATCH] megasas: do not read SCSI req parameters more than once from
+ frame
+
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/scsi/megasas.c | 60 ++++++++++++++++++++++++-------------------------------
+ 1 file changed, 26 insertions(+), 34 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/scsi/megasas.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/scsi/megasas.c	2017-08-22 12:29:33.436826465 -0400
++++ qemu-2.0.0+dfsg/hw/scsi/megasas.c	2017-08-22 12:31:24.856831661 -0400
+@@ -1554,43 +1554,40 @@ static int megasas_handle_scsi(MegasasSt
+                                int frame_cmd)
+ {
+     uint8_t *cdb;
++    int target_id, lun_id, cdb_len;
+     int len;
+     bool is_write;
+     struct SCSIDevice *sdev = NULL;
+     bool is_logical = (frame_cmd == MFI_CMD_LD_SCSI_IO);
+ 
+     cdb = cmd->frame->pass.cdb;
++    target_id = cmd->frame->header.target_id;
++    lun_id = cmd->frame->header.lun_id;
++    cdb_len = cmd->frame->header.cdb_len;
+ 
+     if (is_logical) {
+-        if (cmd->frame->header.target_id >= MFI_MAX_LD ||
+-            cmd->frame->header.lun_id != 0) {
++        if (target_id >= MFI_MAX_LD || lun_id != 0) {
+             trace_megasas_scsi_target_not_present(
+-                mfi_frame_desc[frame_cmd], is_logical,
+-                cmd->frame->header.target_id, cmd->frame->header.lun_id);
++                mfi_frame_desc[frame_cmd], is_logical, target_id, lun_id);
+             return MFI_STAT_DEVICE_NOT_FOUND;
+         }
+     }
+-    sdev = scsi_device_find(&s->bus, 0, cmd->frame->header.target_id,
+-                            cmd->frame->header.lun_id);
++    sdev = scsi_device_find(&s->bus, 0, target_id, lun_id);
+ 
+     cmd->iov_size = le32_to_cpu(cmd->frame->header.data_len);
+-    trace_megasas_handle_scsi(mfi_frame_desc[cmd->frame->header.frame_cmd],
+     trace_megasas_handle_scsi(mfi_frame_desc[frame_cmd], is_logical,
+-                              cmd->frame->header.target_id,
+-                              cmd->frame->header.lun_id, sdev, cmd->iov_size);
++                              target_id, lun_id, sdev, cmd->iov_size);
+ 
+     if (!sdev || (megasas_is_jbod(s) && is_logical)) {
+         trace_megasas_scsi_target_not_present(
+-            mfi_frame_desc[frame_cmd], is_logical,
+-            cmd->frame->header.target_id, cmd->frame->header.lun_id);
++            mfi_frame_desc[frame_cmd], is_logical, target_id, lun_id);
+         return MFI_STAT_DEVICE_NOT_FOUND;
+     }
+ 
+-    if (cmd->frame->header.cdb_len > 16) {
++    if (cdb_len > 16) {
+         trace_megasas_scsi_invalid_cdb_len(
+                 mfi_frame_desc[frame_cmd], is_logical,
+-                cmd->frame->header.target_id, cmd->frame->header.lun_id,
+-                cmd->frame->header.cdb_len);
++                target_id, lun_id, cdb_len);
+         megasas_write_sense(cmd, SENSE_CODE(INVALID_OPCODE));
+         cmd->frame->header.scsi_status = CHECK_CONDITION;
+         s->event_count++;
+@@ -1604,12 +1601,10 @@ static int megasas_handle_scsi(MegasasSt
+         return MFI_STAT_SCSI_DONE_WITH_ERROR;
+     }
+ 
+-    cmd->req = scsi_req_new(sdev, cmd->index,
+-                            cmd->frame->header.lun_id, cdb, cmd);
++    cmd->req = scsi_req_new(sdev, cmd->index, lun_id, cdb, cmd);
+     if (!cmd->req) {
+         trace_megasas_scsi_req_alloc_failed(
+-                mfi_frame_desc[frame_cmd],
+-                cmd->frame->header.target_id, cmd->frame->header.lun_id);
++                mfi_frame_desc[frame_cmd], target_id, lun_id);
+         megasas_write_sense(cmd, SENSE_CODE(NO_SENSE));
+         cmd->frame->header.scsi_status = BUSY;
+         s->event_count++;
+@@ -1638,35 +1633,33 @@ static int megasas_handle_io(MegasasStat
+     uint8_t cdb[16];
+     int len;
+     struct SCSIDevice *sdev = NULL;
++    int target_id, lun_id, cdb_len;
+ 
+     lba_count = le32_to_cpu(cmd->frame->io.header.data_len);
+     lba_start_lo = le32_to_cpu(cmd->frame->io.lba_lo);
+     lba_start_hi = le32_to_cpu(cmd->frame->io.lba_hi);
+     lba_start = ((uint64_t)lba_start_hi << 32) | lba_start_lo;
+ 
+-    if (cmd->frame->header.target_id < MFI_MAX_LD &&
+-        cmd->frame->header.lun_id == 0) {
+-        sdev = scsi_device_find(&s->bus, 0, cmd->frame->header.target_id,
+-                                cmd->frame->header.lun_id);
++    target_id = cmd->frame->header.target_id;
++    lun_id = cmd->frame->header.lun_id;
++    cdb_len = cmd->frame->header.cdb_len;
++
++    if (target_id < MFI_MAX_LD && lun_id == 0) {
++        sdev = scsi_device_find(&s->bus, 0, target_id, lun_id);
+     }
+ 
+     trace_megasas_handle_io(cmd->index,
+-                            mfi_frame_desc[frame_cmd],
+-                            cmd->frame->header.target_id,
+-                            cmd->frame->header.lun_id,
++                            mfi_frame_desc[frame_cmd], target_id, lun_id,
+                             (unsigned long)lba_start, (unsigned long)lba_count);
+     if (!sdev) {
+         trace_megasas_io_target_not_present(cmd->index,
+-            mfi_frame_desc[frame_cmd],
+-            cmd->frame->header.target_id, cmd->frame->header.lun_id);
++            mfi_frame_desc[frame_cmd], target_id, lun_id);
+         return MFI_STAT_DEVICE_NOT_FOUND;
+     }
+ 
+-    if (cmd->frame->header.cdb_len > 16) {
++    if (cdb_len > 16) {
+         trace_megasas_scsi_invalid_cdb_len(
+-            mfi_frame_desc[frame_cmd], 1,
+-            cmd->frame->header.target_id, cmd->frame->header.lun_id,
+-            cmd->frame->header.cdb_len);
++            mfi_frame_desc[frame_cmd], 1, target_id, lun_id, cdb_len);
+         megasas_write_sense(cmd, SENSE_CODE(INVALID_OPCODE));
+         cmd->frame->header.scsi_status = CHECK_CONDITION;
+         s->event_count++;
+@@ -1683,11 +1676,10 @@ static int megasas_handle_io(MegasasStat
+ 
+     megasas_encode_lba(cdb, lba_start, lba_count, is_write);
+     cmd->req = scsi_req_new(sdev, cmd->index,
+-                            cmd->frame->header.lun_id, cdb, cmd);
++                            lun_id, cdb, cmd);
+     if (!cmd->req) {
+         trace_megasas_scsi_req_alloc_failed(
+-            mfi_frame_desc[frame_cmd],
+-            cmd->frame->header.target_id, cmd->frame->header.lun_id);
++            mfi_frame_desc[frame_cmd], target_id, lun_id);
+         megasas_write_sense(cmd, SENSE_CODE(NO_SENSE));
+         cmd->frame->header.scsi_status = BUSY;
+         s->event_count++;
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-9503-7.patch qemu-2.1+dfsg/debian/patches/CVE-2017-9503-7.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-9503-7.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-9503-7.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,179 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.35
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 865754
+
+Backport of:
+
+From 87e459a810d7b1ec1638085b5a80ea3d9b43119a Mon Sep 17 00:00:00 2001
+From: Paolo Bonzini <pbonzini@redhat.com>
+Date: Thu, 1 Jun 2017 17:26:14 +0200
+Subject: [PATCH] megasas: always store SCSIRequest* into MegasasCmd
+
+This ensures that the request is unref'ed properly, and avoids a
+segmentation fault in the new qtest testcase that is added.
+This is CVE-2017-9503.
+
+Reported-by: Zhangyanyu <zyy4013@stu.ouc.edu.cn>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/scsi/megasas.c    | 31 ++++++++++++++++---------------
+ tests/megasas-test.c | 35 +++++++++++++++++++++++++++++++++++
+ 2 files changed, 51 insertions(+), 15 deletions(-)
+
+Index: qemu-2.0.0+dfsg/hw/scsi/megasas.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/hw/scsi/megasas.c	2017-08-22 12:32:06.408833598 -0400
++++ qemu-2.0.0+dfsg/hw/scsi/megasas.c	2017-08-22 12:32:06.404833598 -0400
+@@ -569,6 +569,9 @@ static void megasas_reset_frames(Megasas
+ 
+ static void megasas_abort_command(MegasasCmd *cmd)
+ {
++    if (cmd->dcmd_opcode != -1) {
++        return;
++    }
+     if (cmd->req) {
+         scsi_req_cancel(cmd->req);
+         cmd->req = NULL;
+@@ -976,7 +979,6 @@ static int megasas_pd_get_info_submit(SC
+     uint64_t pd_size;
+     uint16_t pd_id = ((sdev->id & 0xFF) << 8) | (lun & 0xFF);
+     uint8_t cmdbuf[6];
+-    SCSIRequest *req;
+     size_t len, resid;
+ 
+     if (!cmd->iov_buf) {
+@@ -986,8 +988,8 @@ static int megasas_pd_get_info_submit(SC
+         info->inquiry_data[0] = 0x7f; /* Force PQual 0x3, PType 0x1f */
+         info->vpd_page83[0] = 0x7f;
+         megasas_setup_inquiry(cmdbuf, 0, sizeof(info->inquiry_data));
+-        req = scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd);
+-        if (!req) {
++        cmd->req = scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd);
++        if (!cmd->req) {
+             trace_megasas_dcmd_req_alloc_failed(cmd->index,
+                                                 "PD get info std inquiry");
+             g_free(cmd->iov_buf);
+@@ -996,26 +998,26 @@ static int megasas_pd_get_info_submit(SC
+         }
+         trace_megasas_dcmd_internal_submit(cmd->index,
+                                            "PD get info std inquiry", lun);
+-        len = scsi_req_enqueue(req);
++        len = scsi_req_enqueue(cmd->req);
+         if (len > 0) {
+             cmd->iov_size = len;
+-            scsi_req_continue(req);
++            scsi_req_continue(cmd->req);
+         }
+         return MFI_STAT_INVALID_STATUS;
+     } else if (info->inquiry_data[0] != 0x7f && info->vpd_page83[0] == 0x7f) {
+         megasas_setup_inquiry(cmdbuf, 0x83, sizeof(info->vpd_page83));
+-        req = scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd);
+-        if (!req) {
++        cmd->req = scsi_req_new(sdev, cmd->index, lun, cmdbuf, cmd);
++        if (!cmd->req) {
+             trace_megasas_dcmd_req_alloc_failed(cmd->index,
+                                                 "PD get info vpd inquiry");
+             return MFI_STAT_FLASH_ALLOC_FAIL;
+         }
+         trace_megasas_dcmd_internal_submit(cmd->index,
+                                            "PD get info vpd inquiry", lun);
+-        len = scsi_req_enqueue(req);
++        len = scsi_req_enqueue(cmd->req);
+         if (len > 0) {
+             cmd->iov_size = len;
+-            scsi_req_continue(req);
++            scsi_req_continue(cmd->req);
+         }
+         return MFI_STAT_INVALID_STATUS;
+     }
+@@ -1129,7 +1131,6 @@ static int megasas_ld_get_info_submit(SC
+     struct mfi_ld_info *info = cmd->iov_buf;
+     size_t dcmd_size = sizeof(struct mfi_ld_info);
+     uint8_t cdb[6];
+-    SCSIRequest *req;
+     ssize_t len, resid;
+     BlockConf *conf = &sdev->conf;
+     uint16_t sdev_id = ((sdev->id & 0xFF) << 8) | (lun & 0xFF);
+@@ -1140,8 +1141,8 @@ static int megasas_ld_get_info_submit(SC
+         memset(cmd->iov_buf, 0x0, dcmd_size);
+         info = cmd->iov_buf;
+         megasas_setup_inquiry(cdb, 0x83, sizeof(info->vpd_page83));
+-        req = scsi_req_new(sdev, cmd->index, lun, cdb, cmd);
+-        if (!req) {
++        cmd->req = scsi_req_new(sdev, cmd->index, lun, cdb, cmd);
++        if (!cmd->req) {
+             trace_megasas_dcmd_req_alloc_failed(cmd->index,
+                                                 "LD get info vpd inquiry");
+             g_free(cmd->iov_buf);
+@@ -1150,10 +1151,10 @@ static int megasas_ld_get_info_submit(SC
+         }
+         trace_megasas_dcmd_internal_submit(cmd->index,
+                                            "LD get info vpd inquiry", lun);
+-        len = scsi_req_enqueue(req);
++        len = scsi_req_enqueue(cmd->req);
+         if (len > 0) {
+             cmd->iov_size = len;
+-            scsi_req_continue(req);
++            scsi_req_continue(cmd->req);
+         }
+         return MFI_STAT_INVALID_STATUS;
+     }
+@@ -1749,7 +1750,7 @@ static void megasas_command_complete(SCS
+ 
+     trace_megasas_command_complete(cmd->index, status, resid);
+ 
+-    if (cmd->req != req) {
++    if (cmd->dcmd_opcode != -1) {
+         /*
+          * Internal command complete
+          */
+Index: qemu-2.0.0+dfsg/tests/megasas-test.c
+===================================================================
+--- qemu-2.0.0+dfsg.orig/tests/megasas-test.c	2017-08-22 12:32:06.408833598 -0400
++++ qemu-2.0.0+dfsg/tests/megasas-test.c	2017-08-22 12:32:06.404833598 -0400
+@@ -42,10 +42,45 @@ static void pci_nop(void)
+     qmegasas_stop(qs);
+ }
+ 
++/* This used to cause a NULL pointer dereference.  */
++static void megasas_pd_get_info_fuzz(void)
++{
++    QPCIDevice *dev;
++    QOSState *qs;
++    QPCIBar bar;
++    uint32_t context[256];
++    uint64_t context_pa;
++    int i;
++
++    qs = qmegasas_start(NULL);
++    dev = qpci_device_find(qs->pcibus, QPCI_DEVFN(4,0));
++    g_assert(dev != NULL);
++
++    qpci_device_enable(dev);
++    bar = qpci_iomap(dev, 0, NULL);
++
++    memset(context, 0, sizeof(context));
++    context[0] = cpu_to_le32(0x05050505);
++    context[1] = cpu_to_le32(0x01010101);
++    for (i = 2; i < ARRAY_SIZE(context); i++) {
++        context[i] = cpu_to_le32(0x41414141);
++    }
++    context[6] = cpu_to_le32(0x02020000);
++    context[7] = cpu_to_le32(0);
++
++    context_pa = qmalloc(qs, sizeof(context));
++    memwrite(context_pa, context, sizeof(context));
++    qpci_io_writel(dev, bar, 0x40, context_pa);
++
++    g_free(dev);
++    qmegasas_stop(qs);
++}
++
+ int main(int argc, char **argv)
+ {
+     g_test_init(&argc, &argv, NULL);
+     qtest_add_func("/megasas/pci/nop", pci_nop);
++    qtest_add_func("/megasas/dcmd/pd-get-info/fuzz", megasas_pd_get_info_fuzz);
+ 
+     return g_test_run();
+ }
diff -Nru qemu-2.1+dfsg/debian/patches/CVE-2017-9503-pre1.patch qemu-2.1+dfsg/debian/patches/CVE-2017-9503-pre1.patch
--- qemu-2.1+dfsg/debian/patches/CVE-2017-9503-pre1.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/CVE-2017-9503-pre1.patch	2018-07-29 15:33:43.000000000 +0200
@@ -0,0 +1,283 @@
+Origin: ubuntu, https://launchpad.net/ubuntu/+source/qemu/2.0.0+dfsg-2ubuntu1.35
+Reviewed-by Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 865754
+
+Backport of:
+
+From 3f2cd4dd47719497540fb0e0aa0635e127f2838f Mon Sep 17 00:00:00 2001
+From: Hannes Reinecke <hare@suse.de>
+Date: Wed, 29 Oct 2014 13:00:07 +0100
+Subject: [PATCH] megasas: fixup device mapping
+
+Logical drives can only be addressed with the 'target_id' number;
+LUN numbers cannot be selected.
+Physical drives can be selected with both, target and LUN id.
+
+So we should disallow LUN numbers not equal to 0 when in
+RAID mode.
+
+Signed-off-by: Hannes Reinecke <hare@suse.de>
+Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
+---
+ hw/scsi/megasas.c | 95 +++++++++++++++++++++++++++++++++++--------------------
+ hw/scsi/mfi.h     |  2 +-
+ 2 files changed, 61 insertions(+), 36 deletions(-)
+
+Index: qemu/hw/scsi/megasas.c
+===================================================================
+--- qemu.orig/hw/scsi/megasas.c
++++ qemu/hw/scsi/megasas.c
+@@ -688,8 +688,7 @@ static int megasas_ctrl_get_info(Megasas
+     struct mfi_ctrl_info info;
+     size_t dcmd_size = sizeof(info);
+     BusChild *kid;
+-    int num_ld_disks = 0;
+-    uint16_t sdev_id;
++    int num_pd_disks = 0;
+ 
+     memset(&info, 0x0, dcmd_size);
+     if (cmd->iov_size < dcmd_size) {
+@@ -718,13 +717,14 @@ static int megasas_ctrl_get_info(Megasas
+     info.device.port_count = 8;
+     QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
+         SCSIDevice *sdev = DO_UPCAST(SCSIDevice, qdev, kid->child);
++        uint16_t pd_id;
+ 
+-        if (num_ld_disks < 8) {
+-            sdev_id = ((sdev->id & 0xFF) >> 8) | (sdev->lun & 0xFF);
+-            info.device.port_addr[num_ld_disks] =
+-                cpu_to_le64(megasas_get_sata_addr(sdev_id));
++        if (num_pd_disks < 8) {
++            pd_id = ((sdev->id & 0xFF) << 8) | (sdev->lun & 0xFF);
++            info.device.port_addr[num_pd_disks] =
++                cpu_to_le64(megasas_get_sata_addr(pd_id));
+         }
+-        num_ld_disks++;
++        num_pd_disks++;
+     }
+ 
+     memcpy(info.product_name, "MegaRAID SAS 8708EM2", 20);
+@@ -750,13 +750,14 @@ static int megasas_ctrl_get_info(Megasas
+     info.max_arms = 32;
+     info.max_spans = 8;
+     info.max_arrays = MEGASAS_MAX_ARRAYS;
+-    info.max_lds = s->fw_luns;
++    info.max_lds = MFI_MAX_LD;
+     info.max_cmds = cpu_to_le16(s->fw_cmds);
+     info.max_sg_elements = cpu_to_le16(s->fw_sge);
+     info.max_request_size = cpu_to_le32(MEGASAS_MAX_SECTORS);
+-    info.lds_present = cpu_to_le16(num_ld_disks);
+-    info.pd_present = cpu_to_le16(num_ld_disks);
+-    info.pd_disks_present = cpu_to_le16(num_ld_disks);
++    if (!megasas_is_jbod(s))
++        info.lds_present = cpu_to_le16(num_pd_disks);
++    info.pd_present = cpu_to_le16(num_pd_disks);
++    info.pd_disks_present = cpu_to_le16(num_pd_disks);
+     info.hw_present = cpu_to_le32(MFI_INFO_HW_NVRAM |
+                                    MFI_INFO_HW_MEM |
+                                    MFI_INFO_HW_FLASH);
+@@ -915,7 +916,6 @@ static int megasas_dcmd_pd_get_list(Mega
+     size_t dcmd_size = sizeof(info);
+     BusChild *kid;
+     uint32_t offset, dcmd_limit, num_pd_disks = 0, max_pd_disks;
+-    uint16_t sdev_id;
+ 
+     memset(&info, 0, dcmd_size);
+     offset = 8;
+@@ -927,22 +927,25 @@ static int megasas_dcmd_pd_get_list(Mega
+     }
+ 
+     max_pd_disks = (cmd->iov_size - offset) / sizeof(struct mfi_pd_address);
+-    if (max_pd_disks > s->fw_luns) {
+-        max_pd_disks = s->fw_luns;
++    if (max_pd_disks > MFI_MAX_SYS_PDS) {
++        max_pd_disks = MFI_MAX_SYS_PDS;
+     }
+-
+     QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
+         SCSIDevice *sdev = DO_UPCAST(SCSIDevice, qdev, kid->child);
++        uint16_t pd_id;
++
++        if (num_pd_disks >= max_pd_disks)
++            break;
+ 
+-        sdev_id = ((sdev->id & 0xFF) >> 8) | (sdev->lun & 0xFF);
+-        info.addr[num_pd_disks].device_id = cpu_to_le16(sdev_id);
++        pd_id = ((sdev->id & 0xFF) << 8) | (sdev->lun & 0xFF);
++        info.addr[num_pd_disks].device_id = cpu_to_le16(pd_id);
+         info.addr[num_pd_disks].encl_device_id = 0xFFFF;
+         info.addr[num_pd_disks].encl_index = 0;
+-        info.addr[num_pd_disks].slot_number = (sdev->id & 0xFF);
++        info.addr[num_pd_disks].slot_number = sdev->id & 0xFF;
+         info.addr[num_pd_disks].scsi_dev_type = sdev->type;
+         info.addr[num_pd_disks].connect_port_bitmap = 0x1;
+         info.addr[num_pd_disks].sas_addr[0] =
+-            cpu_to_le64(megasas_get_sata_addr(sdev_id));
++            cpu_to_le64(megasas_get_sata_addr(pd_id));
+         num_pd_disks++;
+         offset += sizeof(struct mfi_pd_address);
+     }
+@@ -978,7 +981,7 @@ static int megasas_pd_get_info_submit(SC
+     size_t dcmd_size = sizeof(struct mfi_pd_info);
+     BlockConf *conf = &sdev->conf;
+     uint64_t pd_size;
+-    uint16_t sdev_id = ((sdev->id & 0xFF) >> 8) | (lun & 0xFF);
++    uint16_t pd_id = ((sdev->id & 0xFF) << 8) | (lun & 0xFF);
+     uint8_t cmdbuf[6];
+     SCSIRequest *req;
+     size_t len, resid;
+@@ -1034,7 +1037,7 @@ static int megasas_pd_get_info_submit(SC
+         info->fw_state = cpu_to_le16(MFI_PD_STATE_OFFLINE);
+     }
+ 
+-    info->ref.v.device_id = cpu_to_le16(sdev_id);
++    info->ref.v.device_id = cpu_to_le16(pd_id);
+     info->state.ddf.pd_type = cpu_to_le16(MFI_PD_DDF_TYPE_IN_VD|
+                                           MFI_PD_DDF_TYPE_INTF_SAS);
+     bdrv_get_geometry(conf->bs, &pd_size);
+@@ -1045,7 +1048,7 @@ static int megasas_pd_get_info_submit(SC
+     info->slot_number = (sdev->id & 0xFF);
+     info->path_info.count = 1;
+     info->path_info.sas_addr[0] =
+-        cpu_to_le64(megasas_get_sata_addr(sdev_id));
++        cpu_to_le64(megasas_get_sata_addr(pd_id));
+     info->connected_port_bitmap = 0x1;
+     info->device_speed = 1;
+     info->link_speed = 1;
+@@ -1060,6 +1063,7 @@ static int megasas_dcmd_pd_get_info(Mega
+ {
+     size_t dcmd_size = sizeof(struct mfi_pd_info);
+     uint16_t pd_id;
++    uint8_t target_id, lun_id;
+     SCSIDevice *sdev = NULL;
+     int retval = MFI_STAT_DEVICE_NOT_FOUND;
+ 
+@@ -1069,7 +1073,9 @@ static int megasas_dcmd_pd_get_info(Mega
+ 
+     /* mbox0 has the ID */
+     pd_id = le16_to_cpu(cmd->frame->dcmd.mbox[0]);
+-    sdev = scsi_device_find(&s->bus, 0, pd_id, 0);
++    target_id = (pd_id >> 8) & 0xFF;
++    lun_id = pd_id & 0xFF;
++    sdev = scsi_device_find(&s->bus, 0, target_id, lun_id);
+     trace_megasas_dcmd_pd_get_info(cmd->index, pd_id);
+ 
+     if (sdev) {
+@@ -1084,7 +1090,7 @@ static int megasas_dcmd_ld_get_list(Mega
+ {
+     struct mfi_ld_list info;
+     size_t dcmd_size = sizeof(info), resid;
+-    uint32_t num_ld_disks = 0, max_ld_disks = s->fw_luns;
++    uint32_t num_ld_disks = 0, max_ld_disks;
+     uint64_t ld_size;
+     BusChild *kid;
+ 
+@@ -1095,9 +1101,13 @@ static int megasas_dcmd_ld_get_list(Mega
+         return MFI_STAT_INVALID_PARAMETER;
+     }
+ 
++    max_ld_disks = (cmd->iov_size - 8) / 16;
+     if (megasas_is_jbod(s)) {
+         max_ld_disks = 0;
+     }
++    if (max_ld_disks > MFI_MAX_LD) {
++        max_ld_disks = MFI_MAX_LD;
++    }
+     QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
+         SCSIDevice *sdev = DO_UPCAST(SCSIDevice, qdev, kid->child);
+         BlockConf *conf = &sdev->conf;
+@@ -1108,7 +1118,6 @@ static int megasas_dcmd_ld_get_list(Mega
+         /* Logical device size is in blocks */
+         bdrv_get_geometry(conf->bs, &ld_size);
+         info.ld_list[num_ld_disks].ld.v.target_id = sdev->id;
+-        info.ld_list[num_ld_disks].ld.v.lun_id = sdev->lun;
+         info.ld_list[num_ld_disks].state = MFI_LD_STATE_OPTIMAL;
+         info.ld_list[num_ld_disks].size = cpu_to_le64(ld_size);
+         num_ld_disks++;
+@@ -1145,7 +1154,7 @@ static int megasas_ld_get_info_submit(SC
+     SCSIRequest *req;
+     ssize_t len, resid;
+     BlockConf *conf = &sdev->conf;
+-    uint16_t sdev_id = ((sdev->id & 0xFF) >> 8) | (lun & 0xFF);
++    uint16_t sdev_id = ((sdev->id & 0xFF) << 8) | (lun & 0xFF);
+     uint64_t ld_size;
+ 
+     if (!cmd->iov_buf) {
+@@ -1262,7 +1271,7 @@ static int megasas_dcmd_cfg_read(Megasas
+     QTAILQ_FOREACH(kid, &s->bus.qbus.children, sibling) {
+         SCSIDevice *sdev = DO_UPCAST(SCSIDevice, qdev, kid->child);
+         BlockConf *conf = &sdev->conf;
+-        uint16_t sdev_id = ((sdev->id & 0xFF) >> 8) | (sdev->lun & 0xFF);
++        uint16_t sdev_id = ((sdev->id & 0xFF) << 8) | (sdev->lun & 0xFF);
+         struct mfi_array *array;
+         struct mfi_ld_config *ld;
+         uint64_t pd_size;
+@@ -1288,7 +1297,7 @@ static int megasas_dcmd_cfg_read(Megasas
+         array_offset += sizeof(struct mfi_array);
+         ld = (struct mfi_ld_config *)(data + ld_offset);
+         memset(ld, 0, sizeof(struct mfi_ld_config));
+-        ld->properties.ld.v.target_id = (sdev->id & 0xFF);
++        ld->properties.ld.v.target_id = sdev->id;
+         ld->properties.default_cache_policy = MR_LD_CACHE_READ_AHEAD |
+             MR_LD_CACHE_READ_ADAPTIVE;
+         ld->properties.current_cache_policy = MR_LD_CACHE_READ_AHEAD |
+@@ -1576,10 +1585,18 @@ static int megasas_handle_scsi(MegasasSt
+ 
+     cdb = cmd->frame->pass.cdb;
+ 
+-    if (cmd->frame->header.target_id < s->fw_luns) {
+-        sdev = scsi_device_find(&s->bus, 0, cmd->frame->header.target_id,
+-                                cmd->frame->header.lun_id);
++    if (is_logical) {
++        if (cmd->frame->header.target_id >= MFI_MAX_LD ||
++            cmd->frame->header.lun_id != 0) {
++            trace_megasas_scsi_target_not_present(
++                mfi_frame_desc[cmd->frame->header.frame_cmd], is_logical,
++                cmd->frame->header.target_id, cmd->frame->header.lun_id);
++            return MFI_STAT_DEVICE_NOT_FOUND;
++        }
+     }
++    sdev = scsi_device_find(&s->bus, 0, cmd->frame->header.target_id,
++                            cmd->frame->header.lun_id);
++
+     cmd->iov_size = le32_to_cpu(cmd->frame->header.data_len);
+     trace_megasas_handle_scsi(mfi_frame_desc[cmd->frame->header.frame_cmd],
+                               is_logical, cmd->frame->header.target_id,
+@@ -1650,7 +1667,8 @@ static int megasas_handle_io(MegasasStat
+     lba_start_hi = le32_to_cpu(cmd->frame->io.lba_hi);
+     lba_start = ((uint64_t)lba_start_hi << 32) | lba_start_lo;
+ 
+-    if (cmd->frame->header.target_id < s->fw_luns) {
++    if (cmd->frame->header.target_id < MFI_MAX_LD &&
++        cmd->frame->header.lun_id == 0) {
+         sdev = scsi_device_find(&s->bus, 0, cmd->frame->header.target_id,
+                                 cmd->frame->header.lun_id);
+     }
+@@ -2209,8 +2227,12 @@ static int megasas_scsi_init(PCIDevice *
+     }
+     trace_megasas_init(s->fw_sge, s->fw_cmds,
+                        megasas_is_jbod(s) ? "jbod" : "raid");
+-    s->fw_luns = (MFI_MAX_LD > MAX_SCSI_DEVS) ?
+-        MAX_SCSI_DEVS : MFI_MAX_LD;
++
++    if (megasas_is_jbod(s)) {
++        s->fw_luns = MFI_MAX_SYS_PDS;
++    } else {
++        s->fw_luns = MFI_MAX_LD;
++    }
+     s->producer_pa = 0;
+     s->consumer_pa = 0;
+     for (i = 0; i < s->fw_cmds; i++) {
+Index: qemu/hw/scsi/mfi.h
+===================================================================
+--- qemu.orig/hw/scsi/mfi.h
++++ qemu/hw/scsi/mfi.h
+@@ -1094,7 +1094,7 @@ struct mfi_pd_list {
+ union mfi_ld_ref {
+     struct {
+         uint8_t target_id;
+-        uint8_t lun_id;
++        uint8_t reserved;
+         uint16_t seq;
+     } v;
+     uint32_t ref;
diff -Nru qemu-2.1+dfsg/debian/patches/series qemu-2.1+dfsg/debian/patches/series
--- qemu-2.1+dfsg/debian/patches/series	2016-05-08 15:35:16.000000000 +0200
+++ qemu-2.1+dfsg/debian/patches/series	2018-07-29 15:33:43.000000000 +0200
@@ -102,3 +102,108 @@
 vga-factor-out-vga-register-setup.patch
 vga-update-vga-register-setup-on-vbe-changes.patch
 vga-make-sure-vga-register-setup-for-vbe-stays-intac.patch
+
+CVE-2016-2198-usb-ehci-add-capability-mmio-write-function.patch
+CVE-2016-6833-vmxnet3-check-for-device_active-before-write.patch
+CVE-2016-6835-net-vmxnet-check-IP-header-length.patch
+CVE-2016-8576-fix-infinite-loop.patch
+CVE-2016-8667.patch
+CVE-2016-8669.patch
+CVE-2016-9602-1.patch
+CVE-2016-9602-2.patch
+CVE-2016-9602-3.patch
+CVE-2016-9602-4.patch
+CVE-2016-9602-5.patch
+CVE-2016-9602-6.patch
+CVE-2016-9602-7.patch
+CVE-2016-9602-8.patch
+CVE-2016-9602-9.patch
+CVE-2016-9602-10.patch
+CVE-2016-9602-11.patch
+CVE-2016-9602-12.patch
+CVE-2016-9602-13.patch
+CVE-2016-9602-14.patch
+CVE-2016-9602-15.patch
+CVE-2016-9602-16.patch
+CVE-2016-9602-17.patch
+CVE-2016-9602-18.patch
+CVE-2016-9602-19.patch
+CVE-2016-9602-20.patch
+CVE-2016-9602-21.patch
+CVE-2016-9602-22.patch
+CVE-2016-9602-23.patch
+CVE-2016-9602-24.patch
+CVE-2016-9602-25.patch
+CVE-2016-9602-26.patch
+CVE-2016-9602-27.patch
+CVE-2016-9602-28.patch
+CVE-2016-9602-29.patch
+CVE-2016-9602-pre.patch
+CVE-2016-9603-cirrus-vnc-zap-bitblit-support-from-console-code.patch
+#display-cirrus-ignore-source-pitch-value-as-needed-in-bli.patch
+CVE-2017-7471.patch
+CVE-2016-9776.patch
+CVE-2016-9907.patch
+CVE-2016-9911.patch
+CVE-2016-9914-1.patch
+CVE-2016-9914-2.patch
+CVE-2016-9915.patch
+CVE-2016-9916.patch
+CVE-2016-9921-9922.patch
+CVE-2016-10155.patch
+CVE-2017-2620-pre.patch
+CVE-2017-2620-cirrus-add-blit_is_unsafe-call-to-cirrus_bi.patch
+0001-cirrus-fix-oob-access-issue-CVE-2017-2615.patch
+CVE-2017-5525.patch
+CVE-2017-5526.patch
+CVE-2017-5579.patch
+CVE-2017-5667.patch
+CVE-2017-5715-1.patch
+CVE-2017-5715-2.patch
+CVE-2017-5715-3pre1.patch
+CVE-2017-5715-3.patch
+CVE-2017-5715-4.patch
+CVE-2017-5715-5.patch
+CVE-2017-5856.patch
+CVE-2017-5987-1.patch
+CVE-2017-5987-2.patch
+CVE-2017-5987-3.patch
+CVE-2017-5987-4.patch
+CVE-2017-5973.patch
+CVE-2017-6505.patch
+CVE-2017-7377.patch
+CVE-2017-7493.patch
+CVE-2017-7718.patch
+CVE-2017-7980-1-CVE-2017-18030.patch
+CVE-2017-7980-2.patch
+CVE-2017-7980-3.patch
+CVE-2017-7980-4.patch
+CVE-2017-7980-5.patch
+CVE-2017-7980-6.patch
+CVE-2017-7980-7.patch
+CVE-2017-8086.patch
+CVE-2017-8112.patch
+CVE-2017-8309-audio-release-capture-buffers.patch
+CVE-2017-8379-1.patch
+CVE-2017-8379-2.patch
+CVE-2017-9330.patch
+CVE-2017-9373-1.patch
+CVE-2017-9373-2.patch
+CVE-2017-9374.patch
+CVE-2017-9503-pre1.patch
+CVE-2017-9503-1.patch
+CVE-2017-9503-2.patch
+CVE-2017-9503-3.patch
+CVE-2017-9503-4.patch
+CVE-2017-9503-5.patch
+CVE-2017-9503-6.patch
+CVE-2017-9503-7.patch
+CVE-2017-10664-Ignore-SIGPIPE.patch
+CVE-2017-10806.patch
+xen-disk-don-t-leak-stack-data-via-response-ring-CVE-2017-10911.patch
+CVE-2017-11434-slirp-check-len-against-dhcp-options-array.patch
+CVE-2017-14167-multiboot-validate-multiboot-header-addres.patch
+CVE-2017-15038-9pfs-use-g_malloc0-to-allocate-space-for-x.patch
+CVE-2017-15289.patch
+CVE-2017-16845.patch
+CVE-2017-18043.patch
diff -Nru qemu-2.1+dfsg/debian/patches/xen-disk-don-t-leak-stack-data-via-response-ring-CVE-2017-10911.patch qemu-2.1+dfsg/debian/patches/xen-disk-don-t-leak-stack-data-via-response-ring-CVE-2017-10911.patch
--- qemu-2.1+dfsg/debian/patches/xen-disk-don-t-leak-stack-data-via-response-ring-CVE-2017-10911.patch	1970-01-01 01:00:00.000000000 +0100
+++ qemu-2.1+dfsg/debian/patches/xen-disk-don-t-leak-stack-data-via-response-ring-CVE-2017-10911.patch	2018-07-26 19:12:18.000000000 +0200
@@ -0,0 +1,73 @@
+Origin: backported, https://salsa.debian.org/qemu-team/qemu/commit/c1863320f25f3e3a5d3d3b0fec793ae983a9ea5c
+Reviewed-by: Santiago R.R. <santiagorr@riseup.net>
+Bug-Debian: 869706
+
+From: Stefano Stabellini <sstabellini@kernel.org>
+Date: Tue, 27 Jun 2017 14:45:34 -0700
+Subject: xen/disk: don't leak stack data via response ring
+Commit-Id: b0ac694fdb9113b973048ebe5619927e74965f61
+Bug: https://xenbits.xen.org/xsa/advisory-216.html
+
+Rather than constructing a local structure instance on the stack, fill
+the fields directly on the shared ring, just like other (Linux)
+backends do. Build on the fact that all response structure flavors are
+actually identical (aside from alignment and padding at the end).
+
+This is XSA-216.
+
+Reported by: Anthony Perard <anthony.perard@citrix.com>
+Signed-off-by: Jan Beulich <jbeulich@suse.com>
+Signed-off-by: Stefano Stabellini <sstabellini@kernel.org>
+Acked-by: Anthony PERARD <anthony.perard@citrix.com>
+---
+ hw/block/xen_disk.c | 25 ++++++++++++-------------
+ 1 file changed, 12 insertions(+), 13 deletions(-)
+
+Index: qemu/hw/block/xen_disk.c
+===================================================================
+--- qemu.orig/hw/block/xen_disk.c
++++ qemu/hw/block/xen_disk.c
+@@ -609,30 +609,30 @@ static int blk_send_response_one(struct
+     struct XenBlkDev  *blkdev = ioreq->blkdev;
+     int               send_notify   = 0;
+     int               have_requests = 0;
+-    blkif_response_t  resp;
+-    void              *dst;
+-
+-    resp.id        = ioreq->req.id;
+-    resp.operation = ioreq->req.operation;
+-    resp.status    = ioreq->status;
++    blkif_response_t  *resp;
+ 
+     /* Place on the response ring for the relevant domain. */
+     switch (blkdev->protocol) {
+     case BLKIF_PROTOCOL_NATIVE:
+-        dst = RING_GET_RESPONSE(&blkdev->rings.native, blkdev->rings.native.rsp_prod_pvt);
++        resp = (blkif_response_t *) RING_GET_RESPONSE(&blkdev->rings.native,
++                                 blkdev->rings.native.rsp_prod_pvt);
+         break;
+     case BLKIF_PROTOCOL_X86_32:
+-        dst = RING_GET_RESPONSE(&blkdev->rings.x86_32_part,
+-                                blkdev->rings.x86_32_part.rsp_prod_pvt);
++        resp = (blkif_response_t *) RING_GET_RESPONSE(&blkdev->rings.x86_32_part,
++                                 blkdev->rings.x86_32_part.rsp_prod_pvt);
+         break;
+     case BLKIF_PROTOCOL_X86_64:
+-        dst = RING_GET_RESPONSE(&blkdev->rings.x86_64_part,
+-                                blkdev->rings.x86_64_part.rsp_prod_pvt);
++        resp = (blkif_response_t *) RING_GET_RESPONSE(&blkdev->rings.x86_64_part,
++                                 blkdev->rings.x86_64_part.rsp_prod_pvt);
+         break;
+     default:
+-        dst = NULL;
++        return 0;
+     }
+-    memcpy(dst, &resp, sizeof(resp));
++
++    resp->id        = ioreq->req.id;
++    resp->operation = ioreq->req.operation;
++    resp->status    = ioreq->status;
++
+     blkdev->rings.common.rsp_prod_pvt++;
+ 
+     RING_PUSH_RESPONSES_AND_CHECK_NOTIFY(&blkdev->rings.common, send_notify);

Attachment: signature.asc
Description: PGP signature


Reply to: