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