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

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



Hi,
On Tue, Jul 31, 2018 at 10:00:21PM +0200, Santiago R.R. wrote:
> 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?

Looks good to me! Being a 2.x QEMU the code base much better matches
current upstream (which makes patching e.g. cirrus or 9pfs (which show
up in the CVE list quite often much nicer) and applying resource
management fixes (for DoS) actually makes sense (which wasn't the case
for wheezy since resource cleanup was missing in lots of places).

While looking at these I noticed Ubuntu patches CVE-2018-3639 in their
2.0 branch which is not marked as affecting QEMU in Debian which is
likely an omission.

Cheers,
 -- Guido


> 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);






Reply to: