diff -Nru qemu-2.0.0~rc1+dfsg/block/bochs.c qemu-2.0.0+dfsg/block/bochs.c --- qemu-2.0.0~rc1+dfsg/block/bochs.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/block/bochs.c 2014-04-17 14:26:43.000000000 +0000 @@ -148,16 +148,26 @@ s->extent_blocks = 1 + (le32_to_cpu(bochs.extent) - 1) / 512; s->extent_size = le32_to_cpu(bochs.extent); - if (s->extent_size == 0) { - error_setg(errp, "Extent size may not be zero"); - return -EINVAL; + if (s->extent_size < BDRV_SECTOR_SIZE) { + /* bximage actually never creates extents smaller than 4k */ + error_setg(errp, "Extent size must be at least 512"); + ret = -EINVAL; + goto fail; + } else if (!is_power_of_2(s->extent_size)) { + error_setg(errp, "Extent size %" PRIu32 " is not a power of two", + s->extent_size); + ret = -EINVAL; + goto fail; } else if (s->extent_size > 0x800000) { error_setg(errp, "Extent size %" PRIu32 " is too large", s->extent_size); - return -EINVAL; + ret = -EINVAL; + goto fail; } - if (s->catalog_size < bs->total_sectors / s->extent_size) { + if (s->catalog_size < DIV_ROUND_UP(bs->total_sectors, + s->extent_size / BDRV_SECTOR_SIZE)) + { error_setg(errp, "Catalog size is too small for this disk size"); ret = -EINVAL; goto fail; diff -Nru qemu-2.0.0~rc1+dfsg/block/iscsi.c qemu-2.0.0+dfsg/block/iscsi.c --- qemu-2.0.0~rc1+dfsg/block/iscsi.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/block/iscsi.c 2014-04-17 14:26:43.000000000 +0000 @@ -1101,8 +1101,10 @@ return task; fail: - error_setg(errp, "iSCSI: Inquiry command failed : %s", - iscsi_get_error(iscsi)); + if (!error_is_set(errp)) { + error_setg(errp, "iSCSI: Inquiry command failed : %s", + iscsi_get_error(iscsi)); + } if (task != NULL) { scsi_free_scsi_task(task); } @@ -1231,6 +1233,7 @@ iscsi_readcapacity_sync(iscsilun, &local_err); if (local_err != NULL) { error_propagate(errp, local_err); + ret = -EINVAL; goto out; } bs->total_sectors = sector_lun2qemu(iscsilun->num_blocks, iscsilun); diff -Nru qemu-2.0.0~rc1+dfsg/block/qcow2.c qemu-2.0.0+dfsg/block/qcow2.c --- qemu-2.0.0~rc1+dfsg/block/qcow2.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/block/qcow2.c 2014-04-17 14:26:43.000000000 +0000 @@ -269,12 +269,15 @@ BDRVQcowState *s = bs->opaque; if (s->incompatible_features & QCOW2_INCOMPAT_DIRTY) { - int ret = bdrv_flush(bs); + int ret; + + s->incompatible_features &= ~QCOW2_INCOMPAT_DIRTY; + + ret = bdrv_flush(bs); if (ret < 0) { return ret; } - s->incompatible_features &= ~QCOW2_INCOMPAT_DIRTY; return qcow2_update_header(bs); } return 0; @@ -900,11 +903,25 @@ return 0; } -/* We have nothing to do for QCOW2 reopen, stubs just return - * success */ +/* We have no actual commit/abort logic for qcow2, but we need to write out any + * unwritten data if we reopen read-only. */ static int qcow2_reopen_prepare(BDRVReopenState *state, BlockReopenQueue *queue, Error **errp) { + int ret; + + if ((state->flags & BDRV_O_RDWR) == 0) { + ret = bdrv_flush(state->bs); + if (ret < 0) { + return ret; + } + + ret = qcow2_mark_clean(state->bs); + if (ret < 0) { + return ret; + } + } + return 0; } diff -Nru qemu-2.0.0~rc1+dfsg/block/qcow2-cluster.c qemu-2.0.0+dfsg/block/qcow2-cluster.c --- qemu-2.0.0~rc1+dfsg/block/qcow2-cluster.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/block/qcow2-cluster.c 2014-04-17 14:26:43.000000000 +0000 @@ -491,6 +491,7 @@ break; case QCOW2_CLUSTER_ZERO: if (s->qcow_version < 3) { + qcow2_cache_put(bs, s->l2_table_cache, (void**) &l2_table); return -EIO; } c = count_contiguous_clusters(nb_clusters, s->cluster_size, diff -Nru qemu-2.0.0~rc1+dfsg/block.c qemu-2.0.0+dfsg/block.c --- qemu-2.0.0~rc1+dfsg/block.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/block.c 2014-04-17 14:26:43.000000000 +0000 @@ -767,6 +767,11 @@ { int open_flags = flags | BDRV_O_CACHE_WB; + /* The backing file of a temporary snapshot is read-only */ + if (flags & BDRV_O_SNAPSHOT) { + open_flags &= ~BDRV_O_RDWR; + } + /* * Clear flags that are internal to the block layer before opening the * image. @@ -968,7 +973,7 @@ { BlockDriver *drv; const char *drvname; - bool allow_protocol_prefix = false; + bool parse_filename = false; Error *local_err = NULL; int ret; @@ -977,7 +982,7 @@ filename = qdict_get_try_str(*options, "filename"); } else if (filename && !qdict_haskey(*options, "filename")) { qdict_put(*options, "filename", qstring_from_str(filename)); - allow_protocol_prefix = true; + parse_filename = true; } else { error_setg(errp, "Can't specify 'file' and 'filename' options at the " "same time"); @@ -994,7 +999,7 @@ } qdict_del(*options, "driver"); } else if (filename) { - drv = bdrv_find_protocol(filename, allow_protocol_prefix); + drv = bdrv_find_protocol(filename, parse_filename); if (!drv) { error_setg(errp, "Unknown protocol"); } @@ -1010,7 +1015,7 @@ } /* Parse the filename and open it */ - if (drv->bdrv_parse_filename && filename) { + if (drv->bdrv_parse_filename && parse_filename) { drv->bdrv_parse_filename(filename, *options, &local_err); if (local_err) { error_propagate(errp, local_err); @@ -1162,6 +1167,73 @@ return ret; } +void bdrv_append_temp_snapshot(BlockDriverState *bs, Error **errp) +{ + /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ + char tmp_filename[PATH_MAX + 1]; + + int64_t total_size; + BlockDriver *bdrv_qcow2; + QEMUOptionParameter *create_options; + QDict *snapshot_options; + BlockDriverState *bs_snapshot; + Error *local_err; + int ret; + + /* if snapshot, we create a temporary backing file and open it + instead of opening 'filename' directly */ + + /* Get the required size from the image */ + total_size = bdrv_getlength(bs); + if (total_size < 0) { + error_setg_errno(errp, -total_size, "Could not get image size"); + return; + } + total_size &= BDRV_SECTOR_MASK; + + /* Create the temporary image */ + ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename)); + if (ret < 0) { + error_setg_errno(errp, -ret, "Could not get temporary filename"); + return; + } + + bdrv_qcow2 = bdrv_find_format("qcow2"); + create_options = parse_option_parameters("", bdrv_qcow2->create_options, + NULL); + + set_option_parameter_int(create_options, BLOCK_OPT_SIZE, total_size); + + ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options, &local_err); + free_option_parameters(create_options); + if (ret < 0) { + error_setg_errno(errp, -ret, "Could not create temporary overlay " + "'%s': %s", tmp_filename, + error_get_pretty(local_err)); + error_free(local_err); + return; + } + + /* Prepare a new options QDict for the temporary file */ + snapshot_options = qdict_new(); + qdict_put(snapshot_options, "file.driver", + qstring_from_str("file")); + qdict_put(snapshot_options, "file.filename", + qstring_from_str(tmp_filename)); + + bs_snapshot = bdrv_new(""); + bs_snapshot->is_temporary = 1; + + ret = bdrv_open(&bs_snapshot, NULL, NULL, snapshot_options, + bs->open_flags & ~BDRV_O_SNAPSHOT, bdrv_qcow2, &local_err); + if (ret < 0) { + error_propagate(errp, local_err); + return; + } + + bdrv_append(bs_snapshot, bs); +} + /* * Opens a disk image (raw, qcow2, vmdk, ...) * @@ -1182,8 +1254,6 @@ BlockDriver *drv, Error **errp) { int ret; - /* TODO: extra byte is a hack to ensure MAX_PATH space on Windows. */ - char tmp_filename[PATH_MAX + 1]; BlockDriverState *file = NULL, *bs; const char *drvname; Error *local_err = NULL; @@ -1243,74 +1313,6 @@ } } - /* For snapshot=on, create a temporary qcow2 overlay */ - if (flags & BDRV_O_SNAPSHOT) { - BlockDriverState *bs1; - int64_t total_size; - BlockDriver *bdrv_qcow2; - QEMUOptionParameter *create_options; - QDict *snapshot_options; - - /* if snapshot, we create a temporary backing file and open it - instead of opening 'filename' directly */ - - /* Get the required size from the image */ - QINCREF(options); - bs1 = NULL; - ret = bdrv_open(&bs1, filename, NULL, options, BDRV_O_NO_BACKING, - drv, &local_err); - if (ret < 0) { - goto fail; - } - total_size = bdrv_getlength(bs1) & BDRV_SECTOR_MASK; - - bdrv_unref(bs1); - - /* Create the temporary image */ - ret = get_tmp_filename(tmp_filename, sizeof(tmp_filename)); - if (ret < 0) { - error_setg_errno(errp, -ret, "Could not get temporary filename"); - goto fail; - } - - bdrv_qcow2 = bdrv_find_format("qcow2"); - create_options = parse_option_parameters("", bdrv_qcow2->create_options, - NULL); - - set_option_parameter_int(create_options, BLOCK_OPT_SIZE, total_size); - - ret = bdrv_create(bdrv_qcow2, tmp_filename, create_options, &local_err); - free_option_parameters(create_options); - if (ret < 0) { - error_setg_errno(errp, -ret, "Could not create temporary overlay " - "'%s': %s", tmp_filename, - error_get_pretty(local_err)); - error_free(local_err); - local_err = NULL; - goto fail; - } - - /* Prepare a new options QDict for the temporary file, where user - * options refer to the backing file */ - if (filename) { - qdict_put(options, "file.filename", qstring_from_str(filename)); - } - if (drv) { - qdict_put(options, "driver", qstring_from_str(drv->format_name)); - } - - snapshot_options = qdict_new(); - qdict_put(snapshot_options, "backing", options); - qdict_flatten(snapshot_options); - - bs->options = snapshot_options; - options = qdict_clone_shallow(bs->options); - - filename = tmp_filename; - drv = bdrv_qcow2; - bs->is_temporary = 1; - } - /* Open image file without format layer */ if (flags & BDRV_O_RDWR) { flags |= BDRV_O_ALLOW_RDWR; @@ -1372,6 +1374,17 @@ } } + /* For snapshot=on, create a temporary qcow2 overlay. bs points to the + * temporary snapshot afterwards. */ + if (flags & BDRV_O_SNAPSHOT) { + bdrv_append_temp_snapshot(bs, &local_err); + if (local_err) { + error_propagate(errp, local_err); + goto close_and_fail; + } + } + + done: /* Check if any unknown options were used */ if (options && (qdict_size(options) != 0)) { diff -Nru qemu-2.0.0~rc1+dfsg/blockdev.c qemu-2.0.0+dfsg/blockdev.c --- qemu-2.0.0~rc1+dfsg/blockdev.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/blockdev.c 2014-04-17 14:26:43.000000000 +0000 @@ -1876,6 +1876,10 @@ */ BlockdevOnError on_error = BLOCKDEV_ON_ERROR_REPORT; + if (!has_speed) { + speed = 0; + } + /* drain all i/o before commits */ bdrv_drain_all(); diff -Nru qemu-2.0.0~rc1+dfsg/configure qemu-2.0.0+dfsg/configure --- qemu-2.0.0~rc1+dfsg/configure 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/configure 2014-04-17 14:26:43.000000000 +0000 @@ -1448,7 +1448,10 @@ if test "$stack_protector" != "no" ; then gcc_flags="-fstack-protector-strong -fstack-protector-all" for flag in $gcc_flags; do - if compile_prog "-Werror $flag" "" ; then + # We need to check both a compile and a link, since some compiler + # setups fail only on a .c->.o compile and some only at link time + if do_cc $QEMU_CFLAGS -Werror $flag -c -o $TMPO $TMPC && + compile_prog "-Werror $flag" ""; then QEMU_CFLAGS="$QEMU_CFLAGS $flag" LIBTOOLFLAGS="$LIBTOOLFLAGS -Wc,$flag" break diff -Nru qemu-2.0.0~rc1+dfsg/cpu-exec.c qemu-2.0.0+dfsg/cpu-exec.c --- qemu-2.0.0~rc1+dfsg/cpu-exec.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/cpu-exec.c 2014-04-17 14:26:43.000000000 +0000 @@ -227,6 +227,8 @@ TranslationBlock *tb; uint8_t *tc_ptr; uintptr_t next_tb; + /* This must be volatile so it is not trashed by longjmp() */ + volatile bool have_tb_lock = false; if (cpu->halted) { if (!cpu_has_work(cpu)) { @@ -600,6 +602,7 @@ cpu_loop_exit(cpu); } spin_lock(&tcg_ctx.tb_ctx.tb_lock); + have_tb_lock = true; tb = tb_find_fast(env); /* Note: we do it here to avoid a gcc bug on Mac OS X when doing it in tb_find_slow */ @@ -621,6 +624,7 @@ tb_add_jump((TranslationBlock *)(next_tb & ~TB_EXIT_MASK), next_tb & TB_EXIT_MASK, tb); } + have_tb_lock = false; spin_unlock(&tcg_ctx.tb_ctx.tb_lock); /* cpu_interrupt might be called while translating the @@ -692,6 +696,10 @@ #ifdef TARGET_I386 x86_cpu = X86_CPU(cpu); #endif + if (have_tb_lock) { + spin_unlock(&tcg_ctx.tb_ctx.tb_lock); + have_tb_lock = false; + } } } /* for(;;) */ diff -Nru qemu-2.0.0~rc1+dfsg/debian/changelog qemu-2.0.0+dfsg/debian/changelog --- qemu-2.0.0~rc1+dfsg/debian/changelog 2014-04-09 14:29:33.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/changelog 2019-05-09 07:01:32.000000000 +0000 @@ -1,3 +1,1154 @@ +qemu (2.0.0+dfsg-2ubuntu1.46) trusty-security; urgency=medium + + * SECURITY UPDATE: Add support for exposing md-clear functionality + to guests + - d/p/ubuntu/enable-md-clear.patch + - CVE-2018-12126, CVE-2018-12127, CVE-2018-12130, CVE-2019-11091 + * SECURITY UPDATE: heap overflow when loading device tree blob + - d/p/ubuntu/CVE-2018-20815.patch: specify how large the buffer to + copy the device tree blob into is. + - d/p/ubuntu/CVE-2018-20815-prereq-1.patch: Add load_image_size() + to replace load_image() + - d/p/ubuntu/CVE-2018-20815-prereq-2.patch: Read as long as possible + in load_image_size() + - CVE-2018-20815 + * SECURITY UPDATE: information leak in SLiRP + - d/p/ubuntu/CVE-2019-9824.patch: check sscanf result when + emulating ident. + - CVE-2019-9824 + + -- Steve Beattie Wed, 08 May 2019 23:59:48 -0700 + +qemu (2.0.0+dfsg-2ubuntu1.45) trusty-security; urgency=medium + + * SECURITY UPDATE: race during file renaming in v9fs_wstat + - debian/patches/CVE-2018-19489.patch: add locks to hw/9pfs/9p.c. + - CVE-2018-19489 + * SECURITY UPDATE: heap based buffer overflow in slirp + - debian/patches/CVE-2019-6778.patch: check data length while emulating + ident function in slirp/tcp_subr.c. + - CVE-2019-6778 + + -- Marc Deslauriers Fri, 22 Mar 2019 17:08:37 -0400 + +qemu (2.0.0+dfsg-2ubuntu1.44) trusty-security; urgency=medium + + * SECURITY UPDATE: integer overflow in NE2000 NIC emulation + - debian/patches/CVE-2018-10839.patch: use proper type in + hw/net/ne2000.c. + - CVE-2018-10839 + * SECURITY UPDATE: buffer overflow via incoming fragmented datagrams + - debian/patches/CVE-2018-11806.patch: correct size computation in + slirp/mbuf.c, slirp/mbuf.h. + - CVE-2018-11806 + * SECURITY UPDATE: integer overflow via crafted QMP command + - debian/patches/CVE-2018-12617.patch: check bytes count read by + guest-file-read in qga/commands-posix.c. + - CVE-2018-12617 + * SECURITY UPDATE: buffer overflow in rtl8139 + - debian/patches/CVE-2018-17958.patch: use proper type in + hw/net/rtl8139.c. + - CVE-2018-17958 + * SECURITY UPDATE: buffer overflow in pcnet + - debian/patches/CVE-2018-17962.patch: use proper type in + hw/net/pcnet.c. + - CVE-2018-17962 + * SECURITY UPDATE: DoS via large packet sizes + - debian/patches/CVE-2018-17963.patch: check size in net/net.c. + - CVE-2018-17963 + * SECURITY UPDATE: DoS in lsi53c895a + - debian/patches/CVE-2018-18849.patch: check message length value is + valid in hw/scsi/lsi53c895a.c. + - CVE-2018-18849 + * SECURITY UPDATE: race condition in 9p + - debian/patches/CVE-2018-19364-1.patch: use write lock in + hw/9pfs/cofile.c. + - debian/patches/CVE-2018-19364-2.patch: use write lock in + hw/9pfs/virtio-9p.c. + - CVE-2018-19364 + + -- Marc Deslauriers Wed, 21 Nov 2018 15:10:13 -0500 + +qemu (2.0.0+dfsg-2ubuntu1.43) trusty-security; urgency=medium + + * SECURITY UPDATE: Speculative Store Bypass + - debian/patches/CVE-2018-3639-2.patch: define the AMD 'virt-ssbd' + CPUID feature bit in target/i386/cpu.c. + - debian/patches/CVE-2018-3639-3.patch: define the Virt SSBD MSR and + handling of it in target/i386/cpu.h, target/i386/kvm.c, + target/i386/machine.c. + - CVE-2018-3639 + + -- Marc Deslauriers Wed, 23 May 2018 08:03:09 -0400 + +qemu (2.0.0+dfsg-2ubuntu1.42) trusty-security; urgency=medium + + * SECURITY UPDATE: Speculative Store Bypass + - debian/patches/ubuntu/CVE-2018-3639.patch: add bit(2) of SPEC_CTRL + MSR support - Reduced Data Speculation to target-i386/cpu.*. + - CVE-2018-3639 + + -- Marc Deslauriers Thu, 17 May 2018 10:09:16 -0400 + +qemu (2.0.0+dfsg-2ubuntu1.41) trusty-security; urgency=medium + + * SECURITY UPDATE: arbitrary code execution via load_multiboot + - debian/patches/CVE-2018-7550.patch: handle bss_end_addr being zero in + hw/i386/multiboot.c. + - CVE-2018-7550 + + -- Marc Deslauriers Fri, 11 May 2018 13:35:08 -0400 + +qemu (2.0.0+dfsg-2ubuntu1.40) trusty-security; urgency=medium + + * SECURITY REGRESSION: Xen regression (LP: #1752761) + - debian/patches/CVE-2017-11334-1.patch: removed. + - debian/patches/CVE-2017-11334-2.patch: removed. + + -- Marc Deslauriers Sun, 04 Mar 2018 10:11:19 -0500 + +qemu (2.0.0+dfsg-2ubuntu1.39) trusty-security; urgency=medium + + * SECURITY UPDATE: DoS via guest ram block area + - debian/patches/CVE-2017-11334-1.patch: use qemu_ram_ptr_length to + access guest ram in exec.c. + - debian/patches/CVE-2017-11334-2.patch: add lock parameter to + qemu_ram_ptr_length in exec.c. + - CVE-2017-11334 + * SECURITY UPDATE: code execution via multiboot out-of-bounds write + - debian/patches/CVE-2017-14167.patch: validate multiboot header + address values in hw/i386/multiboot.c. + - CVE-2017-14167 + * SECURITY UPDATE: information disclosure via race in 9pfs + - debian/patches/CVE-2017-15038.patch: use g_malloc0 to allocate space + for xattr in hw/9pfs/virtio-9p.c. + - CVE-2017-15038 + * SECURITY UPDATE: DoS in cirrus driver + - debian/patches/CVE-2017-15289.patch: fix oob access in mode4and5 + write functions in hw/display/cirrus_vga.c. + - CVE-2017-15289 + * SECURITY UPDATE: DoS via integer overflow in ROUND_UP + - debian/patches/CVE-2017-18043.patch: fix ROUND_UP in + include/qemu/osdep.h. + - CVE-2017-18043 + * SECURITY UPDATE: DoS in VGA driver + - debian/patches/CVE-2018-5683.patch: check the validation of memory + addr when draw text in hw/display/vga.c. + - CVE-2018-5683 + + -- Marc Deslauriers Thu, 15 Feb 2018 13:33:14 -0500 + +qemu (2.0.0+dfsg-2ubuntu1.38) trusty-security; urgency=medium + + * SECURITY UPDATE: Add support for Spectre mitigations (LP: #1744882) + - debian/patches/CVE-2017-5715-1.patch: Lengthen X86CPUDefinition:: + model_id in target-i386/cpu.c. + - debian/patches/CVE-2017-5715-2.patch: Add support for SPEC_CTRL MSR + in target-i386/cpu.h, target-i386/kvm.c, target-i386/machine.c. + - debian/patches/CVE-2017-5715-3pre1.patch: add FEAT_7_0_ECX and + FEAT_7_0_EDX in target-i386/cpu.c, target-i386/cpu.h. + - debian/patches/CVE-2017-5715-3.patch: Add spec-ctrl CPUID bit in + target-i386/cpu.c, target-i386/cpu.h. + - debian/patches/CVE-2017-5715-4.patch: Add FEAT_8000_0008_EBX CPUID + feature word in target-i386/cpu.c, target-i386/cpu.h. + - debian/patches/CVE-2017-5715-5.patch: Add new -IBRS versions of Intel + CPU models in target-i386/cpu.c. + - CVE-2017-5715 + + -- Marc Deslauriers Thu, 01 Feb 2018 13:27:00 -0500 + +qemu (2.0.0+dfsg-2ubuntu1.36) trusty-security; urgency=medium + + * SECURITY REGRESSION: regression in in USB xHCI emulation (LP: #1718222) + - debian/patches/CVE-2017-9375-regression.patch: don't kick in + xhci_submit and xhci_fire_ctl_transfer in hw/usb/hcd-xhci.c. + + -- Marc Deslauriers Wed, 20 Sep 2017 07:27:30 -0400 + +qemu (2.0.0+dfsg-2ubuntu1.35) trusty-security; urgency=medium + + * SECURITY UPDATE: privilege escalation via virtFS + - debian/patches/CVE-2017-7493.patch: forbid client access to metadata + in hw/9pfs/virtio-9p-local.c. + - CVE-2017-7493 + * SECURITY UPDATE: DoS via message ring page count + - debian/patches/CVE-2017-8112.patch: check page count in + hw/scsi/vmw_pvscsi.c. + - CVE-2017-8112 + * SECURITY UPDATE: DoS in USB OHCI emulation + - debian/patches/CVE-2017-9330.patch: fix error code in + hw/usb/hcd-ohci.c. + - CVE-2017-9330 + * SECURITY UPDATE: DoS in IDE AHCI emulation + - debian/patches/CVE-2017-9373-1.patch: add cleanup function in + hw/ide/core.c, hw/ide/internal.h. + - debian/patches/CVE-2017-9373-2.patch: call cleanup function in + hw/ide/ahci.c. + - CVE-2017-9373 + * SECURITY UPDATE: DoS in USB EHCI emulation + - debian/patches/CVE-2017-9374.patch: fix memory leak in + hw/usb/hcd-ehci-pci.c, hw/usb/hcd-ehci.c, hw/usb/hcd-ehci.h. + - CVE-2017-9374 + * SECURITY UPDATE: DoS in USB xHCI emulation + - debian/patches/CVE-2017-9375.patch: guard against recursive calls in + hw/usb/hcd-xhci.c. + - CVE-2017-9375 + * SECURITY UPDATE: DoS in MegaSAS + - debian/patches/CVE-2017-9503-pre1.patch: fixup device mapping in + hw/scsi/megasas.c, hw/scsi/mfi.h. + - debian/patches/CVE-2017-9503-1.patch: add test to + tests/Makefile, tests/megasas-test.c. + - debian/patches/CVE-2017-9503-2.patch: do not read sense length more + than once in hw/scsi/megasas.c. + - debian/patches/CVE-2017-9503-3.patch: do not read iovec count more + than once in hw/scsi/megasas.c. + - debian/patches/CVE-2017-9503-4.patch: do not read DCMD opcode more + than once in hw/scsi/megasas.c. + - debian/patches/CVE-2017-9503-5.patch: do not read command more than + once in hw/scsi/megasas.c. + - debian/patches/CVE-2017-9503-6.patch: do not read SCSI req parameters + more than once in hw/scsi/megasas.c. + - debian/patches/CVE-2017-9503-7.patch: always store SCSIRequest* into + MegasasCmd in hw/scsi/megasas.c, added test to tests/megasas-test.c. + - CVE-2017-9503 + * SECURITY UPDATE: DoS via incorrect SIGPIPE handling + - debian/patches/CVE-2017-10664.patch: ignore SIGPIPE in qemu-nbd.c. + - CVE-2017-10664 + * SECURITY UPDATE: stack overflow in usbredir_log_data + - debian/patches/CVE-2017-10806.patch: use qemu_hexdump in + hw/usb/redirect.c. + - CVE-2017-10806 + * SECURITY UPDATE: memory disclosure in Xen block-interface responses + - debian/patches/CVE-2017-10911.patch: fill the fields directly in + hw/block/xen_disk.c. + - CVE-2017-10911 + * SECURITY UPDATE: DoS via crafted DHCP options string + - debian/patches/CVE-2017-11434.patch: check length in slirp/bootp.c. + - CVE-2017-11434 + + -- Marc Deslauriers Tue, 22 Aug 2017 12:38:28 -0400 + +qemu (2.0.0+dfsg-2ubuntu1.34) trusty-security; urgency=medium + + * SECURITY UPDATE: denial of service via leak in virtFS + - debian/patches/CVE-2017-7377.patch: fix file descriptor leak in + hw/9pfs/virtio-9p.c. + - CVE-2017-7377 + * SECURITY UPDATE: denial of service in cirrus_vga + - debian/patches/CVE-2017-7718.patch: check parameters in + hw/display/cirrus_vga_rop.h. + - CVE-2017-7718 + * SECURITY UPDATE: code execution via cirrus_vga OOB r/w + - debian/patches/CVE-2017-7980-1.patch: handle negative pitch in + hw/display/cirrus_vga.c. + - debian/patches/CVE-2017-7980-2.patch: allow zero source pitch in + hw/display/cirrus_vga.c. + - debian/patches/CVE-2017-7980-3.patch: fix blit address mask handling + in hw/display/cirrus_vga.c. + - debian/patches/CVE-2017-7980-4.patch: fix patterncopy checks in + hw/display/cirrus_vga.c. + - debian/patches/CVE-2017-7980-5.patch: revert allow zero source pitch + in hw/display/cirrus_vga.c. + - debian/patches/CVE-2017-7980-6.patch: stop passing around dst + pointers in hw/display/cirrus_vga.c, hw/display/cirrus_vga_rop.h, + hw/display/cirrus_vga_rop2.h. + - debian/patches/CVE-2017-7980-7.patch: stop passing around src + pointers in hw/display/cirrus_vga.c, hw/display/cirrus_vga_rop.h, + hw/display/cirrus_vga_rop2.h. + - debian/patches/CVE-2017-7980-8.patch: fix off-by-one in + hw/display/cirrus_vga_rop.h. + - debian/patches/CVE-2017-7980-9.patch: fix cirrus_invalidate_region in + hw/display/cirrus_vga.c. + - CVE-2017-7980 + * SECURITY UPDATE: denial of service via memory leak in virtFS + - debian/patches/CVE-2017-8086.patch: fix leak in + hw/9pfs/virtio-9p-xattr.c. + - CVE-2017-8086 + * SECURITY UPDATE: denial of service via leak in audio + - debian/patches/CVE-2017-8309.patch: release capture buffers in + audio/audio.c. + - CVE-2017-8309 + * SECURITY UPDATE: denial of service via leak in keyboard + - debian/patches/CVE-2017-8379-1.patch: limit kbd queue depth in + ui/input.c. + - debian/patches/CVE-2017-8379-2.patch: don't queue delay if paused in + ui/input.c. + - CVE-2017-8379 + * SECURITY REGRESSION: Windows 7 VGA compatibility issue (LP: #1581936) + - debian/patches/lp1581936.patch: add sr_vbe register set to + hw/display/vga.c, hw/display/vga_int.h. + + -- Marc Deslauriers Wed, 10 May 2017 15:50:30 -0400 + +qemu (2.0.0+dfsg-2ubuntu1.33) trusty-security; urgency=medium + + * SECURITY UPDATE: DoS via 6300esb unplug operations + - debian/patches/CVE-2016-10155.patch: add exit function in + hw/watchdog/wdt_i6300esb.c. + - CVE-2016-10155 + * SECURITY UPDATE: DoS in JAZZ RC4030 chipset emulation + - debian/patches/CVE-2016-8667.patch: limit interval timer reload value + in hw/dma/rc4030.c. + - CVE-2016-8667 + * SECURITY UPDATE: DoS in 16550A UART emulation + - debian/patches/CVE-2016-8669.patch: check divider value against baud + base in hw/char/serial.c. + - CVE-2016-8669 + * SECURITY UPDATE: privilege escalation via ioreq handling + - debian/patches/CVE-2016-9381.patch: avoid double fetches and add + bounds checks to xen-all.c. + - CVE-2016-9381 + * SECURITY UPDATE: host filesystem access via virtFS + - debian/patches/CVE-2016-9602-*.patch: don't follow symlinks in + hw/9pfs/*. + - CVE-2016-9602 + * SECURITY UPDATE: arbitrary code execution via Cirrus VGA + - debian/patches/CVE-2016-9603.patch: remove bitblit support from + console code in hw/display/cirrus_vga.c, include/ui/console.h, + ui/console.c, ui/vnc.c. + - CVE-2016-9603 + * SECURITY UPDATE: infinite loop in ColdFire Fast Ethernet Controller + - debian/patches/CVE-2016-9776.patch: check receive buffer size + register value in hw/net/mcf_fec.c. + - CVE-2016-9776 + * SECURITY UPDATE: DoS via memory leak in USB redirector + - debian/patches/CVE-2016-9907.patch: properly free memory in + hw/usb/redirect.c. + - CVE-2016-9907 + * SECURITY UPDATE: DoS via memory leak in USB EHCI Emulation + - debian/patches/CVE-2016-9911.patch: properly free memory in + hw/usb/hcd-ehci.c. + - CVE-2016-9911 + * SECURITY UPDATE: DoS via virtFS + - debian/patches/CVE-2016-9913.patch: adjust the order of resource + cleanup in hw/9pfs/virtio-9p-device.c. + - CVE-2016-9913 + * SECURITY UPDATE: DoS via virtFS + - debian/patches/CVE-2016-9914-*.patch: add cleanup operations to + fsdev/file-op-9p.h, hw/9pfs/virtio-9p-device.c. + - CVE-2016-9914 + * SECURITY UPDATE: DoS via virtFS + - debian/patches/CVE-2016-9915.patch: add cleanup operation to + hw/9pfs/virtio-9p-handle.c. + - CVE-2016-9915 + * SECURITY UPDATE: DoS via virtFS + - debian/patches/CVE-2016-9916.patch: add cleanup operation to + hw/9pfs/virtio-9p-proxy.c. + - CVE-2016-9916 + * SECURITY UPDATE: DoS in Cirrus VGA + - debian/patches/CVE-2016-9921-9922.patch: check bpp values in + hw/display/cirrus_vga.c. + - CVE-2016-9921 + - CVE-2016-9922 + * SECURITY UPDATE: code execution via Cirrus VGA + - debian/patches/CVE-2017-2615.patch: fix oob access in + hw/display/cirrus_vga.c. + - CVE-2017-2615 + * SECURITY UPDATE: code execution via Cirrus VGA + - debian/patches/CVE-2017-2620-pre.patch: add extra parameter to + blit_is_unsafe in hw/display/cirrus_vga.c. + - debian/patches/CVE-2017-2620.patch: add blit destination check to + hw/display/cirrus_vga.c. + - CVE-2017-2620 + * SECURITY UPDATE: memory corruption issues in VNC + - debian/patches/CVE-2017-2633.patch: properly handle surface sizes in + ui/vnc.c, ui/vnc.h. + - CVE-2017-2633 + * SECURITY UPDATE: DoS via memory leak in ac97 audio device + - debian/patches/CVE-2017-5525.patch: add exit function to + hw/audio/ac97.c. + - CVE-2017-5525 + * SECURITY UPDATE: DoS via memory leak in es1370 audio device + - debian/patches/CVE-2017-5526.patch: add exit function to + hw/audio/es1370.c. + - CVE-2017-5526 + * SECURITY UPDATE: DoS via memory leak in 16550A UART emulation + - debian/patches/CVE-2017-5579.patch: properly free resources in + hw/char/serial.c. + - CVE-2017-5579 + * SECURITY UPDATE: code execution via SDHCI device emulation + - debian/patches/CVE-2017-5667.patch: check data length in + hw/sd/sdhci.c. + - CVE-2017-5667 + * SECURITY UPDATE: DoS via memory leak in MegaRAID SAS device + - debian/patches/CVE-2017-5856.patch: properly handle memory in + hw/scsi/megasas.c. + - CVE-2017-5856 + * SECURITY UPDATE: DoS in CCID Card device + - debian/patches/CVE-2017-5898.patch: check ccid apdu length in + hw/usb/dev-smartcard-reader.c. + - CVE-2017-5898 + * SECURITY UPDATE: DoS via infinite loop in USB xHCI controller emulator + - debian/patches/CVE-2017-5973.patch: apply limits to loops in + hw/usb/hcd-xhci.c, trace-events. + - CVE-2017-5973 + * SECURITY UPDATE: DoS via infinite loop in SDHCI device emulation + - debian/patches/CVE-2017-5987-*.patch: fix transfer mode register + handling in hw/sd/sdhci.c. + - CVE-2017-5987 + * SECURITY UPDATE: DoS via infinite loop in USB OHCI emulation + - debian/patches/CVE-2017-6505.patch: limit the number of link eds in + hw/usb/hcd-ohci.c. + - CVE-2017-6505 + * A work-around to fix live migrations (LP: #1647389) + - debian/patches/CVE-2016-5403-5.patch: fix vq->inuse recalc after + migration in hw/virtio/virtio.c. + - debian/patches/CVE-2016-5403-6.patch: make sure vdev->vq[i].inuse + never goes below 0 in hw/virtio/virtio.c. + + -- Marc Deslauriers Wed, 05 Apr 2017 11:59:07 -0400 + +qemu (2.0.0+dfsg-2ubuntu1.32) trusty; urgency=medium + + [ Dave Chiluk ] + * Qemu VM crash with error + "bdrv_error_action: Assertion `error >= 0' failed" + (LP: #1655225) + + -- Christian Ehrhardt Tue, 31 Jan 2017 11:26:19 +0100 + +qemu (2.0.0+dfsg-2ubuntu1.31) trusty; urgency=medium + + * aio: fix qemu_bh_schedule() bh->ctx race condition (LP: #1640382) + - d/p/0001-aio-fix-qemu_bh_schedule-bh-ctx-race-condition.patch + * aio: strengthen memory barriers for bottom half scheduling + (LP: #1587039) + - d/p/0002-aio-strengthen-memory-barriers-for-bottom-half-sched.patch + + -- Seyeong Kim Thu, 24 Nov 2016 10:44:55 +0100 + +qemu (2.0.0+dfsg-2ubuntu1.30) trusty-security; urgency=medium + + * SECURITY UPDATE: DoS via unbounded memory allocation + - debian/patches/CVE-2016-5403.patch: re-enable original patch. + - debian/patches/CVE-2016-5403-2.patch: recalculate vq->inuse after + migration in hw/virtio/virtio.c. + - debian/patches/CVE-2016-5403-3.patch: decrement vq->inuse in + virtqueue_discard() in hw/virtio/virtio.c. + - debian/patches/CVE-2016-5403-4.patch: zero vq->inuse in + virtio_reset() in hw/virtio/virtio.c. + - CVE-2016-5403 + * SECURITY UPDATE: use after free while writing in vmxnet3 + - debian/patches/CVE-2016-6833.patch: check for device_active before + write in hw/net/vmxnet3.c. + - CVE-2016-6833 + * SECURITY UPDATE: DoS via infinite loop during packet fragmentation + - debian/patches/CVE-2016-6834.patch: check fragment length during + fragmentation in hw/net/vmxnet_tx_pkt.c. + - CVE-2016-6834 + * SECURITY UPDATE: Buffer overflow in vmxnet_tx_pkt_parse_headers() + - debian/patches/CVE-2016-6835.patch: check IP header length in + hw/net/vmxnet_tx_pkt.c. + - CVE-2016-6835 + * SECURITY UPDATE: Information leak in vmxnet3_complete_packet + - debian/patches/CVE-2016-6836.patch: initialise local tx descriptor in + hw/net/vmxnet3.c. + - CVE-2016-6836 + * SECURITY UPDATE: Integer overflow in packet initialisation in VMXNET3 + - debian/patches/CVE-2016-6888.patch: use g_new for pkt initialisation + in hw/net/vmxnet_tx_pkt.c. + - CVE-2016-6888 + * SECURITY UPDATE: directory traversal flaw in 9p virtio backend + - debian/patches/CVE-2016-7116-1.patch: forbid illegal path names in + hw/9pfs/virtio-9p.c. + - debian/patches/CVE-2016-7116-2.patch: forbid . and .. in file names + in hw/9pfs/virtio-9p.c. + - debian/patches/CVE-2016-7116-3.patch: handle walk of ".." in the root + directory in hw/9pfs/virtio-9p.*. + - debian/patches/CVE-2016-7116-4.patch: fix potential segfault during + walk in hw/9pfs/virtio-9p.c. + - CVE-2016-7116 + * SECURITY UPDATE: OOB read and infinite loop in pvscsi + - debian/patches/CVE-2016-7155.patch: check page count while + initialising descriptor rings in hw/scsi/vmw_pvscsi.c. + - CVE-2016-7155 + * SECURITY UPDATE: infinite loop when building SG list in pvscsi + - debian/patches/CVE-2016-7156.patch: limit loop to fetch SG list in + hw/scsi/vmw_pvscsi.c. + - CVE-2016-7156 + * SECURITY UPDATE: buffer overflow in xlnx.xps-ethernetlite + - debian/patches/CVE-2016-7161.patch: fix a heap overflow in + hw/net/xilinx_ethlite.c. + - CVE-2016-7161 + * SECURITY UPDATE: OOB stack memory access in vmware_vga + - debian/patches/CVE-2016-7170.patch: correct bitmap and pixmap size + checks in hw/display/vmware_vga.c. + - CVE-2016-7170 + * SECURITY UPDATE: Infinite loop when processing IO requests in pvscsi + - debian/patches/CVE-2016-7421.patch: limit process IO loop to ring + size in hw/scsi/vmw_pvscsi.c. + - CVE-2016-7421 + * SECURITY UPDATE: denial of service in mcf via invalid count + - debian/patches/CVE-2016-7908.patch: limit buffer descriptor count in + hw/net/mcf_fec.c. + - CVE-2016-7908 + * SECURITY UPDATE: denial of service in pcnet via invalid length + - debian/patches/CVE-2016-7909.patch: check rx/tx descriptor ring + length in hw/net/pcnet.c. + - CVE-2016-7909 + * SECURITY UPDATE: denial of service via infinite loop in xhci + - debian/patches/CVE-2016-8576.patch: limit the number of link trbs we + are willing to process in hw/usb/hcd-xhci.c. + - CVE-2016-8576 + * SECURITY UPDATE: host memory leakage in 9pfs + - debian/patches/CVE-2016-8577.patch: fix potential host memory leak in + v9fs_read in hw/9pfs/virtio-9p.c. + - CVE-2016-8577 + * SECURITY UPDATE: NULL dereference in 9pfs + - debian/patches/CVE-2016-8578.patch: allocate space for guest + originated empty strings in fsdev/virtio-9p-marshal.c, + hw/9pfs/virtio-9p.c. + - CVE-2016-8578 + * SECURITY UPDATE: infinite loop in Intel HDA controller + - debian/patches/CVE-2016-8909.patch: check stream entry count during + transfer in hw/audio/intel-hda.c. + - CVE-2016-8909 + * SECURITY UPDATE: infinite loop in RTL8139 ethernet controller + - debian/patches/CVE-2016-8910.patch: limit processing of ring + descriptors in hw/net/rtl8139.c. + - CVE-2016-8910 + * SECURITY UPDATE: memory leakage at device unplug in eepro100 + - debian/patches/CVE-2016-9101.patch: fix memory leak in device uninit + in hw/net/eepro100.c. + - CVE-2016-9101 + * SECURITY UPDATE: denial of service via memory leak in 9pfs + - debian/patches/CVE-2016-9102.patch: fix memory leak in + v9fs_xattrcreate in hw/9pfs/virtio-9p.c. + - CVE-2016-9102 + * SECURITY UPDATE: information leakage via xattribute in 9pfs + - debian/patches/CVE-2016-9103.patch: fix information leak in xattr + read in hw/9pfs/virtio-9p.c. + - CVE-2016-9103 + * SECURITY UPDATE: integer overflow leading to OOB access in 9pfs + - debian/patches/CVE-2016-9104.patch: fix integer overflow issue in + xattr read/write in hw/9pfs/virtio-9p.c. + - CVE-2016-9104 + * SECURITY UPDATE: denial of service via memory leakage in 9pfs + - debian/patches/CVE-2016-9105.patch: fix memory leak in v9fs_link in + hw/9pfs/virtio-9p.c. + - CVE-2016-9105 + * SECURITY UPDATE: denial of service via memory leakage in 9pfs + - debian/patches/CVE-2016-9106.patch: fix memory leak in v9fs_write in + hw/9pfs/virtio-9p.c. + - CVE-2016-9106 + + -- Marc Deslauriers Mon, 07 Nov 2016 15:47:33 -0500 + +qemu (2.0.0+dfsg-2ubuntu1.29) trusty; urgency=medium + + * Drop pc-1.0-qemu-kvm alias to pc-1.0, which is a duplicate id to the + pc-1.0-qemu-kvm type, to fix migration from precise (LP: #1536331). + + -- Christian Ehrhardt Mon, 10 Oct 2016 09:06:28 +0200 + +qemu (2.0.0+dfsg-2ubuntu1.28) trusty; urgency=medium + + [ Ryan Harper ] + * Apply upstream fix for memory slot alignement (LP: #1606940) + - debian/patches/kvm-fix-memory-slot-page-alignment-logic.patch + + -- Chris J Arges Thu, 15 Sep 2016 09:58:23 -0500 + +qemu (2.0.0+dfsg-2ubuntu1.27) trusty-security; urgency=medium + + * SECURITY REGRESSION: crash on migration with memory stats enabled + (LP: #1612089) + - debian/patches/CVE-2016-5403.patch: disable for now pending + investigation. + + -- Marc Deslauriers Fri, 12 Aug 2016 08:48:20 -0400 + +qemu (2.0.0+dfsg-2ubuntu1.26) trusty-security; urgency=medium + + * SECURITY UPDATE: DoS and possible host code execution in 53C9X Fast + SCSI Controller + - debian/patches/CVE-2016-4439.patch: check length in hw/scsi/esp.c. + - CVE-2016-4439 + * SECURITY UPDATE: DoS in 53C9X Fast SCSI Controller + - debian/patches/CVE-2016-4441.patch: check DMA length in + hw/scsi/esp.c. + - CVE-2016-4441 + * SECURITY UPDATE: infinite loop in vmware_vga + - debian/patches/CVE-2016-4453.patch: limit fifo commands in + hw/display/vmware_vga.c. + - CVE-2016-4453 + * SECURITY UPDATE: DoS or host memory leakage in vmware_vga + - debian/patches/CVE-2016-4454.patch: fix sanity checks in + hw/display/vmware_vga.c. + - CVE-2016-4454 + * SECURITY UPDATE: DoS in VMWARE PVSCSI paravirtual SCSI bus + - debian/patches/CVE-2016-4952.patch: check command descriptor ring + buffer size in hw/scsi/vmw_pvscsi.c. + - CVE-2016-4952 + * SECURITY UPDATE: MegaRAID SAS 8708EM2 host memory leakage + - debian/patches/CVE-2016-5105.patch: initialise local configuration + data buffer in hw/scsi/megasas.c. + - CVE-2016-5105 + * SECURITY UPDATE: DoS in MegaRAID SAS 8708EM2 + - debian/patches/CVE-2016-5106.patch: use appropriate property buffer + size in hw/scsi/megasas.c. + - CVE-2016-5106 + * SECURITY UPDATE: DoS in MegaRAID SAS 8708EM2 + - debian/patches/CVE-2016-5107.patch: check read_queue_head index + value in hw/scsi/megasas.c. + - CVE-2016-5107 + * SECURITY UPDATE: DoS or code execution via crafted iSCSI asynchronous + I/O ioctl call + - debian/patches/CVE-2016-5126.patch: avoid potential overflow in + block/iscsi.c. + - CVE-2016-5126 + * SECURITY UPDATE: DoS in 53C9X Fast SCSI Controller + - debian/patches/CVE-2016-5238.patch: check buffer length before + reading scsi command in hw/scsi/esp.c. + - CVE-2016-5238 + * SECURITY UPDATE: MegaRAID SAS 8708EM2 host memory leakage + - debian/patches/CVE-2016-5337.patch: null terminate bios version + buffer in hw/scsi/megasas.c. + - CVE-2016-5337 + * SECURITY UPDATE: DoS or code execution in 53C9X Fast SCSI Controller + - debian/patches/CVE-2016-5338.patch: check TI buffer index in + hw/scsi/esp.c. + - CVE-2016-5338 + * SECURITY UPDATE: DoS via unbounded memory allocation + - debian/patches/CVE-2016-5403.patch: check size in hw/virtio/virtio.c. + - CVE-2016-5403 + * SECURITY UPDATE: oob write access while reading ESP command + - debian/patches/CVE-2016-6351.patch: make cmdbuf big enough for + maximum CDB size and handle migration in hw/scsi/esp.c, + include/hw/scsi/esp.h, include/migration/vmstate.h. + - CVE-2016-6351 + + -- Marc Deslauriers Wed, 03 Aug 2016 14:01:20 -0400 + +qemu (2.0.0+dfsg-2ubuntu1.25) trusty; urgency=medium + + [Kai Storbeck] + * backport patch to fix guest hangs after live migration (LP: #1297218) + + -- Serge Hallyn Fri, 01 Jul 2016 14:25:20 -0500 + +qemu (2.0.0+dfsg-2ubuntu1.24) trusty-security; urgency=medium + + * SECURITY UPDATE: denial of service via multiple eof_timers in ohci + - debian/patches/CVE-2016-2391.patch: allocate timer only once in + hw/usb/hcd-ohci.c. + - CVE-2016-2391 + * SECURITY UPDATE: denial of service in in remote NDIS control message + handling + - debian/patches/CVE-2016-2392.patch: check USB configuration + descriptor object in hw/usb/dev-network.c. + - CVE-2016-2392 + * SECURITY UPDATE: denial of service or host information leak in USB Net + device emulation support + - debian/patches/CVE-2016-2538.patch: check RNDIS buffer offsets and + length in hw/usb/dev-network.c. + - CVE-2016-2538 + * SECURITY UPDATE: denial of service via infinite loop in ne2000 + - debian/patches/CVE-2016-2841.patch: heck ring buffer control + registers in hw/net/ne2000.c. + - CVE-2016-2841 + * SECURITY UPDATE: denial of service via payload length in crafted packet + - debian/patches/CVE-2016-2857.patch: check packet payload length in + net/checksum.c. + - CVE-2016-2857 + * SECURITY UPDATE: denial of service in PRNG support + - debian/patches/CVE-2016-2858.patch: add request queue support to + rng-random in backends/rng-egd.c, backends/rng-random.c, + backends/rng.c, include/sysemu/rng.h. + - CVE-2016-2858 + * SECURITY UPDATE: arbitrary host code execution via VGA module + - debian/patches/CVE-2016-3710.patch: fix banked access bounds checking + in hw/display/vga.c. + - CVE-2016-3710 + * SECURITY UPDATE: denial of service via VGA module + - debian/patches/CVE-2016-3712.patch: make sure vga register setup for + vbe stays intact in hw/display/vga.c. + - CVE-2016-3712 + * SECURITY UPDATE: denial of service in Luminary Micro Stellaris Ethernet + - debian/patches/CVE-2016-4001.patch: check packet length against + receive buffer in hw/net/stellaris_enet.c. + - CVE-2016-4001 + * SECURITY UPDATE: denial of sevice and possible code execution in + MIPSnet + - debian/patches/CVE-2016-4002.patch: check size in hw/net/mipsnet.c. + - CVE-2016-4002 + * SECURITY UPDATE: host information leak via TPR access + - debian/patches/CVE-2016-4020.patch: initialize variable in + hw/i386/kvmvapic.c. + - CVE-2016-4020 + * SECURITY UPDATE: denial of service via infinite loop in in usb_ehci + - debian/patches/CVE-2016-4037.patch: apply limit to iTD/sidt + descriptors in hw/usb/hcd-ehci.c. + - CVE-2016-4037 + * This package does _not_ contain the changes from 2.0.0+dfsg-2ubuntu1.23 + in trusty-proposed. + + -- Marc Deslauriers Tue, 10 May 2016 14:58:04 -0400 + +qemu (2.0.0+dfsg-2ubuntu1.22) trusty-security; urgency=medium + + * SECURITY UPDATE: msi-x null pointer dereference + - debian/patches/CVE-2015-7549.patch: implement pba write in + hw/pci/msix.c. + - CVE-2015-7549 + * SECURITY UPDATE: vnc floating point exception + - debian/patches/CVE-2015-8504.patch: handle zero values in ui/vnc.c. + - CVE-2015-8504 + * SECURITY UPDATE: paravirtualized drivers incautious about shared memory + contents + - debian/patches/CVE-2015-8550-1.patch: avoid double access in + hw/block/xen_blkif.h. + - debian/patches/CVE-2015-8550-2.patch: avoid reading twice in + hw/display/xenfb.c. + - CVE-2015-8550 + * SECURITY UPDATE: infinite loop in ehci_advance_state + - debian/patches/CVE-2015-8558.patch: make idt processing more robust + in hw/usb/hcd-ehci.c. + - CVE-2015-8558 + * SECURITY UPDATE: host memory leakage in vmxnet3 + - debian/patches/CVE-2015-856x.patch: avoid memory leakage in + hw/net/vmxnet3.c. + - CVE-2015-8567 + - CVE-2015-8568 + * SECURITY UPDATE: buffer overflow in megasas_ctrl_get_info + - debian/patches/CVE-2015-8613.patch: initialise info object with + appropriate size in hw/scsi/megasas.c. + - CVE-2015-8613 + * SECURITY UPDATE: DoS via Human Monitor Interface + - debian/patches/CVE-2015-8619.patch: fix sendkey out of bounds write + in hmp.c, include/ui/console.h, ui/input-legacy.c. + - CVE-2015-8619 + * SECURITY UPDATE: buffer overrun during VM migration + - debian/patches/CVE-2015-8666.patch: handle full length bytes in + hw/acpi/core.c. + - CVE-2015-8666 + * SECURITY UPDATE: ne2000 OOB r/w in ioport operations + - debian/patches/CVE-2015-8743.patch: fix bounds check in ioport + operations in hw/net/ne2000.c. + - CVE-2015-8743 + * SECURITY UPDATE: incorrect l2 header validation in vmxnet3 + - debian/patches/CVE-2015-8744.patch: properly validate header in + hw/net/vmxnet3.c, hw/net/vmxnet_tx_pkt.c. + - CVE-2015-8744 + * SECURITY UPDATE: crash via reading IMR registers in vmxnet3 + - debian/patches/CVE-2015-8745.patch: support reading IMR registers in + hw/net/vmxnet3.c. + - CVE-2015-8745 + * SECURITY UPDATE: ahci use-after-free vulnerability in aio port commands + - debian/patches/CVE-2016-1568.patch: reset ncq object to unused on + error in hw/ide/ahci.c. + - CVE-2016-1568 + * SECURITY UPDATE: firmware configuration device OOB rw access + - debian/patches/CVE-2016-1714.patch: avoid calculating invalid current + entry pointer in hw/nvram/fw_cfg.c. + - CVE-2016-1714 + * SECURITY UPDATE: DoS via null pointer dereference in vapic_write() + - debian/patches/CVE-2016-1922.patch: avoid null pointer dereference in + hw/i386/kvmvapic.c. + - CVE-2016-1922 + * SECURITY UPDATE: e1000 infinite loop + - debian/patches/CVE-2016-1981.patch: eliminate infinite loops on + out-of-bounds transfer start in hw/net/e1000.c + - CVE-2016-1981 + * SECURITY UPDATE: ehci null pointer dereference in ehci_caps_write + - debian/patches/CVE-2016-2198.patch: add capability mmio write + function in hw/usb/hcd-ehci.c. + - CVE-2016-2198 + + -- Marc Deslauriers Tue, 02 Feb 2016 07:32:36 -0500 + +qemu (2.0.0+dfsg-2ubuntu1.21) trusty-security; urgency=medium + + * SECURITY UPDATE: denial of service via jumbo frame flood in virtio + - debian/patches/CVE-2015-7295.patch: drop truncated packets in + hw/net/virtio-net.c, hw/virtio/virtio.c, include/hw/virtio/virtio.h. + - CVE-2015-7295 + * SECURITY UPDATE: loopback mode heap overflow vulnerability in pcnet + - debian/patches/CVE-2015-7504.patch: leave room for CRC code in + hw/net/pcnet.c. + - CVE-2015-7504 + * SECURITY UPDATE: non-loopback mode buffer overflow in pcnet + - debian/patches/CVE-2015-7512.patch: check packet length in + hw/net/pcnet.c. + - CVE-2015-7512 + * SECURITY UPDATE: infinite loop in eepro100 + - debian/patches/CVE-2015-8345.patch: prevent endless loop in + hw/net/eepro100.c. + - CVE-2015-8345 + + -- Marc Deslauriers Tue, 01 Dec 2015 16:01:17 -0500 + +qemu (2.0.0+dfsg-2ubuntu1.20) trusty; urgency=low + + * debian/patches/upstream-fix-irq-route-entries.patch + Fix "kvm_irqchip_commit_routes: Assertion 'ret == 0' failed" + (LP: #1465935) + + -- Stefan Bader Fri, 09 Oct 2015 17:16:30 +0200 + +qemu (2.0.0+dfsg-2ubuntu1.19) trusty-security; urgency=medium + + * SECURITY UPDATE: denial of service via vnc infinite loop + - debian/patches/CVE-2015-5239.patch: limit client_cut_text msg payload + size in ui/vnc.c. + - CVE-2015-5239 + * SECURITY UPDATE: denial of service via NE2000 driver + - debian/patches/CVE-2015-5278.patch: fix infinite loop in + hw/net/ne2000.c. + - CVE-2015-5278 + * SECURITY UPDATE: denial of service and possible code execution via + heap overflow in NE2000 driver + - debian/patches/CVE-2015-5279.patch: validate ring buffer pointers in + hw/net/ne2000.c. + - CVE-2015-5279 + * SECURITY UPDATE: denial of service via e1000 infinite loop + - debian/patches/CVE-2015-6815.patch: check bytes in hw/net/e1000.c. + - CVE-2015-6815 + * SECURITY UPDATE: denial of service via illegal ATAPI commands + - debian/patches/CVE-2015-6855.patch: fix ATAPI command permissions in + hw/ide/core.c. + - CVE-2015-6855 + + -- Marc Deslauriers Wed, 23 Sep 2015 15:13:35 -0400 + +qemu (2.0.0+dfsg-2ubuntu1.18) trusty-proposed; urgency=medium + + * qemu-nbd-fix-vdi-corruption.patch: + qemu-nbd: fix corruption while writing VDI volumes (LP: #1422307) + + -- Pierre Schweitzer Mon, 17 Aug 2015 11:43:39 +0200 + +qemu (2.0.0+dfsg-2ubuntu1.17) trusty-security; urgency=medium + + * SECURITY UPDATE: denial of service via PRDT with zero complete sectors + - debian/patches/CVE-2014-9718.patch: refactor return codes in + hw/ide/ahci.c, hw/ide/core.c, hw/ide/internal.h, hw/ide/macio.c, + hw/ide/pci.c. + - CVE-2014-9718 + * SECURITY UPDATE: process heap memory disclosure + - debian/patches/CVE-2015-5165.patch: check sizes in hw/net/rtl8139.c. + - CVE-2015-5165 + * SECURITY UPDATE: denial of service via virtio-serial + - debian/patches/CVE-2015-5745.patch: don't assume a specific layout + for control messages in hw/char/virtio-serial-bus.c. + - CVE-2015-5745 + + -- Marc Deslauriers Tue, 25 Aug 2015 10:03:25 -0400 + +qemu (2.0.0+dfsg-2ubuntu1.16) trusty; urgency=medium + + * Support qemu-kvm on x32, arm64, ppc64 and pp64el architectures + (LP: #1389897) (Patch thanks to mwhudson, BenC, and infinity) + * debian/control-in: Add kvm-ipxe-precise to qemu-system-x86's Suggests + field to match debian/control. Without this, this relationship gets + dropped when debian/control is regenerated. + + -- dann frazier Wed, 05 Aug 2015 08:28:04 -0600 + +qemu (2.0.0+dfsg-2ubuntu1.15) trusty-security; urgency=medium + + * SECURITY UPDATE: out-of-bounds memory access in pit_ioport_read() + - debian/patches/CVE-2015-3214.patch: ignore read in hw/timer/i8254.c. + - CVE-2015-3214 + * SECURITY UPDATE: heap overflow when processing ATAPI commands + - debian/patches/CVE-2015-5154.patch: check bounds and clear DRQ in + hw/ide/core.c, make sure command is completed in hw/ide/atapi.c. + - CVE-2015-5154 + + -- Marc Deslauriers Mon, 27 Jul 2015 14:23:15 -0400 + +qemu (2.0.0+dfsg-2ubuntu1.14) trusty; urgency=medium + + * ubuntu/Add-machine-type-pc-i440fx-1.5-qemu-kvm-for-live-migrate.patch: + enable migration from 13.10 hosts (LP: #1425619) + + -- Chris J Arges Mon, 15 Jun 2015 12:26:17 -0500 + +qemu (2.0.0+dfsg-2ubuntu1.13) trusty-security; urgency=medium + + * SECURITY UPDATE: heap overflow in PCNET controller + - debian/patches/CVE-2015-3209-pre.patch: fix negative array index read + in hw/net/pcnet.c. + - debian/patches/CVE-2015-3209.patch: check bounds in hw/net/pcnet.c. + - CVE-2015-3209 + * SECURITY UPDATE: unsafe /tmp filename use by slirp + - debian/patches/CVE-2015-4037.patch: use mkdtemp in net/slirp.c. + - CVE-2015-4037 + * SECURITY UPDATE: denial of service via MSI message data field write + - debian/patches/CVE-2015-4103.patch: properly gate writes in + hw/xen/xen_pt.c, hw/xen/xen_pt.h, hw/xen/xen_pt_config_init.c. + - CVE-2015-4103 + * SECURITY UPDATE: denial of service via MSI mask bits access + - debian/patches/CVE-2015-4104.patch: don't allow guest access in + hw/pci/msi.c, hw/xen/xen_pt_config_init.c, include/hw/pci/pci_regs.h. + - CVE-2015-4104 + * SECURITY UPDATE: denial of service via PCI MSI-X pass-through error + message logging + - debian/patches/CVE-2015-4105.patch: limit messages in + hw/xen/xen_pt.h, hw/xen/xen_pt_msi.c. + - CVE-2015-4105 + * SECURITY UPDATE: denial of service or possible privilege escalation via + write access to PCI config space + - debian/patches/CVE-2015-4106-*.patch: multiple upstream commits to + restrict passthough in hw/xen/xen_pt_config_init.c, hw/xen/xen_pt.h, + hw/xen/xen_pt.c. + - CVE-2015-4106 + * WARNING: this package does _not_ contain the changes from the qemu + 2.0.0+dfsg-2ubuntu1.12 package in trusty-proposed. + + -- Marc Deslauriers Tue, 09 Jun 2015 09:40:05 -0400 + +qemu (2.0.0+dfsg-2ubuntu1.11) trusty-security; urgency=medium + + * SECURITY UPDATE: denial of service in vnc web + - debian/patches/CVE-2015-1779-1.patch: incrementally decode websocket + frames in ui/vnc-ws.c, ui/vnc-ws.h, ui/vnc.h. + - debian/patches/CVE-2015-1779-2.patch: limit size of HTTP headers from + websockets clients in ui/vnc-ws.c. + - CVE-2015-1779 + * SECURITY UPDATE: denial of service via PCI command register access + - debian/patches/CVE-2015-2756.patch: limit PCI command register access + in hw/xen/xen_pt.c, hw/xen/xen_pt_config_init.c. + - CVE-2015-2756 + * SECURITY UPDATE: host code execution via floppy device (VEMON) + - debian/patches/CVE-2015-3456.patch: force the fifo access to be in + bounds of the allocated buffer in hw/block/fdc.c. + - CVE-2015-3456 + + -- Marc Deslauriers Wed, 13 May 2015 07:59:08 -0400 + +qemu (2.0.0+dfsg-2ubuntu1.10) trusty; urgency=low + + * Apply an upstream qemu patch to fix issues with persistent grants + on qcow images accessed by dom0 (LP: #1394327). + + -- Stefan Bader Mon, 15 Dec 2014 09:56:34 +0100 + +qemu (2.0.0+dfsg-2ubuntu1.9) trusty-security; urgency=medium + + * SECURITY UPDATE: code execution via savevm data + - debian/patches/CVE-2014-7840.patch: validate parameters in + arch_init.c. + - CVE-2014-7840 + * SECURITY UPDATE: code execution via cirrus vga blit regions + (LP: #1400775) + - debian/patches/CVE-2014-8106.patch: properly validate blit regions in + hw/display/cirrus_vga.c. + - CVE-2014-8106 + + -- Marc Deslauriers Wed, 10 Dec 2014 16:00:51 -0500 + +qemu (2.0.0+dfsg-2ubuntu1.8) trusty-proposed; urgency=medium + + * debian/qemu-system-x86.qemu-kvm.upstart: create /dev/kvm in a + container. (LP: #1370199) + * Cherrypick upstream patch to fix intermittent qemu-img corruption + (LP: #1368815) + - 501-block-raw-posix-fix-disk-corruption-in-try-fiemap + - (note - 502-block-raw-posic-use-seek-hole-ahead-of-fiemap (which was + also needed in utopic) appears to be unneeded here as the code being + changed has not yet been switched to using try_fiemap) + + -- Serge Hallyn Thu, 20 Nov 2014 11:24:51 -0600 + +qemu (2.0.0+dfsg-2ubuntu1.7) trusty-security; urgency=medium + + * SECURITY UPDATE: information disclosure via vga driver + - debian/patches/CVE-2014-3615.patch: return the correct memory size, + sanity check register writes, and don't use fixed buffer sizes in + hw/display/qxl.c, hw/display/vga.c, hw/display/vga_int.h, + ui/spice-display.c. + - CVE-2014-3615 + * SECURITY UPDATE: denial of service via slirp NULL pointer deref + - debian/patches/CVE-2014-3640.patch: make sure socket is not just a + stub in slirp/udp.c. + - CVE-2014-3640 + * SECURITY UPDATE: possible privilege escalation via vmware-vga driver + - debian/patches/CVE-2014-3689.patch: verify rectangles in + hw/display/vmware_vga.c. + - CVE-2014-3689 + * SECURITY UPDATE: denial of service and possible privilege escalation + via vmstate_xhci_event + - debian/patches/CVE-2014-5263.patch: fix unterminated field list in + hw/usb/hcd-xhci.c. + - CVE-2014-5263 + * SECURITY UPDATE: possible privilege escalation via pcihp out-of-bounds + - debian/patches/CVE-2014-5388.patch: fix bounds checking in + hw/acpi/pcihp.c. + - CVE-2014-5388 + * SECURITY UPDATE: denial of service via VNC console + - debian/patches/CVE-2014-7815.patch: validate bits_per_pixel in + ui/vnc.c. + - CVE-2014-7815 + + -- Marc Deslauriers Tue, 11 Nov 2014 14:17:45 -0500 + +qemu (2.0.0+dfsg-2ubuntu1.6) trusty-proposed; urgency=medium + + * Support incoming migration from 12.04 (LP: #1374612) + - d/p/ubutu/add-machine-type-pc-1.0-qemu-kvm-for-live-migrate-co.patch + - add note in README.Debian + - d/control: have qemu-system-x86 suggest kvm-ipxe-precise + + -- Serge Hallyn Mon, 06 Oct 2014 17:47:08 -0500 + +qemu (2.0.0+dfsg-2ubuntu1.5) trusty-proposed; urgency=medium + + * move reload of kvm_intel qemu-system-x86.postinst. (LP: #1324174) + + -- Serge Hallyn Sun, 14 Sep 2014 19:40:42 -0500 + +qemu (2.0.0+dfsg-2ubuntu1.4) trusty-proposed; urgency=medium + + * reload kvm_intel if needed to set the nested=Y flag (LP: #1324174) + + -- Serge Hallyn Tue, 09 Sep 2014 15:08:12 -0500 + +qemu (2.0.0+dfsg-2ubuntu1.3) trusty-security; urgency=medium + + * SECURITY UPDATE: multiple buffer overflows on invalid state load + - debian/patches: added large number of upstream patches pulled from + git tree. + - CVE-2013-4148 + - CVE-2013-4149 + - CVE-2013-4150 + - CVE-2013-4151 + - CVE-2013-4526 + - CVE-2013-4527 + - CVE-2013-4529 + - CVE-2013-4530 + - CVE-2013-4531 + - CVE-2013-4532 + - CVE-2013-4533 + - CVE-2013-4534 + - CVE-2013-4535 + - CVE-2013-4536 + - CVE-2013-4537 + - CVE-2013-4538 + - CVE-2013-4539 + - CVE-2013-4540 + - CVE-2013-4541 + - CVE-2013-4542 + - CVE-2013-6399 + - CVE-2014-0182 + - CVE-2014-0222 + - CVE-2014-0223 + - CVE-2014-3461 + - CVE-2014-3471 + + -- Marc Deslauriers Tue, 12 Aug 2014 08:10:08 -0400 + +qemu (2.0.0+dfsg-2ubuntu1.2) trusty-proposed; urgency=medium + + * d/qemu-system-x86.qemu-kvm.upstart: change the early-exit check from + /usr/bin/kvm to qemu-system-x86_64. (LP: #1348551) + + -- Serge Hallyn Fri, 25 Jul 2014 08:59:57 -0500 + +qemu (2.0.0+dfsg-2ubuntu1.1) trusty-proposed; urgency=low + + * remove alternatives for qemu: different architectures + aren't really alternatives and never had been (LP: #1316829) + * debian/rules: install the proper /etc/init/qemu-kvm.conf (LP: #1315402) + * debian/control: drop the versioning requirement from libfdt-dev + build-dependency, as it is longer needed (LP: #1295072) + + -- Serge Hallyn Wed, 07 May 2014 17:31:39 -0500 + +qemu (2.0.0+dfsg-2ubuntu1) trusty-proposed; urgency=medium + + * Merge 2.0.0+dfsg-2 + * Incorporates a fix for spice users (LP: #1309452) + * drop patch kvm_physical_sync_dirty_bitmap-ignore-ENOENT-from-kv.patch, as + the regression requiring it was reverted for 2.0 upstream. + * remove qemu-system-common depends on the qemu-system-aarch64 metapackage + * debian/qemu-debootstrap: add arm64 + * Remaining changes from debian: + - keep qemu 'alternative' (not something to change in SRU) + - debian/control and debian/control-in: + * versioned libfdt-dev check, until libfdt is fixed in precise + * enable rbd + * remove ovmf Recommends, as it is in multiverse + * use libsdl1.2, not libsdl2, since libsdl2-dev is in universe + * add a qemu-system-aarch64 metapackage for transitions from trusty + development version. This can be removed after trusty. + - qemu-system-common.install: add debian/tmp/usr/lib to install the + qemu-bridge-helper + - qemu-system-common.postinst: fix /dev/kvm acls + - qemu-system-common.preinst: add kvm group if needed + - qemu-system-x86.links: add eepro100.rom link, drop links which we + have in ipxe-qemu package. + - qemu-system-x86.modprobe: set module options for older releases + - qemu-system-x86.qemu-kvm.default: defaults for the upstart job + - qemu-system-x86.qemu-kvm.upstart: qemu-kvm upstart job + - qemu-user-static.postinst-in: remove qemu-arm64-static on arm64 + - debian/rules + * add legacy kvm-spice link + * fix ppc and arm slections + * add aarch64 to user_targets + - debian/patches/ubuntu/define-trusty-machine-type.patch: define a + pc-i440fx-trusty machine type as the default. + - debian/patches/ubuntu/expose-vmx_qemu64cpu.patch: support nesting by + default in qemu64 cpu time. + + -- Serge Hallyn Fri, 18 Apr 2014 09:23:27 -0500 + +qemu (2.0.0+dfsg-2) unstable; urgency=medium + + * resurrect 02_kfreebsd.patch, -- without it qemu FTBFS on current + Debian kFreeBSD system still. + + -- Michael Tokarev Thu, 17 Apr 2014 22:04:38 +0400 + +qemu (2.0.0+dfsg-1) unstable; urgency=low + + * 2.0 actually does not close #739589, + remove it from from last changelog entry + * mention closing of #707629 by 2.0 + * mention a list of CVE IDs closed by #742730 + * mention closing of CVE-2013-4377 by 1.7.0-6 + * do not set --enable-uname-release=2.6.32 for qemu-user anymore + (was needed for old ubuntu builders) + * removed 02_kfreebsd.patch: it adds configure check for futimens() and + futimesat() syscalls on FreeBSD, however futimens() appeared in FreeBSD + 5.0, and futimesat() in 8.0, and 8.0 is the earliest supported version + * kmod dependency is linux-any + * doc-grammify-allows-to.patch: fix some lintian warnings + * remove alternatives for qemu: different architectures + aren't really alternatives and never had been + * update Standards-Version to 3.9.5 (no changes needed) + * exec-limit-translation-limiting-in-address_space_translate-to-xen.diff - + fixes windows BSOD with virtio-scsi when upgrading from 1.7.0 to 1.7.1 + or 2.0, among other things + + -- Michael Tokarev Thu, 17 Apr 2014 18:27:15 +0400 + +qemu (2.0.0~rc1+dfsg-1exp) experimental; urgency=low + + * new upstream release candidate (2.0-rc1) + Closes: #742730 -- image format processing issues: + CVE-2014-0142 CVE-2014-0143 CVE-2014-0144 CVE-2014-0145 + CVE-2014-0146 CVE-2014-0147 CVE-2014-0148 + Closes: #743235, #707629 + * refreshed patches: + 02_kfreebsd.patch + retry-pxe-after-efi.patch + use-fixed-data-path.patch + * removed patches applied upstream: + qemu-1.7.1.diff + address_space_translate-do-not-cross-page-boundaries.diff + fix-smb-security-share.patch + slirp-smb-redirect-port-445-too.patch + implement-posix-timers.diff + linux-user-fixed-s390x-clone-argument-order.patch + * added bios-256k.bin symlink and bump seabios dependency to >= 1.7.4-2 + * recommend ovmf package for qemu-system-x86 to support UEFI boot + (Closes: #714249) + * switch from sdl1 to sdl2 (build-depend on libsdl2-dev) + * output last 50 lines of config.log in case configure failed + + -- Michael Tokarev Sat, 05 Apr 2014 16:23:48 +0400 + qemu (2.0.0~rc1+dfsg-0ubuntu3) trusty; urgency=medium * d/p/ubuntu/kvm_physical_sync_dirty_bitmap-ignore-ENOENT-from-kv.patch diff -Nru qemu-2.0.0~rc1+dfsg/debian/control qemu-2.0.0+dfsg/debian/control --- qemu-2.0.0~rc1+dfsg/debian/control 2014-04-05 00:15:16.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/control 2015-08-05 14:28:29.000000000 +0000 @@ -14,7 +14,7 @@ # pc-bios/*.dts => *.dtb (PPC firmware) device-tree-compiler, texinfo, - python, + python:any, # --enable-linux-aio linux-* libaio-dev [linux-any], # --audio-drv-list=pa,alsa,sdl,oss linux-* @@ -35,7 +35,7 @@ # --enable-curl libcurl4-gnutls-dev, # --enable-fdt - libfdt-dev (>= 1.4.0), + libfdt-dev, # --enable-vnc-tls # --enable-vnc-ws libgnutls-dev, @@ -43,18 +43,21 @@ # --disable-gtk ## --with-gtkabi=2.0 # libgtk2.0-dev, libvte-dev (>> 0.18.0~), -# ubuntu/libiscsi is in universe +# vte is used together with gtk +# --disable-vte +# libiscsi is debian-only since ubuntu/libiscsi is in universe # --enable-curses libncurses5-dev, # --with-system-pixman libpixman-1-dev, # audio-drv-list += pa libpulse-dev, -# --enable-rbd - librados-dev, librbd-dev, +# --enable-rbd linux-* + librados-dev [linux-any], librbd-dev [linux-any], # --enable-vnc-sasl libsasl2-dev, # --enable-sdl +# libsdl2-dev is debian-only for now while ubuntu/libsdl2-dev is in universe libsdl1.2-dev (>> 1.2.1), # --enable-seccomp linux-amd64|linux-i386 libseccomp-dev (>> 2.1.0) [linux-amd64 linux-i386], @@ -65,8 +68,8 @@ libusb-1.0-0-dev (>= 2:1.0.13~) [linux-any], # --enable-usb-redir linux-* libusbredirparser-dev (>= 0.6~) [linux-any], -# ubuntu/libssh2 is in universe -# ubuntu/vde2 is in universe +# libssh2 is debian-only since ubuntu/libssh2 is in universe +# vde is debian-only since ubuntu/vde2 is in universe # needed for sdl libx11-dev, # --enable-xen linux-amd64|linux-i386 @@ -82,11 +85,17 @@ # other optional features we enable # --enable-vnc # --enable-vnc-png + libpng12-dev, # --enable-kvm linux-* # --enable-vhost-net linux-* # is it really linux-specific? ##--enable-glusterfs todo +##--enable-lzo todo +##--enable-libnfs todo +##--enable-netmap todo bsd +##--enable-quorum todo needs gcrypt +##--enable-xen-pci-passthrough todo Build-Conflicts: oss4-dev -Standards-Version: 3.9.4 +Standards-Version: 3.9.5 Homepage: http://www.qemu.org/ Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-qemu/qemu.git;a=shortlog;h=refs/heads/ubuntu-trusty XS-Debian-Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-qemu/qemu.git @@ -137,7 +146,6 @@ Multi-Arch: foreign Depends: ${misc:Depends}, qemu-system-arm, - qemu-system-aarch64 [arm64], qemu-system-mips, qemu-system-ppc, qemu-system-sparc, @@ -158,6 +166,7 @@ Multi-Arch: foreign Pre-Depends: adduser Depends: ${misc:Depends}, ${shlibs:Depends}, +# to fix wrong acl for newly created device node on ubuntu: udev, acl Breaks: qemu-common (<< 1.2.0.dfsg-1), @@ -212,17 +221,17 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, qemu-system-common, qemu-keymaps, Recommends: qemu-utils Suggests: samba, vde2 -Provides: ${sysprovides:arm}, ${sysprovides:arm64} +Provides: ${sysprovides:arm} Breaks: qemu-system (<< 1.3.0+dfsg-5), qemu-common (<< 1.3.0+dfsg-5), qemu-kvm (<< 1.2.0.dfsg-1), kvm (<< 1.3.0+dfsg-5), - qemu-system-aarch64 (<< 2.0.0~rc1+dfsg-0ubuntu1) + qemu-system-aarch64 (<< 2.0.0~rc1+dfsg-0ubuntu1), Replaces: qemu-system (<< 1.3.0+dfsg-5), qemu-common (<< 1.3.0+dfsg-5), qemu-kvm (<< 1.2.0.dfsg-1), kvm (<< 1.3.0+dfsg-5), - qemu-system-aarch64 (<< 2.0.0~rc1+dfsg-0ubuntu1) + qemu-system-aarch64 (<< 2.0.0~rc1+dfsg-0ubuntu1), Description: QEMU full system emulation binaries (arm) QEMU is a fast processor emulator: currently the package supports ARM emulation. By using dynamic translation it achieves @@ -262,10 +271,10 @@ Architecture: amd64 arm arm64 armel armhf hppa i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc powerpcspe ppc64 ppc64el s390x sparc sparc64 Multi-Arch: foreign Depends: ${shlibs:Depends}, ${misc:Depends}, qemu-system-common, qemu-keymaps, -Recommends: qemu-utils -Suggests: samba, vde2, # ubuntu can't Depend on openbios-ppc and openhackware as they're in universe +Suggests: samba, vde2, openbios-ppc (>= 1.1+svn1229), openhackware, qemu-slof +Recommends: qemu-utils Provides: ${sysprovides:ppc} Breaks: qemu-system (<< 1.3.0+dfsg-5), qemu-common (<< 1.3.0+dfsg-5), @@ -323,16 +332,17 @@ Architecture: amd64 arm arm64 armel armhf hppa i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc powerpcspe ppc64 ppc64el s390x sparc sparc64 Multi-Arch: foreign Depends: ${shlibs:Depends}, ${misc:Depends}, qemu-system-common, qemu-keymaps, - seabios (>= 1.7.2-2~), ipxe-qemu + seabios (>= 1.7.4-2~), ipxe-qemu Recommends: qemu-utils, +# ovmf recommends is debian-only because ubuntu/ovmf is in multiverse cpu-checker -Suggests: samba, vde2, kmod, sgabios +Suggests: samba, vde2, kmod [linux-any], sgabios, kvm-ipxe-precise Provides: ${sysprovides:x86} Conflicts: kvm (<< 1.3.0+dfsg-5) Breaks: qemu-system (<< 1.3.0+dfsg-5), -# older libvirt (eg 0.10.2.x) is known broken with qemu >= 1.3 - libvirt0 (<< 1.0), +# older libvirt (eg 1.0) is known broken with qemu >= 1.6 + libvirt0 (<< 1.2), qemu-common (<< 1.3.0+dfsg-5), qemu-kvm (<< 1.2.0.dfsg-1), kvm (<< 1.3.0+dfsg-5), @@ -433,9 +443,13 @@ qemu virtual machine. It is not used on the host. Package: qemu-kvm -Architecture: i386 amd64 armhf armel powerpc sparc +Architecture: i386 amd64 x32 armhf armel arm64 powerpc ppc64 ppc64el Multi-Arch: foreign -Depends: ${misc:Depends}, qemu-system-x86 (>= 1.7.0+dfsg-2~) +Depends: + ${misc:Depends}, + qemu-system-x86 (= ${binary:Version}) [i386 amd64 x32], + qemu-system-arm (= ${binary:Version}) [armhf armel arm64], + qemu-system-ppc (= ${binary:Version}) [powerpc ppc64 ppc64el] Provides: kvm, qemu-kvm-spice Conflicts: kvm, @@ -443,9 +457,11 @@ Breaks: qemu-system-x86 (<< 1.7.0+dfsg-2~) Replaces: qemu-system-x86 (<< 1.7.0+dfsg-2~), qemu-kvm-spice -Description: QEMU Full virtualization on x86 hardware (transitional package) - QEMU is a fast processor emulator. This package provides just a wrapper - script /usr/bin/kvm which run qemu-system-x86 in kvm mode. +Description: QEMU Full virtualization + QEMU is a fast processor emulator. This package depends on the + appropriate qemu-system-$arch to enable KVM to be run. It also + includes a script /usr/bin/kvm which runs the appropriate + qemu-system-$arch in kvm mode. . Please note that old qemu-kvm configuration files (in /etc/kvm/) are no longer used. diff -Nru qemu-2.0.0~rc1+dfsg/debian/control-in qemu-2.0.0+dfsg/debian/control-in --- qemu-2.0.0~rc1+dfsg/debian/control-in 2014-04-05 00:03:55.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/control-in 2015-08-05 14:24:53.000000000 +0000 @@ -15,7 +15,7 @@ # pc-bios/*.dts => *.dtb (PPC firmware) device-tree-compiler, texinfo, - python, + python:any, # --enable-linux-aio linux-* libaio-dev [linux-any], # --audio-drv-list=pa,alsa,sdl,oss linux-* @@ -36,7 +36,7 @@ # --enable-curl libcurl4-gnutls-dev, # --enable-fdt - libfdt-dev (>= 1.4.0), + libfdt-dev, # --enable-vnc-tls # --enable-vnc-ws libgnutls-dev, @@ -44,7 +44,9 @@ # --disable-gtk ## --with-gtkabi=2.0 # libgtk2.0-dev, libvte-dev (>> 0.18.0~), -# ubuntu/libiscsi is in universe +# vte is used together with gtk +# --disable-vte +# libiscsi is debian-only since ubuntu/libiscsi is in universe :debian:# --enable-libiscsi :debian: libiscsi-dev, # --enable-curses @@ -53,12 +55,15 @@ libpixman-1-dev, # audio-drv-list += pa libpulse-dev, -:ubuntu:# --enable-rbd -:ubuntu: librados-dev, librbd-dev, +:ubuntu:# --enable-rbd linux-* +:ubuntu: librados-dev [linux-any], librbd-dev [linux-any], # --enable-vnc-sasl libsasl2-dev, # --enable-sdl - libsdl1.2-dev (>> 1.2.1), +# libsdl2-dev is debian-only for now while ubuntu/libsdl2-dev is in universe +:debian:# --with-sdlabi=2.0 +:debian: libsdl2-dev, +:ubuntu: libsdl1.2-dev (>> 1.2.1), # --enable-seccomp linux-amd64|linux-i386 libseccomp-dev (>> 2.1.0) [linux-amd64 linux-i386], # --enable-spice linux-amd64|linux-i386 @@ -68,10 +73,10 @@ libusb-1.0-0-dev (>= 2:1.0.13~) [linux-any], # --enable-usb-redir linux-* libusbredirparser-dev (>= 0.6~) [linux-any], -# ubuntu/libssh2 is in universe +# libssh2 is debian-only since ubuntu/libssh2 is in universe :debian:# --enable-libssh2 :debian: libssh2-1-dev, -# ubuntu/vde2 is in universe +# vde is debian-only since ubuntu/vde2 is in universe :debian:# --enable-vde :debian: libvdeplug-dev, # needed for sdl @@ -89,12 +94,19 @@ # other optional features we enable # --enable-vnc :debian:# --enable-vnc-jpeg +:debian: libjpeg8-dev, # --enable-vnc-png + libpng12-dev, # --enable-kvm linux-* # --enable-vhost-net linux-* # is it really linux-specific? ##--enable-glusterfs todo +##--enable-lzo todo +##--enable-libnfs todo +##--enable-netmap todo bsd +##--enable-quorum todo needs gcrypt +##--enable-xen-pci-passthrough todo Build-Conflicts: oss4-dev -Standards-Version: 3.9.4 +Standards-Version: 3.9.5 Homepage: http://www.qemu.org/ :debian:Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-qemu/qemu.git :ubuntu:Vcs-Browser: http://anonscm.debian.org/gitweb/?p=pkg-qemu/qemu.git;a=shortlog;h=refs/heads/ubuntu-trusty @@ -147,7 +159,6 @@ Multi-Arch: foreign Depends: ${misc:Depends}, qemu-system-arm, -:ubuntu: qemu-system-aarch64 [arm64], qemu-system-mips, qemu-system-ppc, qemu-system-sparc, @@ -168,6 +179,7 @@ Multi-Arch: foreign Pre-Depends: adduser Depends: ${misc:Depends}, ${shlibs:Depends}, +# to fix wrong acl for newly created device node on ubuntu: :ubuntu: udev, acl Breaks: :ubuntu: qemu-common (<< 1.2.0.dfsg-1), @@ -222,17 +234,17 @@ Depends: ${shlibs:Depends}, ${misc:Depends}, qemu-system-common, qemu-keymaps, Recommends: qemu-utils Suggests: samba, vde2 -Provides: ${sysprovides:arm}, ${sysprovides:arm64} +Provides: ${sysprovides:arm} Breaks: qemu-system (<< 1.3.0+dfsg-5), :ubuntu: qemu-common (<< 1.3.0+dfsg-5), :ubuntu: qemu-kvm (<< 1.2.0.dfsg-1), :ubuntu: kvm (<< 1.3.0+dfsg-5), -:ubuntu: qemu-system-aarch64 (<< 2.0.0~rc1+dfsg-0ubuntu1) +:ubuntu: qemu-system-aarch64 (<< 2.0.0~rc1+dfsg-0ubuntu1), Replaces: qemu-system (<< 1.3.0+dfsg-5), :ubuntu: qemu-common (<< 1.3.0+dfsg-5), :ubuntu: qemu-kvm (<< 1.2.0.dfsg-1), :ubuntu: kvm (<< 1.3.0+dfsg-5), -:ubuntu: qemu-system-aarch64 (<< 2.0.0~rc1+dfsg-0ubuntu1) +:ubuntu: qemu-system-aarch64 (<< 2.0.0~rc1+dfsg-0ubuntu1), Description: QEMU full system emulation binaries (arm) QEMU is a fast processor emulator: currently the package supports ARM emulation. By using dynamic translation it achieves @@ -272,11 +284,11 @@ Architecture: amd64 arm arm64 armel armhf hppa i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc powerpcspe ppc64 ppc64el s390x sparc sparc64 Multi-Arch: foreign Depends: ${shlibs:Depends}, ${misc:Depends}, qemu-system-common, qemu-keymaps, -:debian: qemu-slof, openbios-ppc (>= 1.1+svn1229), openhackware, -Recommends: qemu-utils -Suggests: samba, vde2, # ubuntu can't Depend on openbios-ppc and openhackware as they're in universe +:debian: openbios-ppc (>= 1.1+svn1229), openhackware, qemu-slof +Suggests: samba, vde2, :ubuntu: openbios-ppc (>= 1.1+svn1229), openhackware, qemu-slof +Recommends: qemu-utils Provides: ${sysprovides:ppc} Breaks: qemu-system (<< 1.3.0+dfsg-5), :ubuntu: qemu-common (<< 1.3.0+dfsg-5), @@ -335,16 +347,18 @@ Architecture: amd64 arm arm64 armel armhf hppa i386 ia64 kfreebsd-amd64 kfreebsd-i386 mips mipsel powerpc powerpcspe ppc64 ppc64el s390x sparc sparc64 Multi-Arch: foreign Depends: ${shlibs:Depends}, ${misc:Depends}, qemu-system-common, qemu-keymaps, - seabios (>= 1.7.2-2~), ipxe-qemu + seabios (>= 1.7.4-2~), ipxe-qemu Recommends: qemu-utils, +# ovmf recommends is debian-only because ubuntu/ovmf is in multiverse +:debian: ovmf, :ubuntu: cpu-checker -Suggests: samba, vde2, kmod, sgabios +Suggests: samba, vde2, kmod [linux-any], sgabios, kvm-ipxe-precise Provides: ${sysprovides:x86} :ubuntu:Conflicts: kvm (<< 1.3.0+dfsg-5) Breaks: qemu-system (<< 1.3.0+dfsg-5), -# older libvirt (eg 0.10.2.x) is known broken with qemu >= 1.3 - libvirt0 (<< 1.0), +# older libvirt (eg 1.0) is known broken with qemu >= 1.6 + libvirt0 (<< 1.2), :ubuntu: qemu-common (<< 1.3.0+dfsg-5), :ubuntu: qemu-kvm (<< 1.2.0.dfsg-1), :ubuntu: kvm (<< 1.3.0+dfsg-5), @@ -446,9 +460,13 @@ Package: qemu-kvm :debian:Architecture: i386 amd64 -:ubuntu:Architecture: i386 amd64 armhf armel powerpc sparc +:ubuntu:Architecture: i386 amd64 x32 armhf armel arm64 powerpc ppc64 ppc64el Multi-Arch: foreign -Depends: ${misc:Depends}, qemu-system-x86 (>= 1.7.0+dfsg-2~) +Depends: + ${misc:Depends}, + qemu-system-x86 (= ${binary:Version}) [i386 amd64 x32], + qemu-system-arm (= ${binary:Version}) [armhf armel arm64], + qemu-system-ppc (= ${binary:Version}) [powerpc ppc64 ppc64el] Provides: kvm, :ubuntu: qemu-kvm-spice Conflicts: kvm, @@ -456,9 +474,11 @@ Breaks: qemu-system-x86 (<< 1.7.0+dfsg-2~) Replaces: qemu-system-x86 (<< 1.7.0+dfsg-2~), :ubuntu: qemu-kvm-spice -Description: QEMU Full virtualization on x86 hardware (transitional package) - QEMU is a fast processor emulator. This package provides just a wrapper - script /usr/bin/kvm which run qemu-system-x86 in kvm mode. +Description: QEMU Full virtualization + QEMU is a fast processor emulator. This package depends on the + appropriate qemu-system-$arch to enable KVM to be run. It also + includes a script /usr/bin/kvm which runs the appropriate + qemu-system-$arch in kvm mode. . Please note that old qemu-kvm configuration files (in /etc/kvm/) are no longer used. @@ -472,14 +492,14 @@ :ubuntu: to the qemu-keymaps package. Once this package and its dependencies are :ubuntu: installed you can safely remove it. -Package: qemu-system-aarch64 -Architecture: arm64 -Multi-Arch: foreign -Depends: ${misc:Depends}, qemu-system-arm (>= 2.0~git-20140403.de03c31-0ubuntu2) -Description: QEMU full system emulation binaries (aarch64) - QEMU is a fast processor emulator: currently the package supports - ARM emulation. By using dynamic translation it achieves - reasonable speed while being easy to port on new host CPUs. - . - This is a transition package as qemu-system-aarch64 has been moved into - qemu-system-arm. +:ubuntu:Package: qemu-system-aarch64 +:ubuntu:Architecture: arm64 +:ubuntu:Multi-Arch: foreign +:ubuntu:Depends: ${misc:Depends}, qemu-system-arm (>= 2.0~git-20140403.de03c31-0ubuntu2) +:ubuntu:Description: QEMU full system emulation binaries (aarch64) +:ubuntu: QEMU is a fast processor emulator: currently the package supports +:ubuntu: ARM emulation. By using dynamic translation it achieves +:ubuntu: reasonable speed while being easy to port on new host CPUs. +:ubuntu: . +:ubuntu: This is a transition package as qemu-system-aarch64 has been moved into +:ubuntu: qemu-system-arm. diff -Nru qemu-2.0.0~rc1+dfsg/debian/kvm qemu-2.0.0+dfsg/debian/kvm --- qemu-2.0.0~rc1+dfsg/debian/kvm 2014-02-04 14:21:19.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/kvm 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -#! /bin/sh -exec qemu-system-x86_64 -enable-kvm "$@" diff -Nru qemu-2.0.0~rc1+dfsg/debian/kvm.arm32 qemu-2.0.0+dfsg/debian/kvm.arm32 --- qemu-2.0.0~rc1+dfsg/debian/kvm.arm32 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/kvm.arm32 2015-08-04 18:57:57.000000000 +0000 @@ -0,0 +1,2 @@ +#!/bin/sh +exec qemu-system-arm -enable-kvm "$@" diff -Nru qemu-2.0.0~rc1+dfsg/debian/kvm.arm64 qemu-2.0.0+dfsg/debian/kvm.arm64 --- qemu-2.0.0~rc1+dfsg/debian/kvm.arm64 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/kvm.arm64 2015-08-04 18:57:57.000000000 +0000 @@ -0,0 +1,2 @@ +#!/bin/sh +exec qemu-system-aarch64 -enable-kvm "$@" diff -Nru qemu-2.0.0~rc1+dfsg/debian/kvm.powerpc qemu-2.0.0+dfsg/debian/kvm.powerpc --- qemu-2.0.0~rc1+dfsg/debian/kvm.powerpc 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/kvm.powerpc 2015-08-04 18:58:01.000000000 +0000 @@ -0,0 +1,31 @@ +#!/bin/sh +set -f + +getcpu() { + CPU="unknown" + [ -r /proc/cpuinfo ] || return + local line + while read line; do + set -- $line + [ "$1" = "cpu" ] && CPU="$3" && return 0; + done < /proc/cpuinfo + return +} + +getcpu +case "$CPU" in + e500*|e6500*|e5500*) + qemu=qemu-system-ppcemb + ;; + *) + case "$(uname -m)" in + ppc64*) + qemu=qemu-system-ppc64 + ;; + *) + qemu=qemu-system-ppc + ;; + esac + ;; +esac +exec "$qemu" -enable-kvm "$@" diff -Nru qemu-2.0.0~rc1+dfsg/debian/kvm.x86 qemu-2.0.0+dfsg/debian/kvm.x86 --- qemu-2.0.0~rc1+dfsg/debian/kvm.x86 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/kvm.x86 2015-08-04 18:57:57.000000000 +0000 @@ -0,0 +1,2 @@ +#!/bin/sh +exec qemu-system-x86_64 -enable-kvm "$@" diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/0001-aio-fix-qemu_bh_schedule-bh-ctx-race-condition.patch qemu-2.0.0+dfsg/debian/patches/0001-aio-fix-qemu_bh_schedule-bh-ctx-race-condition.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/0001-aio-fix-qemu_bh_schedule-bh-ctx-race-condition.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/0001-aio-fix-qemu_bh_schedule-bh-ctx-race-condition.patch 2016-11-24 09:44:54.000000000 +0000 @@ -0,0 +1,59 @@ +From 714b84ffff1fbdc47ac2a1408484a85b6cbb653e Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Tue, 3 Jun 2014 11:21:01 +0200 +Subject: [PATCH 1/2] aio: fix qemu_bh_schedule() bh->ctx race condition + +qemu_bh_schedule() is supposed to be thread-safe at least the first time +it is called. Unfortunately this is not quite true: + + bh->scheduled = 1; + aio_notify(bh->ctx); + +Since another thread may run the BH callback once it has been scheduled, +there is a race condition if the callback frees the BH before +aio_notify(bh->ctx) has a chance to run. + +Reported-by: Stefan Priebe +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Paolo Bonzini +Tested-by: Stefan Priebe +(cherry picked from commit 924fe1293c3e7a3c787bbdfb351e7f168caee3e9) +Signed-off-by: Michael Roth +(cherry picked from commit df54f5efed9b3be7f40e14113cc1f13f5889e644) +--- + async.c | 14 ++++++++++---- + 1 file changed, 10 insertions(+), 4 deletions(-) + +diff --git a/async.c b/async.c +index 6930185..5b6fe6b 100644 +--- a/async.c ++++ b/async.c +@@ -117,15 +117,21 @@ void qemu_bh_schedule_idle(QEMUBH *bh) + + void qemu_bh_schedule(QEMUBH *bh) + { ++ AioContext *ctx; ++ + if (bh->scheduled) + return; ++ ctx = bh->ctx; + bh->idle = 0; +- /* Make sure that idle & any writes needed by the callback are done +- * before the locations are read in the aio_bh_poll. ++ /* Make sure that: ++ * 1. idle & any writes needed by the callback are done before the ++ * locations are read in the aio_bh_poll. ++ * 2. ctx is loaded before scheduled is set and the callback has a chance ++ * to execute. + */ +- smp_wmb(); ++ smp_mb(); + bh->scheduled = 1; +- aio_notify(bh->ctx); ++ aio_notify(ctx); + } + + +-- +2.9.3 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/0002-aio-strengthen-memory-barriers-for-bottom-half-sched.patch qemu-2.0.0+dfsg/debian/patches/0002-aio-strengthen-memory-barriers-for-bottom-half-sched.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/0002-aio-strengthen-memory-barriers-for-bottom-half-sched.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/0002-aio-strengthen-memory-barriers-for-bottom-half-sched.patch 2016-11-24 09:44:54.000000000 +0000 @@ -0,0 +1,148 @@ +From 5646d5f4cca5e5c9c812cf3733639d0d9fa8466c Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Tue, 7 Apr 2015 17:16:19 +0200 +Subject: [PATCH 2/2] aio: strengthen memory barriers for bottom half + scheduling +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +There are two problems with memory barriers in async.c. The fix is +to use atomic_xchg in order to achieve sequential consistency between +the scheduling of a bottom half and the corresponding execution. + +First, if bh->scheduled is already 1 in qemu_bh_schedule, QEMU does +not execute a memory barrier to order any writes needed by the callback +before the read of bh->scheduled. If the other side sees req->state as +THREAD_ACTIVE, the callback is not invoked and you get deadlock. + +Second, the memory barrier in aio_bh_poll is too weak. Without this +patch, it is possible that bh->scheduled = 0 is not "published" until +after the callback has returned. Another thread wants to schedule the +bottom half, but it sees bh->scheduled = 1 and does nothing. This causes +a lost wakeup. The memory barrier should have been changed to smp_mb() +in commit 924fe12 (aio: fix qemu_bh_schedule() bh->ctx race condition, +2014-06-03) together with qemu_bh_schedule()'s. Guess who reviewed +that patch? + +Both of these involve a store and a load, so they are reproducible on +x86_64 as well. It is however much easier on aarch64, where the +libguestfs test suite triggers the bug fairly easily. Even there the +failure can go away or appear depending on compiler optimization level, +tracing options, or even kernel debugging options. + +Paul Leveille however reported how to trigger the problem within 15 +minutes on x86_64 as well. His (untested) recipe, reproduced here +for reference, is the following: + + 1) Qcow2 (or 3) is critical – raw files alone seem to avoid the problem. + + 2) Use “cache=directsync” rather than the default of + “cache=none” to make it happen easier. + + 3) Use a server with a write-back RAID controller to allow for rapid + IO rates. + + 4) Run a random-access load that (mostly) writes chunks to various + files on the virtual block device. + + a. I use ‘diskload.exe c:25’, a Microsoft HCT load + generator, on Windows VMs. + + b. Iometer can probably be configured to generate a similar load. + + 5) Run multiple VMs in parallel, against the same storage device, + to shake the failure out sooner. + + 6) IvyBridge and Haswell processors for certain; not sure about others. + +A similar patch survived over 12 hours of testing, where an unpatched +QEMU would fail within 15 minutes. + +This bug is, most likely, also the cause of failures in the libguestfs +testsuite on AArch64. + +Thanks to Laszlo Ersek for initially reporting this bug, to Stefan +Hajnoczi for suggesting closer examination of qemu_bh_schedule, and to +Paul for providing test input and a prototype patch. + +Reported-by: Laszlo Ersek +Reported-by: Paul Leveille +Reported-by: John Snow +Signed-off-by: Paolo Bonzini +Message-id: 1428419779-26062-1-git-send-email-pbonzini@redhat.com +Suggested-by: Paul Leveille +Suggested-by: Stefan Hajnoczi +Signed-off-by: Paolo Bonzini +Signed-off-by: Stefan Hajnoczi +(cherry picked from commit e8d3b1a25f284cdf9705b7cf0412281cc9ee3a36) +--- + async.c | 28 ++++++++++++---------------- + 1 file changed, 12 insertions(+), 16 deletions(-) + +diff --git a/async.c b/async.c +index 5b6fe6b..a746c7c 100644 +--- a/async.c ++++ b/async.c +@@ -69,12 +69,13 @@ int aio_bh_poll(AioContext *ctx) + /* Make sure that fetching bh happens before accessing its members */ + smp_read_barrier_depends(); + next = bh->next; +- if (!bh->deleted && bh->scheduled) { +- bh->scheduled = 0; +- /* Paired with write barrier in bh schedule to ensure reading for +- * idle & callbacks coming after bh's scheduling. +- */ +- smp_rmb(); ++ /* The atomic_xchg is paired with the one in qemu_bh_schedule. The ++ * implicit memory barrier ensures that the callback sees all writes ++ * done by the scheduling thread. It also ensures that the scheduling ++ * thread sees the zero before bh->cb has run, and thus will call ++ * aio_notify again if necessary. ++ */ ++ if (!bh->deleted && atomic_xchg(&bh->scheduled, 0)) { + if (!bh->idle) + ret = 1; + bh->idle = 0; +@@ -105,33 +106,28 @@ int aio_bh_poll(AioContext *ctx) + + void qemu_bh_schedule_idle(QEMUBH *bh) + { +- if (bh->scheduled) +- return; + bh->idle = 1; + /* Make sure that idle & any writes needed by the callback are done + * before the locations are read in the aio_bh_poll. + */ +- smp_wmb(); +- bh->scheduled = 1; ++ atomic_mb_set(&bh->scheduled, 1); + } + + void qemu_bh_schedule(QEMUBH *bh) + { + AioContext *ctx; + +- if (bh->scheduled) +- return; + ctx = bh->ctx; + bh->idle = 0; +- /* Make sure that: ++ /* The memory barrier implicit in atomic_xchg makes sure that: + * 1. idle & any writes needed by the callback are done before the + * locations are read in the aio_bh_poll. + * 2. ctx is loaded before scheduled is set and the callback has a chance + * to execute. + */ +- smp_mb(); +- bh->scheduled = 1; +- aio_notify(ctx); ++ if (atomic_xchg(&bh->scheduled, 1) == 0) { ++ aio_notify(ctx); ++ } + } + + +-- +2.9.3 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/02_kfreebsd.patch qemu-2.0.0+dfsg/debian/patches/02_kfreebsd.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/02_kfreebsd.patch 2014-03-27 17:56:09.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/02_kfreebsd.patch 2014-04-17 18:02:52.000000000 +0000 @@ -1,8 +1,13 @@ -Index: qemu-2.0~git-20140327.3768d50/configure -=================================================================== ---- qemu-2.0~git-20140327.3768d50.orig/configure 2014-03-27 12:55:45.402902974 -0500 -+++ qemu-2.0~git-20140327.3768d50/configure 2014-03-27 12:55:45.394902975 -0500 -@@ -3013,6 +3013,14 @@ cat > $TMPC << EOF +kFreeBSD has stub utimensat() up to version 9. Without +this change qemu configure "thinks" that the system has +utimensat support and tries to use (CPP) symbols which +comes in system headers together with utimensat(), +namely UTIME_OMIT and UTIME_NOW, but thoes are not +defined. + +--- a/configure ++++ b/configure +@@ -3043,6 +3043,14 @@ cat > $TMPC << EOF #include #include diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/501-block-raw-posix-fix-disk-corruption-in-try-fiemap qemu-2.0.0+dfsg/debian/patches/501-block-raw-posix-fix-disk-corruption-in-try-fiemap --- qemu-2.0.0~rc1+dfsg/debian/patches/501-block-raw-posix-fix-disk-corruption-in-try-fiemap 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/501-block-raw-posix-fix-disk-corruption-in-try-fiemap 2014-11-20 17:34:26.000000000 +0000 @@ -0,0 +1,36 @@ +commit 38c4d0aea3e1264c86e282d99560330adf2b6e25 +Author: Tony Breeds +Date: Fri Sep 26 09:14:11 2014 +1000 + + block/raw-posix: Fix disk corruption in try_fiemap + + Using fiemap without FIEMAP_FLAG_SYNC is a known corrupter. + + Add the FIEMAP_FLAG_SYNC flag to the FS_IOC_FIEMAP ioctl. This has + the downside of significantly reducing performance. + + Reported-By: Michael Steffens + Signed-off-by: Tony Breeds + Cc: Kevin Wolf + Cc: Markus Armbruster + Cc: Stefan Hajnoczi + Cc: Max Reitz + Cc: Pádraig Brady + Cc: Eric Blake + Reviewed-by: Eric Blake + Reviewed-by: Max Reitz + Signed-off-by: Kevin Wolf + +Index: qemu-2.0.0+dfsg/block/raw-posix.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/block/raw-posix.c ++++ qemu-2.0.0+dfsg/block/raw-posix.c +@@ -1309,7 +1309,7 @@ static int64_t coroutine_fn raw_co_get_b + + f.fm.fm_start = start; + f.fm.fm_length = (int64_t)nb_sectors * BDRV_SECTOR_SIZE; +- f.fm.fm_flags = 0; ++ f.fm.fm_flags = FIEMAP_FLAG_SYNC; + f.fm.fm_extent_count = 1; + f.fm.fm_reserved = 0; + if (ioctl(s->fd, FS_IOC_FIEMAP, &f) == -1) { diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/atomics-add-explicit-compiler-fence-in-__atomic-memo.patch qemu-2.0.0+dfsg/debian/patches/atomics-add-explicit-compiler-fence-in-__atomic-memo.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/atomics-add-explicit-compiler-fence-in-__atomic-memo.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/atomics-add-explicit-compiler-fence-in-__atomic-memo.patch 2017-01-31 10:23:02.000000000 +0000 @@ -0,0 +1,71 @@ +Description: Under heavy load qemu hits bdrv_error_action: Assertion `error >= 0' failed +Origin: upstream, https://github.com/qemu/qemu/commit/3bbf572345c65813f86a8fc434ea1b23beb08e16 +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/qemu/+bug/1655225 +Reviewed-by: Dave Chiluk + +Patch import follows. +--- +From 3bbf572345c65813f86a8fc434ea1b23beb08e16 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Wed, 3 Jun 2015 14:21:20 +0200 +Subject: [PATCH] atomics: add explicit compiler fence in __atomic memory + barriers + +__atomic_thread_fence does not include a compiler barrier; in the +C++11 memory model, fences take effect in combination with other +atomic operations. GCC implements this by making __atomic_load and +__atomic_store access memory as if the pointer was volatile, and +leaves no trace whatsoever of acquire and release fences in the +compiler's intermediate representation. + +In QEMU, we want memory barriers to act on all memory, but at the same +time we would like to use __atomic_thread_fence for portability reasons. +Add compiler barriers manually around the __atomic_thread_fence. + +Message-Id: <1433334080-14912-1-git-send-email-pbonzini@redhat.com> +Reviewed-by: Stefan Hajnoczi +Signed-off-by: Paolo Bonzini +--- + include/qemu/atomic.h | 12 +++++++++--- + 1 file changed, 9 insertions(+), 3 deletions(-) + +diff --git a/include/qemu/atomic.h b/include/qemu/atomic.h +index 98e05ca..bd2c075 100644 +--- a/include/qemu/atomic.h ++++ b/include/qemu/atomic.h +@@ -99,7 +99,13 @@ + + #ifndef smp_wmb + #ifdef __ATOMIC_RELEASE +-#define smp_wmb() __atomic_thread_fence(__ATOMIC_RELEASE) ++/* __atomic_thread_fence does not include a compiler barrier; instead, ++ * the barrier is part of __atomic_load/__atomic_store's "volatile-like" ++ * semantics. If smp_wmb() is a no-op, absence of the barrier means that ++ * the compiler is free to reorder stores on each side of the barrier. ++ * Add one here, and similarly in smp_rmb() and smp_read_barrier_depends(). ++ */ ++#define smp_wmb() ({ barrier(); __atomic_thread_fence(__ATOMIC_RELEASE); barrier(); }) + #else + #define smp_wmb() __sync_synchronize() + #endif +@@ -107,7 +113,7 @@ + + #ifndef smp_rmb + #ifdef __ATOMIC_ACQUIRE +-#define smp_rmb() __atomic_thread_fence(__ATOMIC_ACQUIRE) ++#define smp_rmb() ({ barrier(); __atomic_thread_fence(__ATOMIC_ACQUIRE); barrier(); }) + #else + #define smp_rmb() __sync_synchronize() + #endif +@@ -115,7 +121,7 @@ + + #ifndef smp_read_barrier_depends + #ifdef __ATOMIC_CONSUME +-#define smp_read_barrier_depends() __atomic_thread_fence(__ATOMIC_CONSUME) ++#define smp_read_barrier_depends() ({ barrier(); __atomic_thread_fence(__ATOMIC_CONSUME); barrier(); }) + #else + #define smp_read_barrier_depends() barrier() + #endif +-- +2.7.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4148.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4148.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4148.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4148.patch 2014-08-12 11:50:26.000000000 +0000 @@ -0,0 +1,61 @@ +From 71f7fe48e10a8437c9d42d859389f37157f59980 Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Thu, 3 Apr 2014 19:50:39 +0300 +Subject: [PATCH] virtio-net: fix buffer overflow on invalid state load + +CVE-2013-4148 QEMU 1.0 integer conversion in +virtio_net_load()@hw/net/virtio-net.c + +Deals with loading a corrupted savevm image. + +> n->mac_table.in_use = qemu_get_be32(f); + +in_use is int so it can get negative when assigned 32bit unsigned value. + +> /* MAC_TABLE_ENTRIES may be different from the saved image */ +> if (n->mac_table.in_use <= MAC_TABLE_ENTRIES) { + +passing this check ^^^ + +> qemu_get_buffer(f, n->mac_table.macs, +> n->mac_table.in_use * ETH_ALEN); + +with good in_use value, "n->mac_table.in_use * ETH_ALEN" can get +positive and bigger than mac_table.macs. For example 0x81000000 +satisfies this condition when ETH_ALEN is 6. + +Fix it by making the value unsigned. +For consistency, change first_multi as well. + +Note: all call sites were audited to confirm that +making them unsigned didn't cause any issues: +it turns out we actually never do math on them, +so it's easy to validate because both values are +always <= MAC_TABLE_ENTRIES. + +Reviewed-by: Michael Roth +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Laszlo Ersek +Signed-off-by: Juan Quintela +--- + include/hw/virtio/virtio-net.h | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/include/hw/virtio/virtio-net.h b/include/hw/virtio/virtio-net.h +index df60f16..4b32440 100644 +--- a/include/hw/virtio/virtio-net.h ++++ b/include/hw/virtio/virtio-net.h +@@ -176,8 +176,8 @@ typedef struct VirtIONet { + uint8_t nobcast; + uint8_t vhost_started; + struct { +- int in_use; +- int first_multi; ++ uint32_t in_use; ++ uint32_t first_multi; + uint8_t multi_overflow; + uint8_t uni_overflow; + uint8_t *macs; +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4149.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4149.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4149.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4149.patch 2014-08-12 11:50:32.000000000 +0000 @@ -0,0 +1,57 @@ +From 98f93ddd84800f207889491e0b5d851386b459cf Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Mon, 28 Apr 2014 16:08:21 +0300 +Subject: [PATCH] virtio-net: out-of-bounds buffer write on load + +CVE-2013-4149 QEMU 1.3.0 out-of-bounds buffer write in +virtio_net_load()@hw/net/virtio-net.c + +> } else if (n->mac_table.in_use) { +> uint8_t *buf = g_malloc0(n->mac_table.in_use); + +We are allocating buffer of size n->mac_table.in_use + +> qemu_get_buffer(f, buf, n->mac_table.in_use * ETH_ALEN); + +and read to the n->mac_table.in_use size buffer n->mac_table.in_use * +ETH_ALEN bytes, corrupting memory. + +If adversary controls state then memory written there is controlled +by adversary. + +Reviewed-by: Michael Roth +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Juan Quintela +--- + hw/net/virtio-net.c | 15 +++++++++++---- + 1 files changed, 11 insertions(+), 4 deletions(-) + +diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c +index 0a8cb40..940a7cf 100644 +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -1362,10 +1362,17 @@ static int virtio_net_load(QEMUFile *f, void *opaque, int version_id) + if (n->mac_table.in_use <= MAC_TABLE_ENTRIES) { + qemu_get_buffer(f, n->mac_table.macs, + n->mac_table.in_use * ETH_ALEN); +- } else if (n->mac_table.in_use) { +- uint8_t *buf = g_malloc0(n->mac_table.in_use); +- qemu_get_buffer(f, buf, n->mac_table.in_use * ETH_ALEN); +- g_free(buf); ++ } else { ++ int64_t i; ++ ++ /* Overflow detected - can happen if source has a larger MAC table. ++ * We simply set overflow flag so there's no need to maintain the ++ * table of addresses, discard them all. ++ * Note: 64 bit math to avoid integer overflow. ++ */ ++ for (i = 0; i < (int64_t)n->mac_table.in_use * ETH_ALEN; ++i) { ++ qemu_get_byte(f); ++ } + n->mac_table.multi_overflow = n->mac_table.uni_overflow = 1; + n->mac_table.in_use = 0; + } +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4150.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4150.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4150.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4150.patch 2014-08-12 11:50:44.000000000 +0000 @@ -0,0 +1,54 @@ +From eea750a5623ddac7a61982eec8f1c93481857578 Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Thu, 3 Apr 2014 19:50:56 +0300 +Subject: [PATCH] virtio-net: out-of-bounds buffer write on invalid state load + +CVE-2013-4150 QEMU 1.5.0 out-of-bounds buffer write in +virtio_net_load()@hw/net/virtio-net.c + +This code is in hw/net/virtio-net.c: + + if (n->max_queues > 1) { + if (n->max_queues != qemu_get_be16(f)) { + error_report("virtio-net: different max_queues "); + return -1; + } + + n->curr_queues = qemu_get_be16(f); + for (i = 1; i < n->curr_queues; i++) { + n->vqs[i].tx_waiting = qemu_get_be32(f); + } + } + +Number of vqs is max_queues, so if we get invalid input here, +for example if max_queues = 2, curr_queues = 3, we get +write beyond end of the buffer, with data that comes from +wire. + +This might be used to corrupt qemu memory in hard to predict ways. +Since we have lots of function pointers around, RCE might be possible. + +Signed-off-by: Michael S. Tsirkin +Acked-by: Jason Wang +Reviewed-by: Michael Roth +Signed-off-by: Juan Quintela +--- + hw/net/virtio-net.c | 5 +++++ + 1 files changed, 5 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/virtio-net.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/virtio-net.c 2014-08-12 07:50:40.810465870 -0400 ++++ qemu-2.0.0+dfsg/hw/net/virtio-net.c 2014-08-12 07:50:40.806465870 -0400 +@@ -1414,6 +1414,11 @@ + } + + n->curr_queues = qemu_get_be16(f); ++ if (n->curr_queues > n->max_queues) { ++ error_report("virtio-net: curr_queues %x > max_queues %x", ++ n->curr_queues, n->max_queues); ++ return -1; ++ } + for (i = 1; i < n->curr_queues; i++) { + n->vqs[i].tx_waiting = qemu_get_be32(f); + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4151.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4151.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4151.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4151.patch 2014-08-12 11:50:52.000000000 +0000 @@ -0,0 +1,54 @@ +From cc45995294b92d95319b4782750a3580cabdbc0c Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Thu, 3 Apr 2014 19:51:14 +0300 +Subject: [PATCH] virtio: out-of-bounds buffer write on invalid state load + +CVE-2013-4151 QEMU 1.0 out-of-bounds buffer write in +virtio_load@hw/virtio/virtio.c + +So we have this code since way back when: + + num = qemu_get_be32(f); + + for (i = 0; i < num; i++) { + vdev->vq[i].vring.num = qemu_get_be32(f); + +array of vqs has size VIRTIO_PCI_QUEUE_MAX, so +on invalid input this will write beyond end of buffer. + +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Michael Roth +Signed-off-by: Juan Quintela +--- + hw/virtio/virtio.c | 8 +++++++- + 1 files changed, 7 insertions(+), 1 deletions(-) + +diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c +index aeabf3a..05f05e7 100644 +--- a/hw/virtio/virtio.c ++++ b/hw/virtio/virtio.c +@@ -891,7 +891,8 @@ int virtio_set_features(VirtIODevice *vdev, uint32_t val) + + int virtio_load(VirtIODevice *vdev, QEMUFile *f) + { +- int num, i, ret; ++ int i, ret; ++ uint32_t num; + uint32_t features; + uint32_t supported_features; + BusState *qbus = qdev_get_parent_bus(DEVICE(vdev)); +@@ -919,6 +920,11 @@ int virtio_load(VirtIODevice *vdev, QEMUFile *f) + + num = qemu_get_be32(f); + ++ if (num > VIRTIO_PCI_QUEUE_MAX) { ++ error_report("Invalid number of PCI queues: 0x%x", num); ++ return -1; ++ } ++ + for (i = 0; i < num; i++) { + vdev->vq[i].vring.num = qemu_get_be32(f); + if (k->has_variable_vring_alignment) { +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4526.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4526.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4526.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4526.patch 2014-08-12 11:50:58.000000000 +0000 @@ -0,0 +1,38 @@ +From ae2158ad6ce0845b2fae2a22aa7f19c0d7a71ce5 Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Thu, 3 Apr 2014 19:51:18 +0300 +Subject: [PATCH] ahci: fix buffer overrun on invalid state load + +CVE-2013-4526 + +Within hw/ide/ahci.c, VARRAY refers to ports which is also loaded. So +we use the old version of ports to read the array but then allow any +value for ports. This can cause the code to overflow. + +There's no reason to migrate ports - it never changes. +So just make sure it matches. + +Reported-by: Anthony Liguori +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Peter Maydell +Signed-off-by: Juan Quintela +--- + hw/ide/ahci.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c +index 50327ff..e57c583 100644 +--- a/hw/ide/ahci.c ++++ b/hw/ide/ahci.c +@@ -1293,7 +1293,7 @@ const VMStateDescription vmstate_ahci = { + VMSTATE_UINT32(control_regs.impl, AHCIState), + VMSTATE_UINT32(control_regs.version, AHCIState), + VMSTATE_UINT32(idp_index, AHCIState), +- VMSTATE_INT32(ports, AHCIState), ++ VMSTATE_INT32_EQUAL(ports, AHCIState), + VMSTATE_END_OF_LIST() + }, + }; +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4527.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4527.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4527.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4527.patch 2014-08-12 13:21:43.000000000 +0000 @@ -0,0 +1,109 @@ +Backport of the following commit. +Also includes 5bf81c8d63db0216a4d29dc87f9ce530bb791dd1 +and 4082f0889ba04678fc14816c53e1b9251ea9207e to gain VMSTATE_VALIDATE + +From 3f1c49e2136fa08ab1ef3183fd55def308829584 Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Thu, 3 Apr 2014 19:51:23 +0300 +Subject: [PATCH] hpet: fix buffer overrun on invalid state load + +CVE-2013-4527 hw/timer/hpet.c buffer overrun + +hpet is a VARRAY with a uint8 size but static array of 32 + +To fix, make sure num_timers is valid using VMSTATE_VALID hook. + +Reported-by: Anthony Liguori +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Juan Quintela +--- + hw/timer/hpet.c | 13 +++++++++++++ + 1 files changed, 13 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/timer/hpet.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/timer/hpet.c 2014-08-12 09:20:40.882553414 -0400 ++++ qemu-2.0.0+dfsg/hw/timer/hpet.c 2014-08-12 09:20:40.878553414 -0400 +@@ -239,6 +239,18 @@ + return 0; + } + ++static bool hpet_validate_num_timers(void *opaque, int version_id) ++{ ++ HPETState *s = opaque; ++ ++ if (s->num_timers < HPET_MIN_TIMERS) { ++ return false; ++ } else if (s->num_timers > HPET_MAX_TIMERS) { ++ return false; ++ } ++ return true; ++} ++ + static int hpet_post_load(void *opaque, int version_id) + { + HPETState *s = opaque; +@@ -307,6 +319,7 @@ + VMSTATE_UINT64(isr, HPETState), + VMSTATE_UINT64(hpet_counter, HPETState), + VMSTATE_UINT8_V(num_timers, HPETState, 2), ++ VMSTATE_VALIDATE("num_timers in range", hpet_validate_num_timers), + VMSTATE_STRUCT_VARRAY_UINT8(timer, HPETState, num_timers, 0, + vmstate_hpet_timer, HPETTimer), + VMSTATE_END_OF_LIST() +Index: qemu-2.0.0+dfsg/include/migration/vmstate.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/include/migration/vmstate.h 2014-08-12 09:20:40.882553414 -0400 ++++ qemu-2.0.0+dfsg/include/migration/vmstate.h 2014-08-12 09:20:55.606553653 -0400 +@@ -100,6 +100,7 @@ + VMS_MULTIPLY = 0x200, /* multiply "size" field by field_size */ + VMS_VARRAY_UINT8 = 0x400, /* Array with size in uint8_t field*/ + VMS_VARRAY_UINT32 = 0x800, /* Array with size in uint32_t field*/ ++ VMS_MUST_EXIST = 0x1000, /* Field must exist in input */ + }; + + typedef struct { +@@ -203,6 +204,14 @@ + .offset = vmstate_offset_value(_state, _field, _type), \ + } + ++/* Validate state using a boolean predicate. */ ++#define VMSTATE_VALIDATE(_name, _test) { \ ++ .name = (_name), \ ++ .field_exists = (_test), \ ++ .flags = VMS_ARRAY | VMS_MUST_EXIST, \ ++ .num = 0, /* 0 elements: no data, only run _test */ \ ++} ++ + #define VMSTATE_POINTER(_field, _state, _version, _info, _type) { \ + .name = (stringify(_field)), \ + .version_id = (_version), \ +Index: qemu-2.0.0+dfsg/vmstate.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/vmstate.c 2014-08-12 09:20:14.000000000 -0400 ++++ qemu-2.0.0+dfsg/vmstate.c 2014-08-12 09:20:55.610553653 -0400 +@@ -78,6 +78,10 @@ + return ret; + } + } ++ } else if (field->flags & VMS_MUST_EXIST) { ++ fprintf(stderr, "Input validation failed: %s/%s\n", ++ vmsd->name, field->name); ++ return -1; + } + field++; + } +@@ -138,6 +142,12 @@ + field->info->put(f, addr, size); + } + } ++ } else { ++ if (field->flags & VMS_MUST_EXIST) { ++ fprintf(stderr, "Output state validation failed: %s/%s\n", ++ vmsd->name, field->name); ++ assert(!(field->flags & VMS_MUST_EXIST)); ++ } + } + field++; + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4529.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4529.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4529.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4529.patch 2014-08-12 11:51:09.000000000 +0000 @@ -0,0 +1,57 @@ +From 5f691ff91d323b6f97c6600405a7f9dc115a0ad1 Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Thu, 3 Apr 2014 19:51:31 +0300 +Subject: [PATCH] hw/pci/pcie_aer.c: fix buffer overruns on invalid state load + +4) CVE-2013-4529 +hw/pci/pcie_aer.c pcie aer log can overrun the buffer if log_num is + too large + +There are two issues in this file: +1. log_max from remote can be larger than on local +then buffer will overrun with data coming from state file. +2. log_num can be larger then we get data corruption +again with an overflow but not adversary controlled. + +Fix both issues. + +Reported-by: Anthony Liguori +Reported-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Juan Quintela +--- + hw/pci/pcie_aer.c | 10 +++++++++- + 1 files changed, 9 insertions(+), 1 deletions(-) + +diff --git a/hw/pci/pcie_aer.c b/hw/pci/pcie_aer.c +index 991502e..535be2c 100644 +--- a/hw/pci/pcie_aer.c ++++ b/hw/pci/pcie_aer.c +@@ -795,6 +795,13 @@ static const VMStateDescription vmstate_pcie_aer_err = { + } + }; + ++static bool pcie_aer_state_log_num_valid(void *opaque, int version_id) ++{ ++ PCIEAERLog *s = opaque; ++ ++ return s->log_num <= s->log_max; ++} ++ + const VMStateDescription vmstate_pcie_aer_log = { + .name = "PCIE_AER_ERROR_LOG", + .version_id = 1, +@@ -802,7 +809,8 @@ const VMStateDescription vmstate_pcie_aer_log = { + .minimum_version_id_old = 1, + .fields = (VMStateField[]) { + VMSTATE_UINT16(log_num, PCIEAERLog), +- VMSTATE_UINT16(log_max, PCIEAERLog), ++ VMSTATE_UINT16_EQUAL(log_max, PCIEAERLog), ++ VMSTATE_VALIDATE("log_num <= log_max", pcie_aer_state_log_num_valid), + VMSTATE_STRUCT_VARRAY_POINTER_UINT16(log, PCIEAERLog, log_num, + vmstate_pcie_aer_err, PCIEAERErr), + VMSTATE_END_OF_LIST() +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4530.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4530.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4530.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4530.patch 2014-08-12 11:51:15.000000000 +0000 @@ -0,0 +1,52 @@ +From d8d0a0bc7e194300e53a346d25fe5724fd588387 Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Thu, 3 Apr 2014 19:51:35 +0300 +Subject: [PATCH] pl022: fix buffer overun on invalid state load + +CVE-2013-4530 + +pl022.c did not bounds check tx_fifo_head and +rx_fifo_head after loading them from file and +before they are used to dereference array. + +Reported-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Juan Quintela +--- + hw/ssi/pl022.c | 14 ++++++++++++++ + 1 files changed, 14 insertions(+), 0 deletions(-) + +diff --git a/hw/ssi/pl022.c b/hw/ssi/pl022.c +index fd479ef..b19bc71 100644 +--- a/hw/ssi/pl022.c ++++ b/hw/ssi/pl022.c +@@ -240,11 +240,25 @@ static const MemoryRegionOps pl022_ops = { + .endianness = DEVICE_NATIVE_ENDIAN, + }; + ++static int pl022_post_load(void *opaque, int version_id) ++{ ++ PL022State *s = opaque; ++ ++ if (s->tx_fifo_head < 0 || ++ s->tx_fifo_head >= ARRAY_SIZE(s->tx_fifo) || ++ s->rx_fifo_head < 0 || ++ s->rx_fifo_head >= ARRAY_SIZE(s->rx_fifo)) { ++ return -1; ++ } ++ return 0; ++} ++ + static const VMStateDescription vmstate_pl022 = { + .name = "pl022_ssp", + .version_id = 1, + .minimum_version_id = 1, + .minimum_version_id_old = 1, ++ .post_load = pl022_post_load, + .fields = (VMStateField[]) { + VMSTATE_UINT32(cr0, PL022State), + VMSTATE_UINT32(cr1, PL022State), +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4531.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4531.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4531.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4531.patch 2014-08-12 11:51:23.000000000 +0000 @@ -0,0 +1,51 @@ +From d2ef4b61fe6d33d2a5dcf100a9b9440de341ad62 Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Thu, 3 Apr 2014 19:51:42 +0300 +Subject: [PATCH] vmstate: fix buffer overflow in target-arm/machine.c + +CVE-2013-4531 + +cpreg_vmstate_indexes is a VARRAY_INT32. A negative value for +cpreg_vmstate_array_len will cause a buffer overflow. + +VMSTATE_INT32_LE was supposed to protect against this +but doesn't because it doesn't validate that input is +non-negative. + +Fix this macro to valide the value appropriately. + +The only other user of VMSTATE_INT32_LE doesn't +ever use negative numbers so it doesn't care. + +Reported-by: Anthony Liguori +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Juan Quintela +--- + vmstate.c | 7 ++++--- + 1 files changed, 4 insertions(+), 3 deletions(-) + +Index: qemu-2.0.0+dfsg/vmstate.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/vmstate.c 2014-08-12 07:51:20.722466517 -0400 ++++ qemu-2.0.0+dfsg/vmstate.c 2014-08-12 07:51:20.718466517 -0400 +@@ -323,8 +323,9 @@ + .put = put_int32, + }; + +-/* 32 bit int. Check that the received value is less than or equal to +- the one in the field */ ++/* 32 bit int. Check that the received value is non-negative ++ * and less than or equal to the one in the field. ++ */ + + static int get_int32_le(QEMUFile *f, void *pv, size_t size) + { +@@ -332,7 +333,7 @@ + int32_t loaded; + qemu_get_sbe32s(f, &loaded); + +- if (loaded <= *cur) { ++ if (loaded >= 0 && loaded <= *cur) { + *cur = loaded; + return 0; + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4532.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4532.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4532.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4532.patch 2014-08-12 12:20:51.000000000 +0000 @@ -0,0 +1,444 @@ +Description: fix buffer overrun on incoming migration in stellaris_enet +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=5c10495ab1546d5d12b51a97817051e9ec98d0f6 +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=7fd5f064d1c1a827a95ffe678418b3d5b8d2f108 +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=c6fa443b3dab9f49fb157b0164f5852fde68ed3b +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=a9171c4fb570b9c6f65955de03d3e38d2e9b0fdf +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=eacd606ca726b15ce9a5f0871f0c6598dbc8d6ae +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=889ac2a32fd803f7222524d8f56aded1c3cbad3c +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=2e1198672759eda6e122ff38fcf6df06f27e0fe2 + +Index: qemu-2.0.0+dfsg/hw/net/stellaris_enet.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/stellaris_enet.c 2014-08-12 08:02:39.000000000 -0400 ++++ qemu-2.0.0+dfsg/hw/net/stellaris_enet.c 2014-08-12 08:03:27.830478305 -0400 +@@ -47,6 +47,11 @@ + OBJECT_CHECK(stellaris_enet_state, (obj), TYPE_STELLARIS_ENET) + + typedef struct { ++ uint8_t data[2048]; ++ uint32_t len; ++} StellarisEnetRxFrame; ++ ++typedef struct { + SysBusDevice parent_obj; + + uint32_t ris; +@@ -59,29 +64,159 @@ + uint32_t mtxd; + uint32_t mrxd; + uint32_t np; +- int tx_frame_len; +- int tx_fifo_len; ++ uint32_t tx_fifo_len; + uint8_t tx_fifo[2048]; + /* Real hardware has a 2k fifo, which works out to be at most 31 packets. + We implement a full 31 packet fifo. */ +- struct { +- uint8_t data[2048]; +- int len; +- } rx[31]; +- uint8_t *rx_fifo; +- int rx_fifo_len; +- int next_packet; ++ StellarisEnetRxFrame rx[31]; ++ uint32_t rx_fifo_offset; ++ uint32_t next_packet; + NICState *nic; + NICConf conf; + qemu_irq irq; + MemoryRegion mmio; + } stellaris_enet_state; + ++static const VMStateDescription vmstate_rx_frame = { ++ .name = "stellaris_enet/rx_frame", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT8_ARRAY(data, StellarisEnetRxFrame, 2048), ++ VMSTATE_UINT32(len, StellarisEnetRxFrame), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ ++static int stellaris_enet_post_load(void *opaque, int version_id) ++{ ++ stellaris_enet_state *s = opaque; ++ int i; ++ ++ /* Sanitize inbound state. Note that next_packet is an index but ++ * np is a size; hence their valid upper bounds differ. ++ */ ++ if (s->next_packet >= ARRAY_SIZE(s->rx)) { ++ return -1; ++ } ++ ++ if (s->np > ARRAY_SIZE(s->rx)) { ++ return -1; ++ } ++ ++ for (i = 0; i < ARRAY_SIZE(s->rx); i++) { ++ if (s->rx[i].len > ARRAY_SIZE(s->rx[i].data)) { ++ return -1; ++ } ++ } ++ ++ if (s->rx_fifo_offset > ARRAY_SIZE(s->rx[0].data) - 4) { ++ return -1; ++ } ++ ++ if (s->tx_fifo_len > ARRAY_SIZE(s->tx_fifo)) { ++ return -1; ++ } ++ ++ return 0; ++} ++ ++static const VMStateDescription vmstate_stellaris_enet = { ++ .name = "stellaris_enet", ++ .version_id = 2, ++ .minimum_version_id = 2, ++ .post_load = stellaris_enet_post_load, ++ .fields = (VMStateField[]) { ++ VMSTATE_UINT32(ris, stellaris_enet_state), ++ VMSTATE_UINT32(im, stellaris_enet_state), ++ VMSTATE_UINT32(rctl, stellaris_enet_state), ++ VMSTATE_UINT32(tctl, stellaris_enet_state), ++ VMSTATE_UINT32(thr, stellaris_enet_state), ++ VMSTATE_UINT32(mctl, stellaris_enet_state), ++ VMSTATE_UINT32(mdv, stellaris_enet_state), ++ VMSTATE_UINT32(mtxd, stellaris_enet_state), ++ VMSTATE_UINT32(mrxd, stellaris_enet_state), ++ VMSTATE_UINT32(np, stellaris_enet_state), ++ VMSTATE_UINT32(tx_fifo_len, stellaris_enet_state), ++ VMSTATE_UINT8_ARRAY(tx_fifo, stellaris_enet_state, 2048), ++ VMSTATE_STRUCT_ARRAY(rx, stellaris_enet_state, 31, 1, ++ vmstate_rx_frame, StellarisEnetRxFrame), ++ VMSTATE_UINT32(rx_fifo_offset, stellaris_enet_state), ++ VMSTATE_UINT32(next_packet, stellaris_enet_state), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ + static void stellaris_enet_update(stellaris_enet_state *s) + { + qemu_set_irq(s->irq, (s->ris & s->im) != 0); + } + ++/* Return the data length of the packet currently being assembled ++ * in the TX fifo. ++ */ ++static inline int stellaris_txpacket_datalen(stellaris_enet_state *s) ++{ ++ return s->tx_fifo[0] | (s->tx_fifo[1] << 8); ++} ++ ++/* Return true if the packet currently in the TX FIFO is complete, ++* ie the FIFO holds enough bytes for the data length, ethernet header, ++* payload and optionally CRC. ++*/ ++static inline bool stellaris_txpacket_complete(stellaris_enet_state *s) ++{ ++ int framelen = stellaris_txpacket_datalen(s); ++ framelen += 16; ++ if (!(s->tctl & SE_TCTL_CRC)) { ++ framelen += 4; ++ } ++ /* Cover the corner case of a 2032 byte payload with auto-CRC disabled: ++ * this requires more bytes than will fit in the FIFO. It's not totally ++ * clear how the h/w handles this, but if using threshold-based TX ++ * it will definitely try to transmit something. ++ */ ++ framelen = MIN(framelen, ARRAY_SIZE(s->tx_fifo)); ++ return s->tx_fifo_len >= framelen; ++} ++ ++/* Return true if the TX FIFO threshold is enabled and the FIFO ++ * has filled enough to reach it. ++ */ ++static inline bool stellaris_tx_thr_reached(stellaris_enet_state *s) ++{ ++ return (s->thr < 0x3f && ++ (s->tx_fifo_len >= 4 * (s->thr * 8 + 1))); ++} ++ ++/* Send the packet currently in the TX FIFO */ ++static void stellaris_enet_send(stellaris_enet_state *s) ++{ ++ int framelen = stellaris_txpacket_datalen(s); ++ ++ /* Ethernet header is in the FIFO but not in the datacount. ++ * We don't implement explicit CRC, so just ignore any ++ * CRC value in the FIFO. ++ */ ++ framelen += 14; ++ if ((s->tctl & SE_TCTL_PADEN) && framelen < 60) { ++ memset(&s->tx_fifo[framelen + 2], 0, 60 - framelen); ++ framelen = 60; ++ } ++ /* This MIN will have no effect unless the FIFO data is corrupt ++ * (eg bad data from an incoming migration); otherwise the check ++ * on the datalen at the start of writing the data into the FIFO ++ * will have caught this. Silently write a corrupt half-packet, ++ * which is what the hardware does in FIFO underrun situations. ++ */ ++ framelen = MIN(framelen, ARRAY_SIZE(s->tx_fifo) - 2); ++ qemu_send_packet(qemu_get_queue(s->nic), s->tx_fifo + 2, framelen); ++ s->tx_fifo_len = 0; ++ s->ris |= SE_INT_TXEMP; ++ stellaris_enet_update(s); ++ DPRINTF("Done TX\n"); ++} ++ + /* TODO: Implement MAC address filtering. */ + static ssize_t stellaris_enet_receive(NetClientState *nc, const uint8_t *buf, size_t size) + { +@@ -97,7 +232,7 @@ + return -1; + } + +- DPRINTF("Received packet len=%d\n", size); ++ DPRINTF("Received packet len=%zu\n", size); + n = s->next_packet + s->np; + if (n >= 31) + n -= 31; +@@ -152,21 +287,21 @@ + case 0x0c: /* TCTL */ + return s->tctl; + case 0x10: /* DATA */ +- if (s->rx_fifo_len == 0) { +- if (s->np == 0) { +- BADF("RX underflow\n"); +- return 0; +- } +- s->rx_fifo_len = s->rx[s->next_packet].len; +- s->rx_fifo = s->rx[s->next_packet].data; +- DPRINTF("RX FIFO start packet len=%d\n", s->rx_fifo_len); ++ { ++ uint8_t *rx_fifo; ++ ++ if (s->np == 0) { ++ BADF("RX underflow\n"); ++ return 0; + } +- val = s->rx_fifo[0] | (s->rx_fifo[1] << 8) | (s->rx_fifo[2] << 16) +- | (s->rx_fifo[3] << 24); +- s->rx_fifo += 4; +- s->rx_fifo_len -= 4; +- if (s->rx_fifo_len <= 0) { +- s->rx_fifo_len = 0; ++ ++ rx_fifo = s->rx[s->next_packet].data + s->rx_fifo_offset; ++ ++ val = rx_fifo[0] | (rx_fifo[1] << 8) | (rx_fifo[2] << 16) ++ | (rx_fifo[3] << 24); ++ s->rx_fifo_offset += 4; ++ if (s->rx_fifo_offset >= s->rx[s->next_packet].len) { ++ s->rx_fifo_offset = 0; + s->next_packet++; + if (s->next_packet >= 31) + s->next_packet = 0; +@@ -174,6 +309,7 @@ + DPRINTF("RX done np=%d\n", s->np); + } + return val; ++ } + case 0x14: /* IA0 */ + return s->conf.macaddr.a[0] | (s->conf.macaddr.a[1] << 8) + | (s->conf.macaddr.a[2] << 16) +@@ -212,22 +348,23 @@ + switch (offset) { + case 0x00: /* IACK */ + s->ris &= ~value; +- DPRINTF("IRQ ack %02x/%02x\n", value, s->ris); ++ DPRINTF("IRQ ack %02" PRIx64 "/%02x\n", value, s->ris); + stellaris_enet_update(s); + /* Clearing TXER also resets the TX fifo. */ +- if (value & SE_INT_TXER) +- s->tx_frame_len = -1; ++ if (value & SE_INT_TXER) { ++ s->tx_fifo_len = 0; ++ } + break; + case 0x04: /* IM */ +- DPRINTF("IRQ mask %02x/%02x\n", value, s->ris); ++ DPRINTF("IRQ mask %02" PRIx64 "/%02x\n", value, s->ris); + s->im = value; + stellaris_enet_update(s); + break; + case 0x08: /* RCTL */ + s->rctl = value; + if (value & SE_RCTL_RSTFIFO) { +- s->rx_fifo_len = 0; + s->np = 0; ++ s->rx_fifo_offset = 0; + stellaris_enet_update(s); + } + break; +@@ -235,43 +372,26 @@ + s->tctl = value; + break; + case 0x10: /* DATA */ +- if (s->tx_frame_len == -1) { +- s->tx_frame_len = value & 0xffff; +- if (s->tx_frame_len > 2032) { +- DPRINTF("TX frame too long (%d)\n", s->tx_frame_len); +- s->tx_frame_len = 0; ++ if (s->tx_fifo_len == 0) { ++ /* The first word is special, it contains the data length */ ++ int framelen = value & 0xffff; ++ if (framelen > 2032) { ++ DPRINTF("TX frame too long (%d)\n", framelen); + s->ris |= SE_INT_TXER; + stellaris_enet_update(s); +- } else { +- DPRINTF("Start TX frame len=%d\n", s->tx_frame_len); +- /* The value written does not include the ethernet header. */ +- s->tx_frame_len += 14; +- if ((s->tctl & SE_TCTL_CRC) == 0) +- s->tx_frame_len += 4; +- s->tx_fifo_len = 0; +- s->tx_fifo[s->tx_fifo_len++] = value >> 16; +- s->tx_fifo[s->tx_fifo_len++] = value >> 24; ++ break; + } +- } else { ++ } ++ ++ if (s->tx_fifo_len + 4 <= ARRAY_SIZE(s->tx_fifo)) { + s->tx_fifo[s->tx_fifo_len++] = value; + s->tx_fifo[s->tx_fifo_len++] = value >> 8; + s->tx_fifo[s->tx_fifo_len++] = value >> 16; + s->tx_fifo[s->tx_fifo_len++] = value >> 24; +- if (s->tx_fifo_len >= s->tx_frame_len) { +- /* We don't implement explicit CRC, so just chop it off. */ +- if ((s->tctl & SE_TCTL_CRC) == 0) +- s->tx_frame_len -= 4; +- if ((s->tctl & SE_TCTL_PADEN) && s->tx_frame_len < 60) { +- memset(&s->tx_fifo[s->tx_frame_len], 0, 60 - s->tx_frame_len); +- s->tx_fifo_len = 60; +- } +- qemu_send_packet(qemu_get_queue(s->nic), s->tx_fifo, +- s->tx_frame_len); +- s->tx_frame_len = -1; +- s->ris |= SE_INT_TXEMP; +- stellaris_enet_update(s); +- DPRINTF("Done TX\n"); +- } ++ } ++ ++ if (stellaris_tx_thr_reached(s) && stellaris_txpacket_complete(s)) { ++ stellaris_enet_send(s); + } + break; + case 0x14: /* IA0 */ +@@ -299,9 +419,13 @@ + case 0x2c: /* MTXD */ + s->mtxd = value & 0xff; + break; ++ case 0x38: /* TR */ ++ if (value & 1) { ++ stellaris_enet_send(s); ++ } ++ break; + case 0x30: /* MRXD */ + case 0x34: /* NP */ +- case 0x38: /* TR */ + /* Ignored. */ + case 0x3c: /* Undocuented: Timestamp? */ + /* Ignored. */ +@@ -324,68 +448,7 @@ + s->im = SE_INT_PHY | SE_INT_MD | SE_INT_RXER | SE_INT_FOV | SE_INT_TXEMP + | SE_INT_TXER | SE_INT_RX; + s->thr = 0x3f; +- s->tx_frame_len = -1; +-} +- +-static void stellaris_enet_save(QEMUFile *f, void *opaque) +-{ +- stellaris_enet_state *s = (stellaris_enet_state *)opaque; +- int i; +- +- qemu_put_be32(f, s->ris); +- qemu_put_be32(f, s->im); +- qemu_put_be32(f, s->rctl); +- qemu_put_be32(f, s->tctl); +- qemu_put_be32(f, s->thr); +- qemu_put_be32(f, s->mctl); +- qemu_put_be32(f, s->mdv); +- qemu_put_be32(f, s->mtxd); +- qemu_put_be32(f, s->mrxd); +- qemu_put_be32(f, s->np); +- qemu_put_be32(f, s->tx_frame_len); +- qemu_put_be32(f, s->tx_fifo_len); +- qemu_put_buffer(f, s->tx_fifo, sizeof(s->tx_fifo)); +- for (i = 0; i < 31; i++) { +- qemu_put_be32(f, s->rx[i].len); +- qemu_put_buffer(f, s->rx[i].data, sizeof(s->rx[i].data)); +- +- } +- qemu_put_be32(f, s->next_packet); +- qemu_put_be32(f, s->rx_fifo - s->rx[s->next_packet].data); +- qemu_put_be32(f, s->rx_fifo_len); +-} +- +-static int stellaris_enet_load(QEMUFile *f, void *opaque, int version_id) +-{ +- stellaris_enet_state *s = (stellaris_enet_state *)opaque; +- int i; +- +- if (version_id != 1) +- return -EINVAL; +- +- s->ris = qemu_get_be32(f); +- s->im = qemu_get_be32(f); +- s->rctl = qemu_get_be32(f); +- s->tctl = qemu_get_be32(f); +- s->thr = qemu_get_be32(f); +- s->mctl = qemu_get_be32(f); +- s->mdv = qemu_get_be32(f); +- s->mtxd = qemu_get_be32(f); +- s->mrxd = qemu_get_be32(f); +- s->np = qemu_get_be32(f); +- s->tx_frame_len = qemu_get_be32(f); +- s->tx_fifo_len = qemu_get_be32(f); +- qemu_get_buffer(f, s->tx_fifo, sizeof(s->tx_fifo)); +- for (i = 0; i < 31; i++) { +- s->rx[i].len = qemu_get_be32(f); +- qemu_get_buffer(f, s->rx[i].data, sizeof(s->rx[i].data)); +- +- } +- s->next_packet = qemu_get_be32(f); +- s->rx_fifo = s->rx[s->next_packet].data + qemu_get_be32(f); +- s->rx_fifo_len = qemu_get_be32(f); +- +- return 0; ++ s->tx_fifo_len = 0; + } + + static void stellaris_enet_cleanup(NetClientState *nc) +@@ -419,8 +482,6 @@ + qemu_format_nic_info_str(qemu_get_queue(s->nic), s->conf.macaddr.a); + + stellaris_enet_reset(s); +- register_savevm(dev, "stellaris_enet", -1, 1, +- stellaris_enet_save, stellaris_enet_load, s); + return 0; + } + +@@ -428,8 +489,6 @@ + { + stellaris_enet_state *s = STELLARIS_ENET(dev); + +- unregister_savevm(DEVICE(s), "stellaris_enet", s); +- + memory_region_destroy(&s->mmio); + } + +@@ -446,6 +505,7 @@ + k->init = stellaris_enet_init; + dc->unrealize = stellaris_enet_unrealize; + dc->props = stellaris_enet_properties; ++ dc->vmsd = &vmstate_stellaris_enet; + } + + static const TypeInfo stellaris_enet_info = { diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4533.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4533.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4533.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4533.patch 2014-08-12 12:04:46.000000000 +0000 @@ -0,0 +1,53 @@ +From caa881abe0e01f9931125a0977ec33c5343e4aa7 Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Thu, 3 Apr 2014 19:51:57 +0300 +Subject: [PATCH] pxa2xx: avoid buffer overrun on incoming migration + +CVE-2013-4533 + +s->rx_level is read from the wire and used to determine how many bytes +to subsequently read into s->rx_fifo[]. If s->rx_level exceeds the +length of s->rx_fifo[] the buffer can be overrun with arbitrary data +from the wire. + +Fix this by validating rx_level against the size of s->rx_fifo. + +Cc: Don Koch +Reported-by: Michael Roth +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Peter Maydell +Reviewed-by: Don Koch +Signed-off-by: Juan Quintela +--- + hw/arm/pxa2xx.c | 8 ++++++-- + 1 files changed, 6 insertions(+), 2 deletions(-) + +diff --git a/hw/arm/pxa2xx.c b/hw/arm/pxa2xx.c +index 0429148..e0cd847 100644 +--- a/hw/arm/pxa2xx.c ++++ b/hw/arm/pxa2xx.c +@@ -732,7 +732,7 @@ static void pxa2xx_ssp_save(QEMUFile *f, void *opaque) + static int pxa2xx_ssp_load(QEMUFile *f, void *opaque, int version_id) + { + PXA2xxSSPState *s = (PXA2xxSSPState *) opaque; +- int i; ++ int i, v; + + s->enable = qemu_get_be32(f); + +@@ -746,7 +746,11 @@ static int pxa2xx_ssp_load(QEMUFile *f, void *opaque, int version_id) + qemu_get_8s(f, &s->ssrsa); + qemu_get_8s(f, &s->ssacd); + +- s->rx_level = qemu_get_byte(f); ++ v = qemu_get_byte(f); ++ if (v < 0 || v > ARRAY_SIZE(s->rx_fifo)) { ++ return -EINVAL; ++ } ++ s->rx_level = v; + s->rx_start = 0; + for (i = 0; i < s->rx_level; i ++) + s->rx_fifo[i] = qemu_get_byte(f); +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4534.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4534.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4534.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4534.patch 2014-08-12 12:04:50.000000000 +0000 @@ -0,0 +1,74 @@ +From 73d963c0a75cb99c6aaa3f6f25e427aa0b35a02e Mon Sep 17 00:00:00 2001 +From: Michael Roth +Date: Mon, 28 Apr 2014 16:08:17 +0300 +Subject: [PATCH] openpic: avoid buffer overrun on incoming migration + +CVE-2013-4534 + +opp->nb_cpus is read from the wire and used to determine how many +IRQDest elements to read into opp->dst[]. If the value exceeds the +length of opp->dst[], MAX_CPU, opp->dst[] can be overrun with arbitrary +data from the wire. + +Fix this by failing migration if the value read from the wire exceeds +MAX_CPU. + +Signed-off-by: Michael Roth +Reviewed-by: Alexander Graf +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Juan Quintela +--- + hw/intc/openpic.c | 16 ++++++++++++++-- + 1 files changed, 14 insertions(+), 2 deletions(-) + +diff --git a/hw/intc/openpic.c b/hw/intc/openpic.c +index be76fbd..17136c9 100644 +--- a/hw/intc/openpic.c ++++ b/hw/intc/openpic.c +@@ -41,6 +41,7 @@ + #include "hw/sysbus.h" + #include "hw/pci/msi.h" + #include "qemu/bitops.h" ++#include "qapi/qmp/qerror.h" + + //#define DEBUG_OPENPIC + +@@ -1416,7 +1417,7 @@ static void openpic_load_IRQ_queue(QEMUFile* f, IRQQueue *q) + static int openpic_load(QEMUFile* f, void *opaque, int version_id) + { + OpenPICState *opp = (OpenPICState *)opaque; +- unsigned int i; ++ unsigned int i, nb_cpus; + + if (version_id != 1) { + return -EINVAL; +@@ -1428,7 +1429,11 @@ static int openpic_load(QEMUFile* f, void *opaque, int version_id) + qemu_get_be32s(f, &opp->spve); + qemu_get_be32s(f, &opp->tfrr); + +- qemu_get_be32s(f, &opp->nb_cpus); ++ qemu_get_be32s(f, &nb_cpus); ++ if (opp->nb_cpus != nb_cpus) { ++ return -EINVAL; ++ } ++ assert(nb_cpus > 0 && nb_cpus <= MAX_CPU); + + for (i = 0; i < opp->nb_cpus; i++) { + qemu_get_sbe32s(f, &opp->dst[i].ctpr); +@@ -1567,6 +1572,13 @@ static void openpic_realize(DeviceState *dev, Error **errp) + {NULL} + }; + ++ if (opp->nb_cpus > MAX_CPU) { ++ error_set(errp, QERR_PROPERTY_VALUE_OUT_OF_RANGE, ++ TYPE_OPENPIC, "nb_cpus", (uint64_t)opp->nb_cpus, ++ (uint64_t)0, (uint64_t)MAX_CPU); ++ return; ++ } ++ + switch (opp->model) { + case OPENPIC_MODEL_FSL_MPIC_20: + default: +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4535_4536.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4535_4536.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4535_4536.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4535_4536.patch 2014-08-12 12:24:21.000000000 +0000 @@ -0,0 +1,21 @@ +Description: fix buffer overrun on incoming migration in virtio +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=36cf2a37132c7f01fa9adb5f95f5312b27742fd4 +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=937251408051e0489f78e4db3c92e045b147b38b + +Index: qemu-2.0.0+dfsg/hw/virtio/virtio.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/virtio/virtio.c 2014-08-12 08:04:32.874479360 -0400 ++++ qemu-2.0.0+dfsg/hw/virtio/virtio.c 2014-08-12 08:05:21.142480142 -0400 +@@ -430,6 +430,12 @@ + unsigned int i; + hwaddr len; + ++ if (num_sg > VIRTQUEUE_MAX_SIZE) { ++ error_report("virtio: map attempt out of bounds: %zd > %d", ++ num_sg, VIRTQUEUE_MAX_SIZE); ++ exit(1); ++ } ++ + for (i = 0; i < num_sg; i++) { + len = sg[i].iov_len; + sg[i].iov_base = cpu_physical_memory_map(addr[i], &len, is_write); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4537.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4537.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4537.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4537.patch 2014-08-12 12:05:42.000000000 +0000 @@ -0,0 +1,43 @@ +From a9c380db3b8c6af19546a68145c8d1438a09c92b Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Mon, 28 Apr 2014 16:08:14 +0300 +Subject: [PATCH] ssi-sd: fix buffer overrun on invalid state load + +CVE-2013-4537 + +s->arglen is taken from wire and used as idx +in ssi_sd_transfer(). + +Validate it before access. + +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Juan Quintela +--- + hw/sd/ssi-sd.c | 9 +++++++++ + 1 files changed, 9 insertions(+), 0 deletions(-) + +diff --git a/hw/sd/ssi-sd.c b/hw/sd/ssi-sd.c +index 3273c8a..b012e57 100644 +--- a/hw/sd/ssi-sd.c ++++ b/hw/sd/ssi-sd.c +@@ -230,8 +230,17 @@ static int ssi_sd_load(QEMUFile *f, void *opaque, int version_id) + for (i = 0; i < 5; i++) + s->response[i] = qemu_get_be32(f); + s->arglen = qemu_get_be32(f); ++ if (s->mode == SSI_SD_CMDARG && ++ (s->arglen < 0 || s->arglen >= ARRAY_SIZE(s->cmdarg))) { ++ return -EINVAL; ++ } + s->response_pos = qemu_get_be32(f); + s->stopping = qemu_get_be32(f); ++ if (s->mode == SSI_SD_RESPONSE && ++ (s->response_pos < 0 || s->response_pos >= ARRAY_SIZE(s->response) || ++ (!s->stopping && s->arglen > ARRAY_SIZE(s->response)))) { ++ return -EINVAL; ++ } + + ss->cs = qemu_get_be32(f); + +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4538.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4538.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4538.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4538.patch 2014-08-12 12:05:46.000000000 +0000 @@ -0,0 +1,79 @@ +From ead7a57df37d2187813a121308213f41591bd811 Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Thu, 3 Apr 2014 19:52:05 +0300 +Subject: [PATCH] ssd0323: fix buffer overun on invalid state load + +CVE-2013-4538 + +s->cmd_len used as index in ssd0323_transfer() to store 32-bit field. +Possible this field might then be supplied by guest to overwrite a +return addr somewhere. Same for row/col fields, which are indicies into +framebuffer array. + +To fix validate after load. + +Additionally, validate that the row/col_start/end are within bounds; +otherwise the guest can provoke an overrun by either setting the _end +field so large that the row++ increments just walk off the end of the +array, or by setting the _start value to something bogus and then +letting the "we hit end of row" logic reset row to row_start. + +For completeness, validate mode as well. + +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Peter Maydell +Signed-off-by: Juan Quintela +--- + hw/display/ssd0323.c | 24 ++++++++++++++++++++++++ + 1 files changed, 24 insertions(+), 0 deletions(-) + +diff --git a/hw/display/ssd0323.c b/hw/display/ssd0323.c +index 971152e..9727007 100644 +--- a/hw/display/ssd0323.c ++++ b/hw/display/ssd0323.c +@@ -312,18 +312,42 @@ static int ssd0323_load(QEMUFile *f, void *opaque, int version_id) + return -EINVAL; + + s->cmd_len = qemu_get_be32(f); ++ if (s->cmd_len < 0 || s->cmd_len > ARRAY_SIZE(s->cmd_data)) { ++ return -EINVAL; ++ } + s->cmd = qemu_get_be32(f); + for (i = 0; i < 8; i++) + s->cmd_data[i] = qemu_get_be32(f); + s->row = qemu_get_be32(f); ++ if (s->row < 0 || s->row >= 80) { ++ return -EINVAL; ++ } + s->row_start = qemu_get_be32(f); ++ if (s->row_start < 0 || s->row_start >= 80) { ++ return -EINVAL; ++ } + s->row_end = qemu_get_be32(f); ++ if (s->row_end < 0 || s->row_end >= 80) { ++ return -EINVAL; ++ } + s->col = qemu_get_be32(f); ++ if (s->col < 0 || s->col >= 64) { ++ return -EINVAL; ++ } + s->col_start = qemu_get_be32(f); ++ if (s->col_start < 0 || s->col_start >= 64) { ++ return -EINVAL; ++ } + s->col_end = qemu_get_be32(f); ++ if (s->col_end < 0 || s->col_end >= 64) { ++ return -EINVAL; ++ } + s->redraw = qemu_get_be32(f); + s->remap = qemu_get_be32(f); + s->mode = qemu_get_be32(f); ++ if (s->mode != SSD0323_CMD && s->mode != SSD0323_DATA) { ++ return -EINVAL; ++ } + qemu_get_buffer(f, s->framebuffer, sizeof(s->framebuffer)); + + ss->cs = qemu_get_be32(f); +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4539.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4539.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4539.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4539.patch 2014-08-12 12:05:51.000000000 +0000 @@ -0,0 +1,52 @@ +From 5193be3be35f29a35bc465036cd64ad60d43385f Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Thu, 3 Apr 2014 19:52:09 +0300 +Subject: [PATCH] tsc210x: fix buffer overrun on invalid state load +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf8 +Content-Transfer-Encoding: 8bit + +CVE-2013-4539 + +s->precision, nextprecision, function and nextfunction +come from wire and are used +as idx into resolution[] in TSC_CUT_RESOLUTION. + +Validate after load to avoid buffer overrun. + +Cc: Andreas Färber +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Juan Quintela +--- + hw/input/tsc210x.c | 12 ++++++++++++ + 1 files changed, 12 insertions(+), 0 deletions(-) + +diff --git a/hw/input/tsc210x.c b/hw/input/tsc210x.c +index 485c9e5..aa5b688 100644 +--- a/hw/input/tsc210x.c ++++ b/hw/input/tsc210x.c +@@ -1070,9 +1070,21 @@ static int tsc210x_load(QEMUFile *f, void *opaque, int version_id) + s->enabled = qemu_get_byte(f); + s->host_mode = qemu_get_byte(f); + s->function = qemu_get_byte(f); ++ if (s->function < 0 || s->function >= ARRAY_SIZE(mode_regs)) { ++ return -EINVAL; ++ } + s->nextfunction = qemu_get_byte(f); ++ if (s->nextfunction < 0 || s->nextfunction >= ARRAY_SIZE(mode_regs)) { ++ return -EINVAL; ++ } + s->precision = qemu_get_byte(f); ++ if (s->precision < 0 || s->precision >= ARRAY_SIZE(resolution)) { ++ return -EINVAL; ++ } + s->nextprecision = qemu_get_byte(f); ++ if (s->nextprecision < 0 || s->nextprecision >= ARRAY_SIZE(resolution)) { ++ return -EINVAL; ++ } + s->filter = qemu_get_byte(f); + s->pin_func = qemu_get_byte(f); + s->ref = qemu_get_byte(f); +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4540.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4540.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4540.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4540.patch 2014-08-12 12:05:55.000000000 +0000 @@ -0,0 +1,56 @@ +From 52f91c3723932f8340fe36c8ec8b18a757c37b2b Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Thu, 3 Apr 2014 19:52:13 +0300 +Subject: [PATCH] zaurus: fix buffer overrun on invalid state load + +CVE-2013-4540 + +Within scoop_gpio_handler_update, if prev_level has a high bit set, then +we get bit > 16 and that causes a buffer overrun. + +Since prev_level comes from wire indirectly, this can +happen on invalid state load. + +Similarly for gpio_level and gpio_dir. + +To fix, limit to 16 bit. + +Reported-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Juan Quintela +--- + hw/gpio/zaurus.c | 10 ++++++++++ + 1 files changed, 10 insertions(+), 0 deletions(-) + +diff --git a/hw/gpio/zaurus.c b/hw/gpio/zaurus.c +index dc79a8b..8e2ce04 100644 +--- a/hw/gpio/zaurus.c ++++ b/hw/gpio/zaurus.c +@@ -203,6 +203,15 @@ static bool is_version_0 (void *opaque, int version_id) + return version_id == 0; + } + ++static bool vmstate_scoop_validate(void *opaque, int version_id) ++{ ++ ScoopInfo *s = opaque; ++ ++ return !(s->prev_level & 0xffff0000) && ++ !(s->gpio_level & 0xffff0000) && ++ !(s->gpio_dir & 0xffff0000); ++} ++ + static const VMStateDescription vmstate_scoop_regs = { + .name = "scoop", + .version_id = 1, +@@ -215,6 +224,7 @@ static const VMStateDescription vmstate_scoop_regs = { + VMSTATE_UINT32(gpio_level, ScoopInfo), + VMSTATE_UINT32(gpio_dir, ScoopInfo), + VMSTATE_UINT32(prev_level, ScoopInfo), ++ VMSTATE_VALIDATE("irq levels are 16 bit", vmstate_scoop_validate), + VMSTATE_UINT16(mcr, ScoopInfo), + VMSTATE_UINT16(cdr, ScoopInfo), + VMSTATE_UINT16(ccr, ScoopInfo), +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4541.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4541.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4541.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4541.patch 2014-08-12 12:06:02.000000000 +0000 @@ -0,0 +1,40 @@ +From 9f8e9895c504149d7048e9fc5eb5cbb34b16e49a Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Thu, 3 Apr 2014 19:52:25 +0300 +Subject: [PATCH] usb: sanity check setup_index+setup_len in post_load + +CVE-2013-4541 + +s->setup_len and s->setup_index are fed into usb_packet_copy as +size/offset into s->data_buf, it's possible for invalid state to exploit +this to load arbitrary data. + +setup_len and setup_index should be checked to make sure +they are not negative. + +Cc: Gerd Hoffmann +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Gerd Hoffmann +Signed-off-by: Juan Quintela +--- + hw/usb/bus.c | 4 +++- + 1 files changed, 3 insertions(+), 1 deletions(-) + +diff --git a/hw/usb/bus.c b/hw/usb/bus.c +index fe70429..e48b19f 100644 +--- a/hw/usb/bus.c ++++ b/hw/usb/bus.c +@@ -49,7 +49,9 @@ static int usb_device_post_load(void *opaque, int version_id) + } else { + dev->attached = 1; + } +- if (dev->setup_index >= sizeof(dev->data_buf) || ++ if (dev->setup_index < 0 || ++ dev->setup_len < 0 || ++ dev->setup_index >= sizeof(dev->data_buf) || + dev->setup_len >= sizeof(dev->data_buf)) { + return -EINVAL; + } +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4542.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-4542.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-4542.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-4542.patch 2014-08-12 12:06:06.000000000 +0000 @@ -0,0 +1,69 @@ +From 3c3ce981423e0d6c18af82ee62f1850c2cda5976 Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Thu, 3 Apr 2014 19:52:17 +0300 +Subject: [PATCH] virtio-scsi: fix buffer overrun on invalid state load +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf8 +Content-Transfer-Encoding: 8bit + +CVE-2013-4542 + +hw/scsi/scsi-bus.c invokes load_request. + + virtio_scsi_load_request does: + qemu_get_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem)); + +this probably can make elem invalid, for example, +make in_num or out_num huge, then: + + virtio_scsi_parse_req(s, vs->cmd_vqs[n], req); + +will do: + + if (req->elem.out_num > 1) { + qemu_sgl_init_external(req, &req->elem.out_sg[1], + &req->elem.out_addr[1], + req->elem.out_num - 1); + } else { + qemu_sgl_init_external(req, &req->elem.in_sg[1], + &req->elem.in_addr[1], + req->elem.in_num - 1); + } + +and this will access out of array bounds. + +Note: this adds security checks within assert calls since +SCSIBusInfo's load_request cannot fail. +For now simply disable builds with NDEBUG - there seems +to be little value in supporting these. + +Cc: Andreas Färber +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Juan Quintela +--- + hw/scsi/virtio-scsi.c | 9 +++++++++ + 1 files changed, 9 insertions(+), 0 deletions(-) + +diff --git a/hw/scsi/virtio-scsi.c b/hw/scsi/virtio-scsi.c +index b0d7517..1752193 100644 +--- a/hw/scsi/virtio-scsi.c ++++ b/hw/scsi/virtio-scsi.c +@@ -147,6 +147,15 @@ static void *virtio_scsi_load_request(QEMUFile *f, SCSIRequest *sreq) + qemu_get_be32s(f, &n); + assert(n < vs->conf.num_queues); + qemu_get_buffer(f, (unsigned char *)&req->elem, sizeof(req->elem)); ++ /* TODO: add a way for SCSIBusInfo's load_request to fail, ++ * and fail migration instead of asserting here. ++ * When we do, we might be able to re-enable NDEBUG below. ++ */ ++#ifdef NDEBUG ++#error building with NDEBUG is not supported ++#endif ++ assert(req->elem.in_num <= ARRAY_SIZE(req->elem.in_sg)); ++ assert(req->elem.out_num <= ARRAY_SIZE(req->elem.out_sg)); + virtio_scsi_parse_req(s, vs->cmd_vqs[n], req); + + scsi_req_ref(sreq); +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-6399.patch qemu-2.0.0+dfsg/debian/patches/CVE-2013-6399.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2013-6399.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2013-6399.patch 2014-08-12 12:06:17.000000000 +0000 @@ -0,0 +1,39 @@ +From 4b53c2c72cb5541cf394033b528a6fe2a86c0ac1 Mon Sep 17 00:00:00 2001 +From: Michael Roth +Date: Thu, 3 Apr 2014 19:51:46 +0300 +Subject: [PATCH] virtio: avoid buffer overrun on incoming migration + +CVE-2013-6399 + +vdev->queue_sel is read from the wire, and later used in the +emulation code as an index into vdev->vq[]. If the value of +vdev->queue_sel exceeds the length of vdev->vq[], currently +allocated to be VIRTIO_PCI_QUEUE_MAX elements, subsequent PIO +operations such as VIRTIO_PCI_QUEUE_PFN can be used to overrun +the buffer with arbitrary data originating from the source. + +Fix this by failing migration if the value from the wire exceeds +VIRTIO_PCI_QUEUE_MAX. + +Signed-off-by: Michael Roth +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Peter Maydell +Signed-off-by: Juan Quintela +--- + hw/virtio/virtio.c | 3 +++ + 1 files changed, 3 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/virtio/virtio.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/virtio/virtio.c 2014-08-12 08:06:14.330481004 -0400 ++++ qemu-2.0.0+dfsg/hw/virtio/virtio.c 2014-08-12 08:06:14.326481004 -0400 +@@ -913,6 +913,9 @@ + qemu_get_8s(f, &vdev->status); + qemu_get_8s(f, &vdev->isr); + qemu_get_be16s(f, &vdev->queue_sel); ++ if (vdev->queue_sel >= VIRTIO_PCI_QUEUE_MAX) { ++ return -1; ++ } + qemu_get_be32s(f, &features); + + if (virtio_set_features(vdev, features) < 0) { diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-0182.patch qemu-2.0.0+dfsg/debian/patches/CVE-2014-0182.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-0182.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2014-0182.patch 2014-08-12 12:29:59.000000000 +0000 @@ -0,0 +1,38 @@ +Description: fix out-of-bounds buffer write on state load with invalid config_len +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=a890a2f9137ac3cf5b607649e66a6f3a5512d8dc +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=2f5732e9648fcddc8759a8fd25c0b41a38352be6 + +Index: qemu-2.0.0+dfsg/hw/virtio/virtio.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/virtio/virtio.c 2014-08-12 08:06:21.938481128 -0400 ++++ qemu-2.0.0+dfsg/hw/virtio/virtio.c 2014-08-12 08:06:40.466481428 -0400 +@@ -898,6 +898,7 @@ + int virtio_load(VirtIODevice *vdev, QEMUFile *f) + { + int i, ret; ++ int32_t config_len; + uint32_t num; + uint32_t features; + uint32_t supported_features; +@@ -924,8 +925,19 @@ + features, supported_features); + return -1; + } +- vdev->config_len = qemu_get_be32(f); +- qemu_get_buffer(f, vdev->config, vdev->config_len); ++ config_len = qemu_get_be32(f); ++ ++ /* ++ * There are cases where the incoming config can be bigger or smaller ++ * than what we have; so load what we have space for, and skip ++ * any excess that's in the stream. ++ */ ++ qemu_get_buffer(f, vdev->config, MIN(config_len, vdev->config_len)); ++ ++ while (config_len > vdev->config_len) { ++ qemu_get_byte(f); ++ config_len--; ++ } + + num = qemu_get_be32(f); + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-0222.patch qemu-2.0.0+dfsg/debian/patches/CVE-2014-0222.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-0222.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2014-0222.patch 2014-08-12 12:09:20.000000000 +0000 @@ -0,0 +1,48 @@ +Backport of: + +From 42eb58179b3b215bb507da3262b682b8a2ec10b5 Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 15 May 2014 16:10:11 +0200 +Subject: [PATCH] qcow1: Validate L2 table size (CVE-2014-0222) + +Too large L2 table sizes cause unbounded allocations. Images actually +created by qemu-img only have 512 byte or 4k L2 tables. + +To keep things consistent with cluster sizes, allow ranges between 512 +bytes and 64k (in fact, down to 1 entry = 8 bytes is technically +working, but L2 table sizes smaller than a cluster don't make a lot of +sense). + +This also means that the number of bytes on the virtual disk that are +described by the same L2 table is limited to at most 8k * 64k or 2^29, +preventively avoiding any integer overflows. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Kevin Wolf +Reviewed-by: Benoit Canet +--- + block/qcow.c | 8 ++++++++ + tests/qemu-iotests/092 | 15 +++++++++++++++ + tests/qemu-iotests/092.out | 11 +++++++++++ + 3 files changed, 34 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/block/qcow.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/block/qcow.c 2014-08-12 08:08:31.538483229 -0400 ++++ qemu-2.0.0+dfsg/block/qcow.c 2014-08-12 08:09:09.366483842 -0400 +@@ -131,6 +131,15 @@ + ret = -EINVAL; + goto fail; + } ++ ++ /* l2_bits specifies number of entries; storing a uint64_t in each entry, ++ * so bytes = num_entries << 3. */ ++ if (header.l2_bits < 9 - 3 || header.l2_bits > 16 - 3) { ++ error_setg(errp, "L2 table size must be between 512 and 64k"); ++ ret = -EINVAL; ++ goto fail; ++ } ++ + if (header.crypt_method > QCOW_CRYPT_AES) { + error_setg(errp, "invalid encryption method in qcow header"); + ret = -EINVAL; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-0223.patch qemu-2.0.0+dfsg/debian/patches/CVE-2014-0223.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-0223.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2014-0223.patch 2014-08-12 12:09:34.000000000 +0000 @@ -0,0 +1,56 @@ +Backport of: + +From 46485de0cb357b57373e1ca895adedf1f3ed46ec Mon Sep 17 00:00:00 2001 +From: Kevin Wolf +Date: Thu, 8 May 2014 13:08:20 +0200 +Subject: [PATCH] qcow1: Validate image size (CVE-2014-0223) + +A huge image size could cause s->l1_size to overflow. Make sure that +images never require a L1 table larger than what fits in s->l1_size. + +This cannot only cause unbounded allocations, but also the allocation of +a too small L1 table, resulting in out-of-bounds array accesses (both +reads and writes). + +Cc: qemu-stable@nongnu.org +Signed-off-by: Kevin Wolf +--- + block/qcow.c | 16 ++++++++++++++-- + tests/qemu-iotests/092 | 9 +++++++++ + tests/qemu-iotests/092.out | 7 +++++++ + 3 files changed, 30 insertions(+), 2 deletions(-) + +Index: qemu-2.0.0+dfsg/block/qcow.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/block/qcow.c 2014-08-12 08:09:32.382484215 -0400 ++++ qemu-2.0.0+dfsg/block/qcow.c 2014-08-12 08:09:32.378484215 -0400 +@@ -60,7 +60,7 @@ + int cluster_sectors; + int l2_bits; + int l2_size; +- int l1_size; ++ unsigned int l1_size; + uint64_t cluster_offset_mask; + uint64_t l1_table_offset; + uint64_t *l1_table; +@@ -159,7 +159,19 @@ + + /* read the level 1 table */ + shift = s->cluster_bits + s->l2_bits; +- s->l1_size = (header.size + (1LL << shift) - 1) >> shift; ++ if (header.size > UINT64_MAX - (1LL << shift)) { ++ error_setg(errp, "Image too large"); ++ ret = -EINVAL; ++ goto fail; ++ } else { ++ uint64_t l1_size = (header.size + (1LL << shift) - 1) >> shift; ++ if (l1_size > INT_MAX / sizeof(uint64_t)) { ++ error_setg(errp, "Image too large"); ++ ret = -EINVAL; ++ goto fail; ++ } ++ s->l1_size = l1_size; ++ } + + s->l1_table_offset = header.l1_table_offset; + s->l1_table = g_malloc(s->l1_size * sizeof(uint64_t)); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-3461.patch qemu-2.0.0+dfsg/debian/patches/CVE-2014-3461.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-3461.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2014-3461.patch 2014-08-12 12:09:50.000000000 +0000 @@ -0,0 +1,39 @@ +From 719ffe1f5f72b1c7ace4afe9ba2815bcb53a829e Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Tue, 13 May 2014 12:33:16 +0300 +Subject: [PATCH] usb: fix up post load checks + +Correct post load checks: +1. dev->setup_len == sizeof(dev->data_buf) + seems fine, no need to fail migration +2. When state is DATA, passing index > len + will cause memcpy with negative length, + resulting in heap overflow + +First of the issues was reported by dgilbert. + +Reported-by: "Dr. David Alan Gilbert" +Signed-off-by: Michael S. Tsirkin +Signed-off-by: Juan Quintela +--- + hw/usb/bus.c | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +diff --git a/hw/usb/bus.c b/hw/usb/bus.c +index 699aa10..927a47b 100644 +--- a/hw/usb/bus.c ++++ b/hw/usb/bus.c +@@ -51,8 +51,8 @@ static int usb_device_post_load(void *opaque, int version_id) + } + if (dev->setup_index < 0 || + dev->setup_len < 0 || +- dev->setup_index >= sizeof(dev->data_buf) || +- dev->setup_len >= sizeof(dev->data_buf)) { ++ dev->setup_index > dev->setup_len || ++ dev->setup_len > sizeof(dev->data_buf)) { + return -EINVAL; + } + return 0; +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-3471.patch qemu-2.0.0+dfsg/debian/patches/CVE-2014-3471.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-3471.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2014-3471.patch 2014-08-12 12:09:59.000000000 +0000 @@ -0,0 +1,85 @@ +From 554f802da3f8b09b16b9a84ad5847b2eb0e9ad2b Mon Sep 17 00:00:00 2001 +From: Marcel Apfelbaum +Date: Mon, 23 Jun 2014 17:32:49 +0300 +Subject: [PATCH] hw/pcie: better hotplug/hotunplug support + +The current code is broken: it does surprise removal which crashes guests. + +Reimplemented the steps: + - Hotplug triggers both 'present detect change' and + 'attention button pressed'. + + - Hotunplug starts by triggering 'attention button pressed', + then waits for the OS to power off the device and only + then detaches it. + +Fixes CVE-2014-3471. + +Signed-off-by: Marcel Apfelbaum +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +--- + hw/pci/pcie.c | 29 ++++++++++++++++++++++++----- + 1 files changed, 24 insertions(+), 5 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/pci/pcie.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/pci/pcie.c 2014-08-12 08:09:56.758484610 -0400 ++++ qemu-2.0.0+dfsg/hw/pci/pcie.c 2014-08-12 08:09:56.750484610 -0400 +@@ -258,7 +258,8 @@ + + pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA, + PCI_EXP_SLTSTA_PDS); +- pcie_cap_slot_event(PCI_DEVICE(hotplug_dev), PCI_EXP_HP_EV_PDC); ++ pcie_cap_slot_event(PCI_DEVICE(hotplug_dev), ++ PCI_EXP_HP_EV_PDC | PCI_EXP_HP_EV_ABP); + } + + void pcie_cap_slot_hot_unplug_cb(HotplugHandler *hotplug_dev, DeviceState *dev, +@@ -268,10 +269,7 @@ + + pcie_cap_slot_hotplug_common(PCI_DEVICE(hotplug_dev), dev, &exp_cap, errp); + +- object_unparent(OBJECT(dev)); +- pci_word_test_and_clear_mask(exp_cap + PCI_EXP_SLTSTA, +- PCI_EXP_SLTSTA_PDS); +- pcie_cap_slot_event(PCI_DEVICE(hotplug_dev), PCI_EXP_HP_EV_PDC); ++ pcie_cap_slot_push_attention_button(PCI_DEVICE(hotplug_dev)); + } + + /* pci express slot for pci express root/downstream port +@@ -352,6 +350,11 @@ + hotplug_event_update_event_status(dev); + } + ++static void pcie_unplug_device(PCIBus *bus, PCIDevice *dev, void *opaque) ++{ ++ object_unparent(OBJECT(dev)); ++} ++ + void pcie_cap_slot_write_config(PCIDevice *dev, + uint32_t addr, uint32_t val, int len) + { +@@ -376,6 +379,22 @@ + sltsta); + } + ++ /* ++ * If the slot is polulated, power indicator is off and power ++ * controller is off, it is safe to detach the devices. ++ */ ++ if ((sltsta & PCI_EXP_SLTSTA_PDS) && (val & PCI_EXP_SLTCTL_PCC) && ++ ((val & PCI_EXP_SLTCTL_PIC_OFF) == PCI_EXP_SLTCTL_PIC_OFF)) { ++ PCIBus *sec_bus = pci_bridge_get_sec_bus(PCI_BRIDGE(dev)); ++ pci_for_each_device(sec_bus, pci_bus_num(sec_bus), ++ pcie_unplug_device, NULL); ++ ++ pci_word_test_and_clear_mask(exp_cap + PCI_EXP_SLTSTA, ++ PCI_EXP_SLTSTA_PDS); ++ pci_word_test_and_set_mask(exp_cap + PCI_EXP_SLTSTA, ++ PCI_EXP_SLTSTA_PDC); ++ } ++ + hotplug_event_notify(dev); + + /* diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-3615.patch qemu-2.0.0+dfsg/debian/patches/CVE-2014-3615.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-3615.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2014-3615.patch 2014-11-11 19:31:50.000000000 +0000 @@ -0,0 +1,286 @@ +Description: fix information disclosure via vga driver +Origin: backport, http://git.qemu.org/?p=qemu.git;a=commit;h=54a85d462447c1cb8a1638578a7fd086350b4d2d +Origin: backport, http://git.qemu.org/?p=qemu.git;a=commit;h=c1b886c45dc70f247300f549dce9833f3fa2def5 +Origin: backport, http://git.qemu.org/?p=qemu.git;a=commit;h=ab9509cceabef28071e41bdfa073083859c949a7 + +Index: qemu-2.0.0+dfsg/hw/display/qxl.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/display/qxl.c 2014-11-11 14:31:47.385712842 -0500 ++++ qemu-2.0.0+dfsg/hw/display/qxl.c 2014-11-11 14:31:47.381712815 -0500 +@@ -2060,6 +2060,7 @@ + + qxl->id = 0; + qxl_init_ramsize(qxl); ++ vga->vbe_size = qxl->vgamem_size; + vga->vram_size_mb = qxl->vga.vram_size >> 20; + vga_common_init(vga, OBJECT(dev)); + vga_init(vga, OBJECT(dev), +Index: qemu-2.0.0+dfsg/hw/display/vga.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/display/vga.c 2014-11-11 14:31:47.385712842 -0500 ++++ qemu-2.0.0+dfsg/hw/display/vga.c 2014-11-11 14:31:47.385712842 -0500 +@@ -576,6 +576,93 @@ + } + } + ++/* ++ * Sanity check vbe register writes. ++ * ++ * As we don't have a way to signal errors to the guest in the bochs ++ * dispi interface we'll go adjust the registers to the closest valid ++ * value. ++ */ ++static void vbe_fixup_regs(VGACommonState *s) ++{ ++ uint16_t *r = s->vbe_regs; ++ uint32_t bits, linelength, maxy, offset; ++ ++ if (!(r[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) { ++ /* vbe is turned off -- nothing to do */ ++ return; ++ } ++ ++ /* check depth */ ++ switch (r[VBE_DISPI_INDEX_BPP]) { ++ case 4: ++ case 8: ++ case 16: ++ case 24: ++ case 32: ++ bits = r[VBE_DISPI_INDEX_BPP]; ++ break; ++ case 15: ++ bits = 16; ++ break; ++ default: ++ bits = r[VBE_DISPI_INDEX_BPP] = 8; ++ break; ++ } ++ ++ /* check width */ ++ r[VBE_DISPI_INDEX_XRES] &= ~7u; ++ if (r[VBE_DISPI_INDEX_XRES] == 0) { ++ r[VBE_DISPI_INDEX_XRES] = 8; ++ } ++ if (r[VBE_DISPI_INDEX_XRES] > VBE_DISPI_MAX_XRES) { ++ r[VBE_DISPI_INDEX_XRES] = VBE_DISPI_MAX_XRES; ++ } ++ r[VBE_DISPI_INDEX_VIRT_WIDTH] &= ~7u; ++ if (r[VBE_DISPI_INDEX_VIRT_WIDTH] > VBE_DISPI_MAX_XRES) { ++ r[VBE_DISPI_INDEX_VIRT_WIDTH] = VBE_DISPI_MAX_XRES; ++ } ++ if (r[VBE_DISPI_INDEX_VIRT_WIDTH] < r[VBE_DISPI_INDEX_XRES]) { ++ r[VBE_DISPI_INDEX_VIRT_WIDTH] = r[VBE_DISPI_INDEX_XRES]; ++ } ++ ++ /* check height */ ++ linelength = r[VBE_DISPI_INDEX_VIRT_WIDTH] * bits / 8; ++ maxy = s->vbe_size / linelength; ++ if (r[VBE_DISPI_INDEX_YRES] == 0) { ++ r[VBE_DISPI_INDEX_YRES] = 1; ++ } ++ if (r[VBE_DISPI_INDEX_YRES] > VBE_DISPI_MAX_YRES) { ++ r[VBE_DISPI_INDEX_YRES] = VBE_DISPI_MAX_YRES; ++ } ++ if (r[VBE_DISPI_INDEX_YRES] > maxy) { ++ r[VBE_DISPI_INDEX_YRES] = maxy; ++ } ++ ++ /* check offset */ ++ if (r[VBE_DISPI_INDEX_X_OFFSET] > VBE_DISPI_MAX_XRES) { ++ r[VBE_DISPI_INDEX_X_OFFSET] = VBE_DISPI_MAX_XRES; ++ } ++ if (r[VBE_DISPI_INDEX_Y_OFFSET] > VBE_DISPI_MAX_YRES) { ++ r[VBE_DISPI_INDEX_Y_OFFSET] = VBE_DISPI_MAX_YRES; ++ } ++ offset = r[VBE_DISPI_INDEX_X_OFFSET] * bits / 8; ++ offset += r[VBE_DISPI_INDEX_Y_OFFSET] * linelength; ++ if (offset + r[VBE_DISPI_INDEX_YRES] * linelength > s->vbe_size) { ++ r[VBE_DISPI_INDEX_Y_OFFSET] = 0; ++ offset = r[VBE_DISPI_INDEX_X_OFFSET] * bits / 8; ++ if (offset + r[VBE_DISPI_INDEX_YRES] * linelength > s->vbe_size) { ++ r[VBE_DISPI_INDEX_X_OFFSET] = 0; ++ offset = 0; ++ } ++ } ++ ++ /* update vga state */ ++ r[VBE_DISPI_INDEX_VIRT_HEIGHT] = maxy; ++ s->vbe_line_offset = linelength; ++ s->vbe_start_addr = offset / 4; ++} ++ + static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr) + { + VGACommonState *s = opaque; +@@ -610,7 +697,7 @@ + val = s->vbe_regs[s->vbe_index]; + } + } else if (s->vbe_index == VBE_DISPI_INDEX_VIDEO_MEMORY_64K) { +- val = s->vram_size / (64 * 1024); ++ val = s->vbe_size / (64 * 1024); + } else { + val = 0; + } +@@ -645,22 +732,13 @@ + } + break; + case VBE_DISPI_INDEX_XRES: +- if ((val <= VBE_DISPI_MAX_XRES) && ((val & 7) == 0)) { +- s->vbe_regs[s->vbe_index] = val; +- } +- break; + case VBE_DISPI_INDEX_YRES: +- if (val <= VBE_DISPI_MAX_YRES) { +- s->vbe_regs[s->vbe_index] = val; +- } +- break; + case VBE_DISPI_INDEX_BPP: +- if (val == 0) +- val = 8; +- if (val == 4 || val == 8 || val == 15 || +- val == 16 || val == 24 || val == 32) { +- s->vbe_regs[s->vbe_index] = val; +- } ++ case VBE_DISPI_INDEX_VIRT_WIDTH: ++ case VBE_DISPI_INDEX_X_OFFSET: ++ case VBE_DISPI_INDEX_Y_OFFSET: ++ s->vbe_regs[s->vbe_index] = val; ++ vbe_fixup_regs(s); + break; + case VBE_DISPI_INDEX_BANK: + if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) { +@@ -677,19 +755,11 @@ + !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) { + int h, shift_control; + +- s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = +- s->vbe_regs[VBE_DISPI_INDEX_XRES]; +- s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = +- s->vbe_regs[VBE_DISPI_INDEX_YRES]; ++ s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0; + s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0; + s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0; +- +- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) +- s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 1; +- else +- s->vbe_line_offset = s->vbe_regs[VBE_DISPI_INDEX_XRES] * +- ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3); +- s->vbe_start_addr = 0; ++ s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED; ++ vbe_fixup_regs(s); + + /* clear the screen (should be done in BIOS) */ + if (!(val & VBE_DISPI_NOCLEARMEM)) { +@@ -738,40 +808,6 @@ + s->vbe_regs[s->vbe_index] = val; + vga_update_memory_access(s); + break; +- case VBE_DISPI_INDEX_VIRT_WIDTH: +- { +- int w, h, line_offset; +- +- if (val < s->vbe_regs[VBE_DISPI_INDEX_XRES]) +- return; +- w = val; +- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) +- line_offset = w >> 1; +- else +- line_offset = w * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3); +- h = s->vram_size / line_offset; +- /* XXX: support weird bochs semantics ? */ +- if (h < s->vbe_regs[VBE_DISPI_INDEX_YRES]) +- return; +- s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = w; +- s->vbe_regs[VBE_DISPI_INDEX_VIRT_HEIGHT] = h; +- s->vbe_line_offset = line_offset; +- } +- break; +- case VBE_DISPI_INDEX_X_OFFSET: +- case VBE_DISPI_INDEX_Y_OFFSET: +- { +- int x; +- s->vbe_regs[s->vbe_index] = val; +- s->vbe_start_addr = s->vbe_line_offset * s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET]; +- x = s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET]; +- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) +- s->vbe_start_addr += x >> 1; +- else +- s->vbe_start_addr += x * ((s->vbe_regs[VBE_DISPI_INDEX_BPP] + 7) >> 3); +- s->vbe_start_addr >>= 2; +- } +- break; + default: + break; + } +@@ -2286,6 +2322,9 @@ + s->vram_size <<= 1; + } + s->vram_size_mb = s->vram_size >> 20; ++ if (!s->vbe_size) { ++ s->vbe_size = s->vram_size; ++ } + + s->is_vbe_vmstate = 1; + memory_region_init_ram(&s->vram, obj, "vga.vram", s->vram_size); +Index: qemu-2.0.0+dfsg/hw/display/vga_int.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/display/vga_int.h 2014-11-11 14:31:47.385712842 -0500 ++++ qemu-2.0.0+dfsg/hw/display/vga_int.h 2014-11-11 14:31:47.385712842 -0500 +@@ -93,6 +93,7 @@ + MemoryRegion vram_vbe; + uint32_t vram_size; + uint32_t vram_size_mb; /* property */ ++ uint32_t vbe_size; + uint32_t latch; + MemoryRegion *chain4_alias; + uint8_t sr_index; +Index: qemu-2.0.0+dfsg/ui/spice-display.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/ui/spice-display.c 2014-11-11 14:31:47.385712842 -0500 ++++ qemu-2.0.0+dfsg/ui/spice-display.c 2014-11-11 14:31:47.385712842 -0500 +@@ -291,11 +291,23 @@ + void qemu_spice_create_host_primary(SimpleSpiceDisplay *ssd) + { + QXLDevSurfaceCreate surface; ++ uint64_t surface_size; + + memset(&surface, 0, sizeof(surface)); + +- dprint(1, "%s/%d: %dx%d\n", __func__, ssd->qxl.id, +- surface_width(ssd->ds), surface_height(ssd->ds)); ++ surface_size = (uint64_t) surface_width(ssd->ds) * ++ surface_height(ssd->ds) * 4; ++ assert(surface_size > 0); ++ assert(surface_size < INT_MAX); ++ if (ssd->bufsize < surface_size) { ++ ssd->bufsize = surface_size; ++ g_free(ssd->buf); ++ ssd->buf = g_malloc(ssd->bufsize); ++ } ++ ++ dprint(1, "%s/%d: %ux%u (size %" PRIu64 "/%d)\n", __func__, ssd->qxl.id, ++ surface_width(ssd->ds), surface_height(ssd->ds), ++ surface_size, ssd->bufsize); + + surface.format = SPICE_SURFACE_FMT_32_xRGB; + surface.width = surface_width(ssd->ds); +@@ -326,8 +338,6 @@ + if (ssd->num_surfaces == 0) { + ssd->num_surfaces = 1024; + } +- ssd->bufsize = (16 * 1024 * 1024); +- ssd->buf = g_malloc(ssd->bufsize); + } + + /* display listener callbacks */ +@@ -452,7 +462,7 @@ + info->num_memslots = NUM_MEMSLOTS; + info->num_memslots_groups = NUM_MEMSLOTS_GROUPS; + info->internal_groupslot_id = 0; +- info->qxl_ram_size = ssd->bufsize; ++ info->qxl_ram_size = 16 * 1024 * 1024; + info->n_surfaces = ssd->num_surfaces; + } + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-3640.patch qemu-2.0.0+dfsg/debian/patches/CVE-2014-3640.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-3640.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2014-3640.patch 2014-11-11 19:16:30.000000000 +0000 @@ -0,0 +1,42 @@ +From 01f7cecf0037997cb0e58ec0d56bf9b5a6f7cb2a Mon Sep 17 00:00:00 2001 +From: Petr Matousek +Date: Thu, 18 Sep 2014 08:35:37 +0200 +Subject: [PATCH] slirp: udp: fix NULL pointer dereference because of uninitialized socket + +When guest sends udp packet with source port and source addr 0, +uninitialized socket is picked up when looking for matching and already +created udp sockets, and later passed to sosendto() where NULL pointer +dereference is hit during so->slirp->vnetwork_mask.s_addr access. + +Fix this by checking that the socket is not just a socket stub. + +This is CVE-2014-3640. + +Signed-off-by: Petr Matousek +Reported-by: Xavier Mehrenberger +Reported-by: Stephane Duverger +Reviewed-by: Jan Kiszka +Reviewed-by: Michael S. Tsirkin +Reviewed-by: Michael Tokarev +Message-id: 20140918063537.GX9321@dhcp-25-225.brq.redhat.com +Signed-off-by: Peter Maydell +--- + slirp/udp.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +diff --git a/slirp/udp.c b/slirp/udp.c +index 8cc6cb6..f77e00f 100644 +--- a/slirp/udp.c ++++ b/slirp/udp.c +@@ -152,7 +152,7 @@ udp_input(register struct mbuf *m, int iphlen) + * Locate pcb for datagram. + */ + so = slirp->udp_last_so; +- if (so->so_lport != uh->uh_sport || ++ if (so == &slirp->udb || so->so_lport != uh->uh_sport || + so->so_laddr.s_addr != ip->ip_src.s_addr) { + struct socket *tmp; + +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-3689.patch qemu-2.0.0+dfsg/debian/patches/CVE-2014-3689.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-3689.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2014-3689.patch 2014-11-11 19:16:37.000000000 +0000 @@ -0,0 +1,205 @@ +Description: fix possible privilege escalation via vmware-vga driver +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=83afa38eb20ca27e30683edc7729880e091387fc +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=07258900fd45b646f5b69048d64c4490b3243e1b +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=1735fe1edba9cc86bc0f26937ed5a62d3cb47c9c +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=61b41b4c20eba08d2185297767e69153d7f3e09d +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=bd9ccd8517e83b7c33a9167815dbfffb30d70b13 +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=765496 + +Index: qemu-2.1+dfsg/hw/display/vmware_vga.c +=================================================================== +--- qemu-2.1+dfsg.orig/hw/display/vmware_vga.c 2014-08-01 10:12:17.000000000 -0400 ++++ qemu-2.1+dfsg/hw/display/vmware_vga.c 2014-11-11 14:03:40.778497521 -0500 +@@ -292,47 +292,74 @@ + SVGA_CURSOR_ON_RESTORE_TO_FB = 3, + }; + +-static inline void vmsvga_update_rect(struct vmsvga_state_s *s, +- int x, int y, int w, int h) ++static inline bool vmsvga_verify_rect(DisplaySurface *surface, ++ const char *name, ++ int x, int y, int w, int h) + { +- DisplaySurface *surface = qemu_console_surface(s->vga.con); +- int line; +- int bypl; +- int width; +- int start; +- uint8_t *src; +- uint8_t *dst; +- + if (x < 0) { +- fprintf(stderr, "%s: update x was < 0 (%d)\n", __func__, x); +- w += x; +- x = 0; ++ fprintf(stderr, "%s: x was < 0 (%d)\n", name, x); ++ return false; ++ } ++ if (x > SVGA_MAX_WIDTH) { ++ fprintf(stderr, "%s: x was > %d (%d)\n", name, SVGA_MAX_WIDTH, x); ++ return false; + } + if (w < 0) { +- fprintf(stderr, "%s: update w was < 0 (%d)\n", __func__, w); +- w = 0; ++ fprintf(stderr, "%s: w was < 0 (%d)\n", name, w); ++ return false; ++ } ++ if (w > SVGA_MAX_WIDTH) { ++ fprintf(stderr, "%s: w was > %d (%d)\n", name, SVGA_MAX_WIDTH, w); ++ return false; + } + if (x + w > surface_width(surface)) { +- fprintf(stderr, "%s: update width too large x: %d, w: %d\n", +- __func__, x, w); +- x = MIN(x, surface_width(surface)); +- w = surface_width(surface) - x; ++ fprintf(stderr, "%s: width was > %d (x: %d, w: %d)\n", ++ name, surface_width(surface), x, w); ++ return false; + } + + if (y < 0) { +- fprintf(stderr, "%s: update y was < 0 (%d)\n", __func__, y); +- h += y; +- y = 0; ++ fprintf(stderr, "%s: y was < 0 (%d)\n", name, y); ++ return false; ++ } ++ if (y > SVGA_MAX_HEIGHT) { ++ fprintf(stderr, "%s: y was > %d (%d)\n", name, SVGA_MAX_HEIGHT, y); ++ return false; + } + if (h < 0) { +- fprintf(stderr, "%s: update h was < 0 (%d)\n", __func__, h); +- h = 0; ++ fprintf(stderr, "%s: h was < 0 (%d)\n", name, h); ++ return false; ++ } ++ if (h > SVGA_MAX_HEIGHT) { ++ fprintf(stderr, "%s: h was > %d (%d)\n", name, SVGA_MAX_HEIGHT, h); ++ return false; + } + if (y + h > surface_height(surface)) { +- fprintf(stderr, "%s: update height too large y: %d, h: %d\n", +- __func__, y, h); +- y = MIN(y, surface_height(surface)); +- h = surface_height(surface) - y; ++ fprintf(stderr, "%s: update height > %d (y: %d, h: %d)\n", ++ name, surface_height(surface), y, h); ++ return false; ++ } ++ ++ return true; ++} ++ ++static inline void vmsvga_update_rect(struct vmsvga_state_s *s, ++ int x, int y, int w, int h) ++{ ++ DisplaySurface *surface = qemu_console_surface(s->vga.con); ++ int line; ++ int bypl; ++ int width; ++ int start; ++ uint8_t *src; ++ uint8_t *dst; ++ ++ if (!vmsvga_verify_rect(surface, __func__, x, y, w, h)) { ++ /* go for a fullscreen update as fallback */ ++ x = 0; ++ y = 0; ++ w = surface_width(surface); ++ h = surface_height(surface); + } + + bypl = surface_stride(surface); +@@ -377,7 +404,7 @@ + } + + #ifdef HW_RECT_ACCEL +-static inline void vmsvga_copy_rect(struct vmsvga_state_s *s, ++static inline int vmsvga_copy_rect(struct vmsvga_state_s *s, + int x0, int y0, int x1, int y1, int w, int h) + { + DisplaySurface *surface = qemu_console_surface(s->vga.con); +@@ -388,6 +415,13 @@ + int line = h; + uint8_t *ptr[2]; + ++ if (!vmsvga_verify_rect(surface, "vmsvga_copy_rect/src", x0, y0, w, h)) { ++ return -1; ++ } ++ if (!vmsvga_verify_rect(surface, "vmsvga_copy_rect/dst", x1, y1, w, h)) { ++ return -1; ++ } ++ + if (y1 > y0) { + ptr[0] = vram + bypp * x0 + bypl * (y0 + h - 1); + ptr[1] = vram + bypp * x1 + bypl * (y1 + h - 1); +@@ -403,11 +437,12 @@ + } + + vmsvga_update_rect_delayed(s, x1, y1, w, h); ++ return 0; + } + #endif + + #ifdef HW_FILL_ACCEL +-static inline void vmsvga_fill_rect(struct vmsvga_state_s *s, ++static inline int vmsvga_fill_rect(struct vmsvga_state_s *s, + uint32_t c, int x, int y, int w, int h) + { + DisplaySurface *surface = qemu_console_surface(s->vga.con); +@@ -420,6 +455,10 @@ + uint8_t *src; + uint8_t col[4]; + ++ if (!vmsvga_verify_rect(surface, __func__, x, y, w, h)) { ++ return -1; ++ } ++ + col[0] = c; + col[1] = c >> 8; + col[2] = c >> 16; +@@ -444,6 +483,7 @@ + } + + vmsvga_update_rect_delayed(s, x, y, w, h); ++ return 0; + } + #endif + +@@ -576,12 +616,12 @@ + width = vmsvga_fifo_read(s); + height = vmsvga_fifo_read(s); + #ifdef HW_FILL_ACCEL +- vmsvga_fill_rect(s, colour, x, y, width, height); +- break; +-#else ++ if (vmsvga_fill_rect(s, colour, x, y, width, height) == 0) { ++ break; ++ } ++#endif + args = 0; + goto badcmd; +-#endif + + case SVGA_CMD_RECT_COPY: + len -= 7; +@@ -596,12 +636,12 @@ + width = vmsvga_fifo_read(s); + height = vmsvga_fifo_read(s); + #ifdef HW_RECT_ACCEL +- vmsvga_copy_rect(s, x, y, dx, dy, width, height); +- break; +-#else ++ if (vmsvga_copy_rect(s, x, y, dx, dy, width, height) == 0) { ++ break; ++ } ++#endif + args = 0; + goto badcmd; +-#endif + + case SVGA_CMD_DEFINE_CURSOR: + len -= 8; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-5263.patch qemu-2.0.0+dfsg/debian/patches/CVE-2014-5263.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-5263.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2014-5263.patch 2014-11-11 19:17:03.000000000 +0000 @@ -0,0 +1,46 @@ +From 3afca1d6d413592c2b78cf28f52fa24a586d8f56 Mon Sep 17 00:00:00 2001 +From: Laszlo Ersek +Date: Tue, 22 Jul 2014 17:26:41 +0200 +Subject: [PATCH] vmstate_xhci_event: fix unterminated field list + +"vmstate_xhci_event" was introduced in commit 37352df3 ("xhci: add live +migration support"), and first released in v1.6.0. The field list in this +VMSD is not terminated with the VMSTATE_END_OF_LIST() macro. + +During normal use (ie. migration), the issue is practically invisible, +because the "vmstate_xhci_event" object (with the unterminated field list) +is only ever referenced -- via "vmstate_xhci_intr" -- if xhci_er_full() +returns true, for the "ev_buffer" test. Since that field_exists() check +(apparently) almost always returns false, we almost never traverse +"vmstate_xhci_event" during migration, which hides the bug. + +However, Amit's vmstate checker forces recursion into this VMSD as well, +and the lack of VMSTATE_END_OF_LIST() breaks the field list terminator +check (field->name != NULL) in dump_vmstate_vmsd(). The result is +undefined behavior, which in my case translates to infinite recursion +(because the loop happens to overflow into "vmstate_xhci_intr", which then +links back to "vmstate_xhci_event"). + +Add the missing terminator. + +Signed-off-by: Laszlo Ersek +Reviewed-by: Amit Shah +Reviewed-by: Paolo Bonzini +Cc: qemu-stable@nongnu.org +Signed-off-by: Peter Maydell +--- + hw/usb/hcd-xhci.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/usb/hcd-xhci.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/usb/hcd-xhci.c 2014-11-11 14:17:00.683814158 -0500 ++++ qemu-2.0.0+dfsg/hw/usb/hcd-xhci.c 2014-11-11 14:17:00.683814158 -0500 +@@ -3703,6 +3703,7 @@ + VMSTATE_UINT32(flags, XHCIEvent), + VMSTATE_UINT8(slotid, XHCIEvent), + VMSTATE_UINT8(epid, XHCIEvent), ++ VMSTATE_END_OF_LIST() + } + }; + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-5388.patch qemu-2.0.0+dfsg/debian/patches/CVE-2014-5388.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-5388.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2014-5388.patch 2014-11-11 19:17:22.000000000 +0000 @@ -0,0 +1,31 @@ +From fa365d7cd11185237471823a5a33d36765454e16 Mon Sep 17 00:00:00 2001 +From: Gonglei +Date: Wed, 20 Aug 2014 13:52:30 +0800 +Subject: [PATCH] pcihp: fix possible array out of bounds + +Prevent out-of-bounds array access on +acpi_pcihp_pci_status. + +Signed-off-by: Gonglei +Reviewed-by: Peter Crosthwaite +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Cc: qemu-stable@nongnu.org +Reviewed-by: Marcel Apfelbaum +--- + hw/acpi/pcihp.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/acpi/pcihp.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/acpi/pcihp.c 2014-11-11 14:17:19.343939391 -0500 ++++ qemu-2.0.0+dfsg/hw/acpi/pcihp.c 2014-11-11 14:17:19.343939391 -0500 +@@ -229,7 +229,7 @@ + uint32_t val = 0; + int bsel = s->hotplug_select; + +- if (bsel < 0 || bsel > ACPI_PCIHP_MAX_HOTPLUG_BUS) { ++ if (bsel < 0 || bsel >= ACPI_PCIHP_MAX_HOTPLUG_BUS) { + return 0; + } + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-7815.patch qemu-2.0.0+dfsg/debian/patches/CVE-2014-7815.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-7815.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2014-7815.patch 2014-11-11 19:17:37.000000000 +0000 @@ -0,0 +1,45 @@ +From e6908bfe8e07f2b452e78e677da1b45b1c0f6829 Mon Sep 17 00:00:00 2001 +From: Petr Matousek +Date: Mon, 27 Oct 2014 12:41:44 +0100 +Subject: [PATCH] vnc: sanitize bits_per_pixel from the client + +bits_per_pixel that are less than 8 could result in accessing +non-initialized buffers later in the code due to the expectation +that bytes_per_pixel value that is used to initialize these buffers is +never zero. + +To fix this check that bits_per_pixel from the client is one of the +values that the rfb protocol specification allows. + +This is CVE-2014-7815. + +Signed-off-by: Petr Matousek + +[ kraxel: apply codestyle fix ] + +Signed-off-by: Gerd Hoffmann +--- + ui/vnc.c | 10 ++++++++++ + 1 files changed, 10 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/ui/vnc.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/ui/vnc.c 2014-11-11 14:17:34.584041708 -0500 ++++ qemu-2.0.0+dfsg/ui/vnc.c 2014-11-11 14:17:34.584041708 -0500 +@@ -2010,6 +2010,16 @@ + return; + } + ++ switch (bits_per_pixel) { ++ case 8: ++ case 16: ++ case 32: ++ break; ++ default: ++ vnc_client_error(vs); ++ return; ++ } ++ + vs->client_pf.rmax = red_max; + vs->client_pf.rbits = hweight_long(red_max); + vs->client_pf.rshift = red_shift; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-7840.patch qemu-2.0.0+dfsg/debian/patches/CVE-2014-7840.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-7840.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2014-7840.patch 2014-12-10 21:01:09.000000000 +0000 @@ -0,0 +1,53 @@ +Backport of: + +From 0be839a2701369f669532ea5884c15bead1c6e08 Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Wed, 12 Nov 2014 11:44:39 +0200 +Subject: [PATCH] migration: fix parameter validation on ram load + +During migration, the values read from migration stream during ram load +are not validated. Especially offset in host_from_stream_offset() and +also the length of the writes in the callers of said function. + +To fix this, we need to make sure that the [offset, offset + length] +range fits into one of the allocated memory regions. + +Validating addr < len should be sufficient since data seems to always be +managed in TARGET_PAGE_SIZE chunks. + +Fixes: CVE-2014-7840 + +Note: follow-up patches add extra checks on each block->host access. + +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Paolo Bonzini +Reviewed-by: Dr. David Alan Gilbert +Signed-off-by: Amit Shah +--- + arch_init.c | 5 +++-- + 1 files changed, 3 insertions(+), 2 deletions(-) + +Index: qemu-2.0.0+dfsg/arch_init.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/arch_init.c 2014-12-10 15:59:43.620194490 -0500 ++++ qemu-2.0.0+dfsg/arch_init.c 2014-12-10 16:00:05.980364705 -0500 +@@ -956,7 +956,7 @@ + uint8_t len; + + if (flags & RAM_SAVE_FLAG_CONTINUE) { +- if (!block) { ++ if (!block || block->length <= offset) { + fprintf(stderr, "Ack, bad migration stream!\n"); + return NULL; + } +@@ -969,8 +969,9 @@ + id[len] = 0; + + QTAILQ_FOREACH(block, &ram_list.blocks, next) { +- if (!strncmp(id, block->idstr, sizeof(id))) ++ if (!strncmp(id, block->idstr, sizeof(id)) && block->length > offset) { + return memory_region_get_ram_ptr(block->mr) + offset; ++ } + } + + fprintf(stderr, "Can't find block %s!\n", id); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-8106.patch qemu-2.0.0+dfsg/debian/patches/CVE-2014-8106.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-8106.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2014-8106.patch 2014-12-10 21:00:41.000000000 +0000 @@ -0,0 +1,110 @@ +Description: fix code execution via cirrus vga blit regions +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=d3532a0db02296e687711b8cdc7791924efccea0 +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=bf25983345ca44aec3dd92c57142be45452bd38a +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/qemu/+bug/1400775 + +Index: qemu-2.1+dfsg/hw/display/cirrus_vga.c +=================================================================== +--- qemu-2.1+dfsg.orig/hw/display/cirrus_vga.c 2014-08-01 10:12:17.000000000 -0400 ++++ qemu-2.1+dfsg/hw/display/cirrus_vga.c 2014-12-10 15:53:44.617454358 -0500 +@@ -172,20 +172,6 @@ + + #define CIRRUS_PNPMMIO_SIZE 0x1000 + +-#define BLTUNSAFE(s) \ +- ( \ +- ( /* check dst is within bounds */ \ +- (s)->cirrus_blt_height * ABS((s)->cirrus_blt_dstpitch) \ +- + ((s)->cirrus_blt_dstaddr & (s)->cirrus_addr_mask) > \ +- (s)->vga.vram_size \ +- ) || \ +- ( /* check src is within bounds */ \ +- (s)->cirrus_blt_height * ABS((s)->cirrus_blt_srcpitch) \ +- + ((s)->cirrus_blt_srcaddr & (s)->cirrus_addr_mask) > \ +- (s)->vga.vram_size \ +- ) \ +- ) +- + struct CirrusVGAState; + typedef void (*cirrus_bitblt_rop_t) (struct CirrusVGAState *s, + uint8_t * dst, const uint8_t * src, +@@ -278,6 +264,50 @@ + * + ***************************************/ + ++static bool blit_region_is_unsafe(struct CirrusVGAState *s, ++ int32_t pitch, int32_t addr) ++{ ++ 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) { ++ return true; ++ } ++ } else { ++ int64_t max = addr ++ + ((int64_t)s->cirrus_blt_height-1) * pitch ++ + s->cirrus_blt_width; ++ if (max >= s->vga.vram_size) { ++ return true; ++ } ++ } ++ return false; ++} ++ ++static bool blit_is_unsafe(struct CirrusVGAState *s) ++{ ++ /* should be the case, see cirrus_bitblt_start */ ++ assert(s->cirrus_blt_width > 0); ++ assert(s->cirrus_blt_height > 0); ++ ++ if (s->cirrus_blt_width > CIRRUS_BLTBUFSIZE) { ++ return true; ++ } ++ ++ if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch, ++ s->cirrus_blt_dstaddr & s->cirrus_addr_mask)) { ++ return true; ++ } ++ if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch, ++ s->cirrus_blt_srcaddr & s->cirrus_addr_mask)) { ++ return true; ++ } ++ ++ return false; ++} ++ + static void cirrus_bitblt_rop_nop(CirrusVGAState *s, + uint8_t *dst,const uint8_t *src, + int dstpitch,int srcpitch, +@@ -635,7 +665,7 @@ + + dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask); + +- if (BLTUNSAFE(s)) ++ if (blit_is_unsafe(s)) + return 0; + + (*s->cirrus_rop) (s, dst, src, +@@ -653,8 +683,9 @@ + { + cirrus_fill_t rop_func; + +- if (BLTUNSAFE(s)) ++ if (blit_is_unsafe(s)) { + 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), + s->cirrus_blt_dstpitch, +@@ -751,7 +782,7 @@ + + static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) + { +- if (BLTUNSAFE(s)) ++ if (blit_is_unsafe(s)) + return 0; + + cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr, diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-9718.patch qemu-2.0.0+dfsg/debian/patches/CVE-2014-9718.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2014-9718.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2014-9718.patch 2015-08-25 15:49:14.000000000 +0000 @@ -0,0 +1,337 @@ +Backport of: + +From 3251bdcf1c67427d964517053c3d185b46e618e8 Mon Sep 17 00:00:00 2001 +From: John Snow +Date: Fri, 31 Oct 2014 16:03:39 -0400 +Subject: [PATCH] ide: Correct handling of malformed/short PRDTs + +This impacts both BMDMA and AHCI HBA interfaces for IDE. +Currently, we confuse the difference between a PRDT having +"0 bytes" and a PRDT having "0 complete sectors." + +When we receive an incomplete sector, inconsistent error checking +leads to an infinite loop wherein the call succeeds, but it +didn't give us enough bytes -- leading us to re-call the +DMA chain over and over again. This leads to, in the BMDMA case, +leaked memory for short PRDTs, and infinite loops and resource +usage in the AHCI case. + +The .prepare_buf() callback is reworked to return the number of +bytes that it successfully prepared. 0 is a valid, non-error +answer that means the table was empty and described no bytes. +-1 indicates an error. + +Our current implementation uses the io_buffer in IDEState to +ultimately describe the size of a prepared scatter-gather list. +Even though the AHCI PRDT/SGList can be as large as 256GiB, the +AHCI command header limits transactions to just 4GiB. ATA8-ACS3, +however, defines the largest transaction to be an LBA48 command +that transfers 65,536 sectors. With a 512 byte sector size, this +is just 32MiB. + +Since our current state structures use the int type to describe +the size of the buffer, and this state is migrated as int32, we +are limited to describing 2GiB buffer sizes unless we change the +migration protocol. + +For this reason, this patch begins to unify the assertions in the +IDE pathways that the scatter-gather list provided by either the +AHCI PRDT or the PCI BMDMA PRDs can only describe, at a maximum, +2GiB. This should be resilient enough unless we need a sector +size that exceeds 32KiB. + +Further, the likelihood of any guest operating system actually +attempting to transfer this much data in a single operation is +very slim. + +To this end, the IDEState variables have been updated to more +explicitly clarify our maximum supported size. Callers to the +prepare_buf callback have been reworked to understand the new +return code, and all versions of the prepare_buf callback have +been adjusted accordingly. + +Lastly, the ahci_populate_sglist helper, relied upon by the +AHCI implementation of .prepare_buf() as well as the PCI +implementation of the callback have had overflow assertions +added to help make clear the reasonings behind the various +type changes. + +[Added %d -> %"PRId64" fix John sent because off_pos changed from int to +int64_t. +--Stefan] + +Signed-off-by: John Snow +Reviewed-by: Paolo Bonzini +Message-id: 1414785819-26209-4-git-send-email-jsnow@redhat.com +Signed-off-by: Stefan Hajnoczi +--- + hw/ide/ahci.c | 33 ++++++++++++++++++++++++++------- + hw/ide/core.c | 10 ++++++++-- + hw/ide/internal.h | 13 +++++++------ + hw/ide/macio.c | 7 ++++++- + hw/ide/pci.c | 27 +++++++++++++++++++++------ + 5 files changed, 68 insertions(+), 22 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/ide/ahci.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/ide/ahci.c 2015-08-25 09:56:30.496062375 -0400 ++++ qemu-2.0.0+dfsg/hw/ide/ahci.c 2015-08-25 09:58:28.321286292 -0400 +@@ -639,7 +639,8 @@ + } + } + +-static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist, int offset) ++static int ahci_populate_sglist(AHCIDevice *ad, QEMUSGList *sglist, ++ int32_t offset) + { + AHCICmdHdr *cmd = ad->cur_cmd; + uint32_t opts = le32_to_cpu(cmd->opts); +@@ -650,13 +651,21 @@ + uint8_t *prdt; + int i; + int r = 0; +- int sum = 0; ++ uint64_t sum = 0; + int off_idx = -1; +- int off_pos = -1; ++ int64_t off_pos = -1; + int tbl_entry_size; + IDEBus *bus = &ad->port; + BusState *qbus = BUS(bus); + ++ /* ++ * Note: AHCI PRDT can describe up to 256GiB. SATA/ATA only support ++ * transactions of up to 32MiB as of ATA8-ACS3 rev 1b, assuming a ++ * 512 byte sector size. We limit the PRDT in this implementation to ++ * a reasonably large 2GiB, which can accommodate the maximum transfer ++ * request for sector sizes up to 32K. ++ */ ++ + if (!sglist_alloc_hint) { + DPRINTF(ad->port_no, "no sg list given by guest: 0x%08x\n", opts); + return -1; +@@ -691,7 +700,7 @@ + } + if ((off_idx == -1) || (off_pos < 0) || (off_pos > tbl_entry_size)) { + DPRINTF(ad->port_no, "%s: Incorrect offset! " +- "off_idx: %d, off_pos: %d\n", ++ "off_idx: %d, off_pos: %"PRId64"\n", + __func__, off_idx, off_pos); + r = -1; + goto out; +@@ -706,6 +715,13 @@ + /* flags_size is zero-based */ + qemu_sglist_add(sglist, le64_to_cpu(tbl[i].addr), + le32_to_cpu(tbl[i].flags_size) + 1); ++ if (sglist->size > INT32_MAX) { ++ error_report("AHCI Physical Region Descriptor Table describes " ++ "more than 2 GiB.\n"); ++ qemu_sglist_destroy(sglist); ++ r = -1; ++ goto out; ++ } + } + } + +@@ -1050,16 +1066,19 @@ + dma_cb(s, 0); + } + +-static int ahci_dma_prepare_buf(IDEDMA *dma, int is_write) ++static int32_t ahci_dma_prepare_buf(IDEDMA *dma, int is_write) + { + AHCIDevice *ad = DO_UPCAST(AHCIDevice, dma, dma); + IDEState *s = &ad->port.ifs[0]; + +- ahci_populate_sglist(ad, &s->sg, 0); ++ if (ahci_populate_sglist(ad, &s->sg, 0) == -1) { ++ DPRINTF(ad->port_no, "ahci_dma_prepare_buf failed.\n"); ++ return -1; ++ } + s->io_buffer_size = s->sg.size; + + DPRINTF(ad->port_no, "len=%#x\n", s->io_buffer_size); +- return s->io_buffer_size != 0; ++ return s->io_buffer_size; + } + + static int ahci_dma_rw_buf(IDEDMA *dma, int is_write) +Index: qemu-2.0.0+dfsg/hw/ide/core.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/ide/core.c 2015-08-25 09:56:30.496062375 -0400 ++++ qemu-2.0.0+dfsg/hw/ide/core.c 2015-08-25 09:58:57.121585236 -0400 +@@ -659,10 +659,11 @@ + n = s->nsector; + s->io_buffer_index = 0; + s->io_buffer_size = n * 512; +- if (s->bus->dma->ops->prepare_buf(s->bus->dma, ide_cmd_is_read(s)) == 0) { ++ if (s->bus->dma->ops->prepare_buf(s->bus->dma, ide_cmd_is_read(s)) < 512) { + /* The PRDs were too short. Reset the Active bit, but don't raise an + * interrupt. */ + s->status = READY_STAT | SEEK_STAT; ++ dma_buf_commit(s); + goto eot; + } + +@@ -2207,6 +2208,11 @@ + return 0; + } + ++static int32_t ide_nop_int32(IDEDMA *dma, int x) ++{ ++ return 0; ++} ++ + static void ide_nop_restart(void *opaque, int x, RunState y) + { + } +@@ -2214,7 +2220,7 @@ + static const IDEDMAOps ide_dma_nop_ops = { + .start_dma = ide_nop_start, + .start_transfer = ide_nop, +- .prepare_buf = ide_nop_int, ++ .prepare_buf = ide_nop_int32, + .rw_buf = ide_nop_int, + .set_unit = ide_nop_int, + .add_status = ide_nop_int, +Index: qemu-2.0.0+dfsg/hw/ide/internal.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/ide/internal.h 2015-08-25 09:56:30.496062375 -0400 ++++ qemu-2.0.0+dfsg/hw/ide/internal.h 2015-08-25 09:59:32.225949500 -0400 +@@ -322,6 +322,7 @@ + typedef void DMAStartFunc(IDEDMA *, IDEState *, BlockDriverCompletionFunc *); + typedef int DMAFunc(IDEDMA *); + typedef int DMAIntFunc(IDEDMA *, int); ++typedef int32_t DMAInt32Func(IDEDMA *, int); + typedef void DMARestartFunc(void *, int, RunState); + + struct unreported_events { +@@ -383,7 +384,7 @@ + uint8_t cdrom_changed; + int packet_transfer_size; + int elementary_transfer_size; +- int io_buffer_index; ++ int32_t io_buffer_index; + int lba; + int cd_sector_size; + int atapi_dma; /* true if dma is requested for the packet cmd */ +@@ -392,8 +393,8 @@ + struct iovec iov; + QEMUIOVector qiov; + /* ATA DMA state */ +- int io_buffer_offset; +- int io_buffer_size; ++ int32_t io_buffer_offset; ++ int32_t io_buffer_size; + QEMUSGList sg; + /* PIO transfer handling */ + int req_nb_sectors; /* number of sectors per interrupt */ +@@ -403,8 +404,8 @@ + uint8_t *io_buffer; + /* PIO save/restore */ + int32_t io_buffer_total_len; +- int cur_io_buffer_offset; +- int cur_io_buffer_len; ++ int32_t cur_io_buffer_offset; ++ int32_t cur_io_buffer_len; + uint8_t end_transfer_fn_idx; + QEMUTimer *sector_write_timer; /* only used for win2k install hack */ + uint32_t irq_count; /* counts IRQs when using win2k install hack */ +@@ -428,7 +429,7 @@ + struct IDEDMAOps { + DMAStartFunc *start_dma; + DMAFunc *start_transfer; +- DMAIntFunc *prepare_buf; ++ DMAInt32Func *prepare_buf; + DMAIntFunc *rw_buf; + DMAIntFunc *set_unit; + DMAIntFunc *add_status; +Index: qemu-2.0.0+dfsg/hw/ide/macio.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/ide/macio.c 2015-08-25 09:56:30.496062375 -0400 ++++ qemu-2.0.0+dfsg/hw/ide/macio.c 2015-08-25 09:59:50.150135444 -0400 +@@ -505,6 +505,11 @@ + return 0; + } + ++static int32_t ide_nop_int32(IDEDMA *dma, int x) ++{ ++ return 0; ++} ++ + static void ide_nop_restart(void *opaque, int x, RunState y) + { + } +@@ -522,7 +527,7 @@ + static const IDEDMAOps dbdma_ops = { + .start_dma = ide_dbdma_start, + .start_transfer = ide_nop, +- .prepare_buf = ide_nop_int, ++ .prepare_buf = ide_nop_int32, + .rw_buf = ide_nop_int, + .set_unit = ide_nop_int, + .add_status = ide_nop_int, +Index: qemu-2.0.0+dfsg/hw/ide/pci.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/ide/pci.c 2015-08-25 09:56:30.496062375 -0400 ++++ qemu-2.0.0+dfsg/hw/ide/pci.c 2015-08-25 09:56:30.492062334 -0400 +@@ -28,7 +28,7 @@ + #include + #include "block/block.h" + #include "sysemu/dma.h" +- ++#include "qemu/error-report.h" + #include + + #define BMDMA_PAGE_SIZE 4096 +@@ -51,8 +51,11 @@ + } + } + +-/* return 0 if buffer completed */ +-static int bmdma_prepare_buf(IDEDMA *dma, int is_write) ++/** ++ * Return the number of bytes successfully prepared. ++ * -1 on error. ++ */ ++static int32_t bmdma_prepare_buf(IDEDMA *dma, int is_write) + { + BMDMAState *bm = DO_UPCAST(BMDMAState, dma, dma); + IDEState *s = bmdma_active_if(bm); +@@ -70,8 +73,9 @@ + if (bm->cur_prd_len == 0) { + /* end of table (with a fail safe of one page) */ + if (bm->cur_prd_last || +- (bm->cur_addr - bm->addr) >= BMDMA_PAGE_SIZE) +- return s->io_buffer_size != 0; ++ (bm->cur_addr - bm->addr) >= BMDMA_PAGE_SIZE) { ++ return s->io_buffer_size; ++ } + pci_dma_read(pci_dev, bm->cur_addr, &prd, 8); + bm->cur_addr += 8; + prd.addr = le32_to_cpu(prd.addr); +@@ -86,12 +90,23 @@ + l = bm->cur_prd_len; + if (l > 0) { + qemu_sglist_add(&s->sg, bm->cur_prd_addr, l); ++ ++ /* Note: We limit the max transfer to be 2GiB. ++ * This should accommodate the largest ATA transaction ++ * for LBA48 (65,536 sectors) and 32K sector sizes. */ ++ if (s->sg.size > INT32_MAX) { ++ error_report("IDE: sglist describes more than 2GiB.\n"); ++ break; ++ } + bm->cur_prd_addr += l; + bm->cur_prd_len -= l; + s->io_buffer_size += l; + } + } +- return 1; ++ ++ qemu_sglist_destroy(&s->sg); ++ s->io_buffer_size = 0; ++ return -1; + } + + /* return 0 if buffer completed */ diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-1779-1.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-1779-1.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-1779-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-1779-1.patch 2015-05-13 11:58:39.000000000 +0000 @@ -0,0 +1,238 @@ +From a2bebfd6e09d285aa793cae3fb0fc3a39a9fee6e Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +Date: Mon, 23 Mar 2015 22:58:21 +0000 +Subject: [PATCH] CVE-2015-1779: incrementally decode websocket frames + +The logic for decoding websocket frames wants to fully +decode the frame header and payload, before allowing the +VNC server to see any of the payload data. There is no +size limit on websocket payloads, so this allows a +malicious network client to consume 2^64 bytes in memory +in QEMU. It can trigger this denial of service before +the VNC server even performs any authentication. + +The fix is to decode the header, and then incrementally +decode the payload data as it is needed. With this fix +the websocket decoder will allow at most 4k of data to +be buffered before decoding and processing payload. + +Signed-off-by: Daniel P. Berrange + +[ kraxel: fix frequent spurious disconnects, suggested by Peter Maydell ] + + @@ -361,7 +361,7 @@ int vncws_decode_frame_payload(Buffer *input, + - *payload_size = input->offset; + + *payload_size = *payload_remain; + +[ kraxel: fix 32bit build ] + + @@ -306,7 +306,7 @@ struct VncState + - uint64_t ws_payload_remain; + + size_t ws_payload_remain; + +Signed-off-by: Gerd Hoffmann +--- + ui/vnc-ws.c | 105 ++++++++++++++++++++++++++++++++++++++++------------------- + ui/vnc-ws.h | 9 ++++- + ui/vnc.h | 2 + + 3 files changed, 80 insertions(+), 36 deletions(-) + +Index: qemu-2.0.0+dfsg/ui/vnc-ws.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/ui/vnc-ws.c 2015-05-13 07:58:35.612172114 -0400 ++++ qemu-2.0.0+dfsg/ui/vnc-ws.c 2015-05-13 07:58:35.572171810 -0400 +@@ -115,7 +115,7 @@ + { + int ret, err; + uint8_t *payload; +- size_t payload_size, frame_size; ++ size_t payload_size, header_size; + VNC_DEBUG("Read websocket %p size %zd offset %zd\n", vs->ws_input.buffer, + vs->ws_input.capacity, vs->ws_input.offset); + buffer_reserve(&vs->ws_input, 4096); +@@ -125,18 +125,39 @@ + } + vs->ws_input.offset += ret; + +- /* make sure that nothing is left in the ws_input buffer */ ++ ret = 0; ++ /* consume as much of ws_input buffer as possible */ + do { +- err = vncws_decode_frame(&vs->ws_input, &payload, +- &payload_size, &frame_size); +- if (err <= 0) { +- return err; ++ if (vs->ws_payload_remain == 0) { ++ err = vncws_decode_frame_header(&vs->ws_input, ++ &header_size, ++ &vs->ws_payload_remain, ++ &vs->ws_payload_mask); ++ if (err <= 0) { ++ return err; ++ } ++ ++ buffer_advance(&vs->ws_input, header_size); + } ++ if (vs->ws_payload_remain != 0) { ++ err = vncws_decode_frame_payload(&vs->ws_input, ++ &vs->ws_payload_remain, ++ &vs->ws_payload_mask, ++ &payload, ++ &payload_size); ++ if (err < 0) { ++ return err; ++ } ++ if (err == 0) { ++ return ret; ++ } ++ ret += err; + +- buffer_reserve(&vs->input, payload_size); +- buffer_append(&vs->input, payload, payload_size); ++ buffer_reserve(&vs->input, payload_size); ++ buffer_append(&vs->input, payload, payload_size); + +- buffer_advance(&vs->ws_input, frame_size); ++ buffer_advance(&vs->ws_input, payload_size); ++ } + } while (vs->ws_input.offset > 0); + + return ret; +@@ -274,15 +295,14 @@ + buffer_append(output, payload, payload_size); + } + +-int vncws_decode_frame(Buffer *input, uint8_t **payload, +- size_t *payload_size, size_t *frame_size) ++int vncws_decode_frame_header(Buffer *input, ++ size_t *header_size, ++ size_t *payload_remain, ++ WsMask *payload_mask) + { + unsigned char opcode = 0, fin = 0, has_mask = 0; +- size_t header_size = 0; +- uint32_t *payload32; ++ size_t payload_len; + WsHeader *header = (WsHeader *)input->buffer; +- WsMask mask; +- int i; + + if (input->offset < WS_HEAD_MIN_LEN + 4) { + /* header not complete */ +@@ -292,7 +312,7 @@ + fin = (header->b0 & 0x80) >> 7; + opcode = header->b0 & 0x0f; + has_mask = (header->b1 & 0x80) >> 7; +- *payload_size = header->b1 & 0x7f; ++ payload_len = header->b1 & 0x7f; + + if (opcode == WS_OPCODE_CLOSE) { + /* disconnect */ +@@ -309,40 +329,57 @@ + return -2; + } + +- if (*payload_size < 126) { +- header_size = 6; +- mask = header->u.m; +- } else if (*payload_size == 126 && input->offset >= 8) { +- *payload_size = be16_to_cpu(header->u.s16.l16); +- header_size = 8; +- mask = header->u.s16.m16; +- } else if (*payload_size == 127 && input->offset >= 14) { +- *payload_size = be64_to_cpu(header->u.s64.l64); +- header_size = 14; +- mask = header->u.s64.m64; ++ if (payload_len < 126) { ++ *payload_remain = payload_len; ++ *header_size = 6; ++ *payload_mask = header->u.m; ++ } else if (payload_len == 126 && input->offset >= 8) { ++ *payload_remain = be16_to_cpu(header->u.s16.l16); ++ *header_size = 8; ++ *payload_mask = header->u.s16.m16; ++ } else if (payload_len == 127 && input->offset >= 14) { ++ *payload_remain = be64_to_cpu(header->u.s64.l64); ++ *header_size = 14; ++ *payload_mask = header->u.s64.m64; + } else { + /* header not complete */ + return 0; + } + +- *frame_size = header_size + *payload_size; ++ return 1; ++} + +- if (input->offset < *frame_size) { +- /* frame not complete */ ++int vncws_decode_frame_payload(Buffer *input, ++ size_t *payload_remain, WsMask *payload_mask, ++ uint8_t **payload, size_t *payload_size) ++{ ++ size_t i; ++ uint32_t *payload32; ++ ++ *payload = input->buffer; ++ /* If we aren't at the end of the payload, then drop ++ * off the last bytes, so we're always multiple of 4 ++ * for purpose of unmasking, except at end of payload ++ */ ++ if (input->offset < *payload_remain) { ++ *payload_size = input->offset - (input->offset % 4); ++ } else { ++ *payload_size = *payload_remain; ++ } ++ if (*payload_size == 0) { + return 0; + } +- +- *payload = input->buffer + header_size; ++ *payload_remain -= *payload_size; + + /* unmask frame */ + /* process 1 frame (32 bit op) */ + payload32 = (uint32_t *)(*payload); + for (i = 0; i < *payload_size / 4; i++) { +- payload32[i] ^= mask.u; ++ payload32[i] ^= payload_mask->u; + } + /* process the remaining bytes (if any) */ + for (i *= 4; i < *payload_size; i++) { +- (*payload)[i] ^= mask.c[i % 4]; ++ (*payload)[i] ^= payload_mask->c[i % 4]; + } + + return 1; +Index: qemu-2.0.0+dfsg/ui/vnc-ws.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/ui/vnc-ws.h 2015-05-13 07:58:35.612172114 -0400 ++++ qemu-2.0.0+dfsg/ui/vnc-ws.h 2015-05-13 07:58:35.572171810 -0400 +@@ -83,7 +83,12 @@ + void vncws_process_handshake(VncState *vs, uint8_t *line, size_t size); + void vncws_encode_frame(Buffer *output, const void *payload, + const size_t payload_size); +-int vncws_decode_frame(Buffer *input, uint8_t **payload, +- size_t *payload_size, size_t *frame_size); ++int vncws_decode_frame_header(Buffer *input, ++ size_t *header_size, ++ size_t *payload_remain, ++ WsMask *payload_mask); ++int vncws_decode_frame_payload(Buffer *input, ++ size_t *payload_remain, WsMask *payload_mask, ++ uint8_t **payload, size_t *payload_size); + + #endif /* __QEMU_UI_VNC_WS_H */ +Index: qemu-2.0.0+dfsg/ui/vnc.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/ui/vnc.h 2015-05-13 07:58:35.612172114 -0400 ++++ qemu-2.0.0+dfsg/ui/vnc.h 2015-05-13 07:58:35.572171810 -0400 +@@ -299,6 +299,8 @@ + #ifdef CONFIG_VNC_WS + Buffer ws_input; + Buffer ws_output; ++ size_t ws_payload_remain; ++ WsMask ws_payload_mask; + #endif + /* current output mode information */ + VncWritePixels *write_pixels; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-1779-2.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-1779-2.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-1779-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-1779-2.patch 2015-05-13 11:58:42.000000000 +0000 @@ -0,0 +1,54 @@ +From 2cdb5e142fb93e875fa53c52864ef5eb8d5d8b41 Mon Sep 17 00:00:00 2001 +From: Daniel P. Berrange +Date: Mon, 23 Mar 2015 22:58:22 +0000 +Subject: [PATCH] CVE-2015-1779: limit size of HTTP headers from websockets clients + +The VNC server websockets decoder will read and buffer data from +websockets clients until it sees the end of the HTTP headers, +as indicated by \r\n\r\n. In theory this allows a malicious to +trick QEMU into consuming an arbitrary amount of RAM. In practice, +because QEMU runs g_strstr_len() across the buffered header data, +it will spend increasingly long burning CPU time searching for +the substring match and less & less time reading data. So while +this does cause arbitrary memory growth, the bigger problem is +that QEMU will be burning 100% of available CPU time. + +A novnc websockets client typically sends headers of around +512 bytes in length. As such it is reasonable to place a 4096 +byte limit on the amount of data buffered while searching for +the end of HTTP headers. + +Signed-off-by: Daniel P. Berrange +Signed-off-by: Gerd Hoffmann +--- + ui/vnc-ws.c | 10 ++++++++-- + 1 files changed, 8 insertions(+), 2 deletions(-) + +Index: qemu-2.2+dfsg/ui/vnc-ws.c +=================================================================== +--- qemu-2.2+dfsg.orig/ui/vnc-ws.c 2015-05-13 07:25:33.581211895 -0400 ++++ qemu-2.2+dfsg/ui/vnc-ws.c 2015-05-13 07:25:33.577211865 -0400 +@@ -89,8 +89,11 @@ + VncState *vs = opaque; + uint8_t *handshake_end; + long ret; +- buffer_reserve(&vs->ws_input, 4096); +- ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), 4096); ++ /* Typical HTTP headers from novnc are 512 bytes, so limiting ++ * total header size to 4096 is easily enough. */ ++ size_t want = 4096 - vs->ws_input.offset; ++ buffer_reserve(&vs->ws_input, want); ++ ret = vnc_client_read_buf(vs, buffer_end(&vs->ws_input), want); + + if (!ret) { + if (vs->csock == -1) { +@@ -107,6 +110,9 @@ + vncws_process_handshake(vs, vs->ws_input.buffer, vs->ws_input.offset); + buffer_advance(&vs->ws_input, handshake_end - vs->ws_input.buffer + + strlen(WS_HANDSHAKE_END)); ++ } else if (vs->ws_input.offset >= 4096) { ++ VNC_DEBUG("End of headers not found in first 4096 bytes\n"); ++ vnc_client_error(vs); + } + } + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-2756.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-2756.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-2756.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-2756.patch 2015-05-13 11:58:52.000000000 +0000 @@ -0,0 +1,143 @@ +Backport of: + +From 81b23ef82cd1be29ca3d69ab7e98b5b5e55926ce Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Tue, 31 Mar 2015 15:18:03 +0100 +Subject: [PATCH] xen: limit guest control of PCI command register + +Otherwise the guest can abuse that control to cause e.g. PCIe +Unsupported Request responses (by disabling memory and/or I/O decoding +and subsequently causing [CPU side] accesses to the respective address +ranges), which (depending on system configuration) may be fatal to the +host. + +This is CVE-2015-2756 / XSA-126. + +Signed-off-by: Jan Beulich +Reviewed-by: Stefano Stabellini +Acked-by: Ian Campbell +Message-id: alpine.DEB.2.02.1503311510300.7690@kaball.uk.xensource.com +Signed-off-by: Peter Maydell +--- + hw/xen/xen_pt.c | 12 ++++++++++-- + hw/xen/xen_pt_config_init.c | 28 +++------------------------- + 2 files changed, 13 insertions(+), 27 deletions(-) + +Index: qemu-2.1+dfsg/hw/xen/xen_pt.c +=================================================================== +--- qemu-2.1+dfsg.orig/hw/xen/xen_pt.c 2015-05-13 07:44:51.997941235 -0400 ++++ qemu-2.1+dfsg/hw/xen/xen_pt.c 2015-05-13 07:45:30.546232109 -0400 +@@ -388,7 +388,7 @@ + .write = xen_pt_bar_write, + }; + +-static int xen_pt_register_regions(XenPCIPassthroughState *s) ++static int xen_pt_register_regions(XenPCIPassthroughState *s, uint16_t *cmd) + { + int i = 0; + XenHostPCIDevice *d = &s->real_device; +@@ -406,6 +406,7 @@ + + if (r->type & XEN_HOST_PCI_REGION_TYPE_IO) { + type = PCI_BASE_ADDRESS_SPACE_IO; ++ *cmd |= PCI_COMMAND_IO; + } else { + type = PCI_BASE_ADDRESS_SPACE_MEMORY; + if (r->type & XEN_HOST_PCI_REGION_TYPE_PREFETCH) { +@@ -414,6 +415,7 @@ + if (r->type & XEN_HOST_PCI_REGION_TYPE_MEM_64) { + type |= PCI_BASE_ADDRESS_MEM_TYPE_64; + } ++ *cmd |= PCI_COMMAND_MEMORY; + } + + memory_region_init_io(&s->bar[i], OBJECT(s), &ops, &s->dev, +@@ -657,6 +659,7 @@ + XenPCIPassthroughState *s = DO_UPCAST(XenPCIPassthroughState, dev, d); + int rc = 0; + uint8_t machine_irq = 0; ++ uint16_t cmd = 0; + int pirq = XEN_PT_UNASSIGNED_PIRQ; + + /* register real device */ +@@ -691,7 +694,7 @@ + s->io_listener = xen_pt_io_listener; + + /* Handle real device's MMIO/PIO BARs */ +- xen_pt_register_regions(s); ++ xen_pt_register_regions(s, &cmd); + + /* reinitialize each config register to be emulated */ + if (xen_pt_config_init(s)) { +@@ -755,6 +758,11 @@ + } + + out: ++ if (cmd) { ++ xen_host_pci_set_word(&s->real_device, PCI_COMMAND, ++ pci_get_word(d->config + PCI_COMMAND) | cmd); ++ } ++ + memory_listener_register(&s->memory_listener, &address_space_memory); + memory_listener_register(&s->io_listener, &address_space_io); + XEN_PT_LOG(d, +Index: qemu-2.1+dfsg/hw/xen/xen_pt_config_init.c +=================================================================== +--- qemu-2.1+dfsg.orig/hw/xen/xen_pt_config_init.c 2015-05-13 07:44:51.997941235 -0400 ++++ qemu-2.1+dfsg/hw/xen/xen_pt_config_init.c 2015-05-13 07:44:51.957940933 -0400 +@@ -286,23 +286,6 @@ + } + + /* Command register */ +-static int xen_pt_cmd_reg_read(XenPCIPassthroughState *s, XenPTReg *cfg_entry, +- uint16_t *value, uint16_t valid_mask) +-{ +- XenPTRegInfo *reg = cfg_entry->reg; +- uint16_t valid_emu_mask = 0; +- uint16_t emu_mask = reg->emu_mask; +- +- if (s->is_virtfn) { +- emu_mask |= PCI_COMMAND_MEMORY; +- } +- +- /* emulate word register */ +- valid_emu_mask = emu_mask & valid_mask; +- *value = XEN_PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask); +- +- return 0; +-} + static int xen_pt_cmd_reg_write(XenPCIPassthroughState *s, XenPTReg *cfg_entry, + uint16_t *val, uint16_t dev_value, + uint16_t valid_mask) +@@ -310,18 +293,13 @@ + XenPTRegInfo *reg = cfg_entry->reg; + uint16_t writable_mask = 0; + uint16_t throughable_mask = 0; +- uint16_t emu_mask = reg->emu_mask; +- +- if (s->is_virtfn) { +- emu_mask |= PCI_COMMAND_MEMORY; +- } + + /* modify emulate register */ + writable_mask = ~reg->ro_mask & valid_mask; + cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); + + /* create value for writing to I/O device register */ +- throughable_mask = ~emu_mask & valid_mask; ++ throughable_mask = ~reg->emu_mask & valid_mask; + + if (*val & PCI_COMMAND_INTX_DISABLE) { + throughable_mask |= PCI_COMMAND_INTX_DISABLE; +@@ -605,9 +583,9 @@ + .size = 2, + .init_val = 0x0000, + .ro_mask = 0xF880, +- .emu_mask = 0x0740, ++ .emu_mask = 0x0743, + .init = xen_pt_common_reg_init, +- .u.w.read = xen_pt_cmd_reg_read, ++ .u.w.read = xen_pt_word_reg_read, + .u.w.write = xen_pt_cmd_reg_write, + }, + /* Capabilities Pointer reg */ diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-3209.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-3209.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-3209.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-3209.patch 2015-06-09 13:37:16.000000000 +0000 @@ -0,0 +1,42 @@ +From 2630672ab22255de252f877709851c0557a1c647 Mon Sep 17 00:00:00 2001 +From: Petr Matousek +Date: Sun, 24 May 2015 10:53:44 +0200 +Subject: [PATCH] pcnet: force the buffer access to be in bounds during tx + +4096 is the maximum length per TMD and it is also currently the size of +the relay buffer pcnet driver uses for sending the packet data to QEMU +for further processing. With packet spanning multiple TMDs it can +happen that the overall packet size will be bigger than sizeof(buffer), +which results in memory corruption. + +Fix this by only allowing to queue maximum sizeof(buffer) bytes. + +This is CVE-2015-3209. + +Signed-off-by: Petr Matousek +Reported-by: Matt Tait +Reviewed-by: Peter Maydell +Reviewed-by: Stefan Hajnoczi +--- + hw/net/pcnet.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +Index: qemu-2.0.0+dfsg/hw/net/pcnet.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/pcnet.c 2015-06-09 09:37:13.714269970 -0400 ++++ qemu-2.0.0+dfsg/hw/net/pcnet.c 2015-06-09 09:37:13.674269503 -0400 +@@ -1254,6 +1254,14 @@ + } + + bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); ++ ++ /* if multi-tmd packet outsizes s->buffer then skip it silently. ++ Note: this is not what real hw does */ ++ if (s->xmit_pos + bcnt > sizeof(s->buffer)) { ++ s->xmit_pos = -1; ++ goto txdone; ++ } ++ + s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), + s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); + s->xmit_pos += bcnt; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-3209-pre.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-3209-pre.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-3209-pre.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-3209-pre.patch 2015-06-09 13:37:07.000000000 +0000 @@ -0,0 +1,96 @@ +From 7b50d00911ddd6d56a766ac5671e47304c20a21b Mon Sep 17 00:00:00 2001 +From: Gonglei +Date: Thu, 20 Nov 2014 19:35:02 +0800 +Subject: [PATCH] pcnet: fix Negative array index read + +s->xmit_pos maybe assigned to a negative value (-1), +but in this branch variable s->xmit_pos as an index to +array s->buffer. Let's add a check for s->xmit_pos. + +Signed-off-by: Gonglei +Signed-off-by: Paolo Bonzini +Reviewed-by: Jason Wang +Reviewed-by: Jason Wang +Signed-off-by: Stefan Hajnoczi +--- + hw/net/pcnet.c | 55 ++++++++++++++++++++++++++++++------------------------- + 1 files changed, 30 insertions(+), 25 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/pcnet.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/pcnet.c 2015-06-09 09:37:05.062169021 -0400 ++++ qemu-2.0.0+dfsg/hw/net/pcnet.c 2015-06-09 09:37:05.038168741 -0400 +@@ -1213,7 +1213,7 @@ + hwaddr xmit_cxda = 0; + int count = CSR_XMTRL(s)-1; + int add_crc = 0; +- ++ int bcnt; + s->xmit_pos = -1; + + if (!CSR_TXON(s)) { +@@ -1248,35 +1248,40 @@ + s->xmit_pos = -1; + goto txdone; + } ++ ++ if (s->xmit_pos < 0) { ++ goto txdone; ++ } ++ ++ bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); ++ s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), ++ s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); ++ s->xmit_pos += bcnt; ++ + if (!GET_FIELD(tmd.status, TMDS, ENP)) { +- int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); +- s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), +- s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); +- s->xmit_pos += bcnt; +- } else if (s->xmit_pos >= 0) { +- int bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); +- s->phys_mem_read(s->dma_opaque, PHYSADDR(s, tmd.tbadr), +- s->buffer + s->xmit_pos, bcnt, CSR_BSWP(s)); +- s->xmit_pos += bcnt; ++ goto txdone; ++ } ++ + #ifdef PCNET_DEBUG +- printf("pcnet_transmit size=%d\n", s->xmit_pos); ++ printf("pcnet_transmit size=%d\n", s->xmit_pos); + #endif +- if (CSR_LOOP(s)) { +- if (BCR_SWSTYLE(s) == 1) +- add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS); +- s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC; +- pcnet_receive(qemu_get_queue(s->nic), s->buffer, s->xmit_pos); +- s->looptest = 0; +- } else +- if (s->nic) +- qemu_send_packet(qemu_get_queue(s->nic), s->buffer, +- s->xmit_pos); +- +- s->csr[0] &= ~0x0008; /* clear TDMD */ +- s->csr[4] |= 0x0004; /* set TXSTRT */ +- s->xmit_pos = -1; ++ if (CSR_LOOP(s)) { ++ if (BCR_SWSTYLE(s) == 1) ++ add_crc = !GET_FIELD(tmd.status, TMDS, NOFCS); ++ s->looptest = add_crc ? PCNET_LOOPTEST_CRC : PCNET_LOOPTEST_NOCRC; ++ pcnet_receive(qemu_get_queue(s->nic), s->buffer, s->xmit_pos); ++ s->looptest = 0; ++ } else { ++ if (s->nic) { ++ qemu_send_packet(qemu_get_queue(s->nic), s->buffer, ++ s->xmit_pos); ++ } + } + ++ s->csr[0] &= ~0x0008; /* clear TDMD */ ++ s->csr[4] |= 0x0004; /* set TXSTRT */ ++ s->xmit_pos = -1; ++ + txdone: + SET_FIELD(&tmd.status, TMDS, OWN, 0); + TMDSTORE(&tmd, PHYSADDR(s,CSR_CXDA(s))); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-3214.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-3214.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-3214.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-3214.patch 2015-07-27 18:22:41.000000000 +0000 @@ -0,0 +1,43 @@ +From d4862a87e31a51de9eb260f25c9e99a75efe3235 Mon Sep 17 00:00:00 2001 +From: Petr Matousek +Date: Wed, 17 Jun 2015 12:46:11 +0200 +Subject: [PATCH] i8254: fix out-of-bounds memory access in pit_ioport_read() + +Due converting PIO to the new memory read/write api we no longer provide +separate I/O region lenghts for read and write operations. As a result, +reading from PIT Mode/Command register will end with accessing +pit->channels with invalid index. + +Fix this by ignoring read from the Mode/Command register. + +This is CVE-2015-3214. + +Reported-by: Matt Tait +Fixes: 0505bcdec8228d8de39ab1a02644e71999e7c052 +Cc: qemu-stable@nongnu.org +Signed-off-by: Petr Matousek +Signed-off-by: Paolo Bonzini +--- + hw/timer/i8254.c | 6 ++++++ + 1 files changed, 6 insertions(+), 0 deletions(-) + +diff --git a/hw/timer/i8254.c b/hw/timer/i8254.c +index 3450c98..9b65a33 100644 +--- a/hw/timer/i8254.c ++++ b/hw/timer/i8254.c +@@ -196,6 +196,12 @@ static uint64_t pit_ioport_read(void *opaque, hwaddr addr, + PITChannelState *s; + + addr &= 3; ++ ++ if (addr == 3) { ++ /* Mode/Command register is write only, read is ignored */ ++ return 0; ++ } ++ + s = &pit->channels[addr]; + if (s->status_latched) { + s->status_latched = 0; +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-3456.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-3456.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-3456.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-3456.patch 2015-05-13 11:59:03.000000000 +0000 @@ -0,0 +1,80 @@ +From ac7ddbe342d7aa2303c39ca731cc6229dbbd739b Mon Sep 17 00:00:00 2001 +From: Petr Matousek +Date: Wed, 6 May 2015 09:48:59 +0200 +Subject: [PATCH] fdc: force the fifo access to be in bounds of the allocated buffer + +During processing of certain commands such as FD_CMD_READ_ID and +FD_CMD_DRIVE_SPECIFICATION_COMMAND the fifo memory access could +get out of bounds leading to memory corruption with values coming +from the guest. + +Fix this by making sure that the index is always bounded by the +allocated memory. + +This is CVE-2015-3456. + +Signed-off-by: Petr Matousek +Reviewed-by: John Snow +--- + hw/block/fdc.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/block/fdc.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/block/fdc.c 2015-05-13 07:58:59.832355826 -0400 ++++ qemu-2.0.0+dfsg/hw/block/fdc.c 2015-05-13 07:58:59.776355401 -0400 +@@ -1440,7 +1440,7 @@ + { + FDrive *cur_drv; + uint32_t retval = 0; +- int pos; ++ uint32_t pos; + + cur_drv = get_cur_drv(fdctrl); + fdctrl->dsr &= ~FD_DSR_PWRDOWN; +@@ -1449,8 +1449,8 @@ + return 0; + } + pos = fdctrl->data_pos; ++ pos %= FD_SECTOR_LEN; + if (fdctrl->msr & FD_MSR_NONDMA) { +- pos %= FD_SECTOR_LEN; + if (pos == 0) { + if (fdctrl->data_pos != 0) + if (!fdctrl_seek_to_next_sect(fdctrl, cur_drv)) { +@@ -1794,10 +1794,13 @@ + static void fdctrl_handle_drive_specification_command(FDCtrl *fdctrl, int direction) + { + FDrive *cur_drv = get_cur_drv(fdctrl); ++ uint32_t pos; + +- if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x80) { ++ pos = fdctrl->data_pos - 1; ++ pos %= FD_SECTOR_LEN; ++ if (fdctrl->fifo[pos] & 0x80) { + /* Command parameters done */ +- if (fdctrl->fifo[fdctrl->data_pos - 1] & 0x40) { ++ if (fdctrl->fifo[pos] & 0x40) { + fdctrl->fifo[0] = fdctrl->fifo[1]; + fdctrl->fifo[2] = 0; + fdctrl->fifo[3] = 0; +@@ -1897,7 +1900,7 @@ + static void fdctrl_write_data(FDCtrl *fdctrl, uint32_t value) + { + FDrive *cur_drv; +- int pos; ++ uint32_t pos; + + /* Reset mode */ + if (!(fdctrl->dor & FD_DOR_nRESET)) { +@@ -1945,7 +1948,9 @@ + } + + FLOPPY_DPRINTF("%s: %02x\n", __func__, value); +- fdctrl->fifo[fdctrl->data_pos++] = value; ++ pos = fdctrl->data_pos++; ++ pos %= FD_SECTOR_LEN; ++ fdctrl->fifo[pos] = value; + if (fdctrl->data_pos == fdctrl->data_len) { + /* We now have all parameters + * and will be able to treat the command diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4037.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-4037.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4037.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-4037.patch 2015-06-09 13:37:26.000000000 +0000 @@ -0,0 +1,49 @@ +From 8b8f1c7e9ddb2e88a144638f6527bf70e32343e3 Mon Sep 17 00:00:00 2001 +From: Michael Tokarev +Date: Thu, 28 May 2015 14:12:26 +0300 +Subject: [PATCH] slirp: use less predictable directory name in /tmp for smb config (CVE-2015-4037) + +In this version I used mkdtemp(3) which is: + + _BSD_SOURCE + || /* Since glibc 2.10: */ + (_POSIX_C_SOURCE >= 200809L || _XOPEN_SOURCE >= 700) + +(POSIX.1-2008), so should be available on systems we care about. + +While at it, reset the resulting directory name within smb structure +on error so cleanup function wont try to remove directory which we +failed to create. + +Signed-off-by: Michael Tokarev +Reviewed-by: Markus Armbruster +--- + net/slirp.c | 7 +++---- + 1 files changed, 3 insertions(+), 4 deletions(-) + +Index: qemu-2.0.0+dfsg/net/slirp.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/net/slirp.c 2015-06-09 09:37:23.414383132 -0400 ++++ qemu-2.0.0+dfsg/net/slirp.c 2015-06-09 09:37:23.378382712 -0400 +@@ -481,7 +481,6 @@ + static int slirp_smb(SlirpState* s, const char *exported_dir, + struct in_addr vserver_addr) + { +- static int instance; + char smb_conf[128]; + char smb_cmdline[128]; + struct passwd *passwd; +@@ -505,10 +504,10 @@ + return -1; + } + +- snprintf(s->smb_dir, sizeof(s->smb_dir), "/tmp/qemu-smb.%ld-%d", +- (long)getpid(), instance++); +- if (mkdir(s->smb_dir, 0700) < 0) { ++ snprintf(s->smb_dir, sizeof(s->smb_dir), "/tmp/qemu-smb.XXXXXX"); ++ if (!mkdtemp(s->smb_dir)) { + error_report("could not create samba server dir '%s'", s->smb_dir); ++ s->smb_dir[0] = 0; + return -1; + } + snprintf(smb_conf, sizeof(smb_conf), "%s/%s", s->smb_dir, "smb.conf"); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4103.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-4103.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4103.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-4103.patch 2015-06-09 13:37:31.000000000 +0000 @@ -0,0 +1,132 @@ +From 5c83b2f5b4b956e91dd6e5711f14df7ab800aefb Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Tue, 2 Jun 2015 15:07:00 +0000 +Subject: [PATCH] xen: properly gate host writes of modified PCI CFG contents + +The old logic didn't work as intended when an access spanned multiple +fields (for example a 32-bit access to the location of the MSI Message +Data field with the high 16 bits not being covered by any known field). +Remove it and derive which fields not to write to from the accessed +fields' emulation masks: When they're all ones, there's no point in +doing any host write. + +This fixes a secondary issue at once: We obviously shouldn't make any +host write attempt when already the host read failed. + +This is XSA-128. + +Signed-off-by: Jan Beulich +Reviewed-by: Stefano Stabellini +--- + hw/xen/xen_pt.c | 25 +++++++++++++++++++++---- + hw/xen/xen_pt.h | 2 -- + hw/xen/xen_pt_config_init.c | 4 ---- + 3 files changed, 21 insertions(+), 10 deletions(-) + +Index: qemu-2.2+dfsg/hw/xen/xen_pt.c +=================================================================== +--- qemu-2.2+dfsg.orig/hw/xen/xen_pt.c 2015-06-09 07:39:00.848182115 -0400 ++++ qemu-2.2+dfsg/hw/xen/xen_pt.c 2015-06-09 07:39:00.844182073 -0400 +@@ -234,7 +234,7 @@ + int index = 0; + XenPTRegGroup *reg_grp_entry = NULL; + int rc = 0; +- uint32_t read_val = 0; ++ uint32_t read_val = 0, wb_mask; + int emul_len = 0; + XenPTReg *reg_entry = NULL; + uint32_t find_addr = addr; +@@ -271,6 +271,9 @@ + if (rc < 0) { + XEN_PT_ERR(d, "pci_read_block failed. return value: %d.\n", rc); + memset(&read_val, 0xff, len); ++ wb_mask = 0; ++ } else { ++ wb_mask = 0xFFFFFFFF >> ((4 - len) << 3); + } + + /* pass directly to the real device for passthrough type register group */ +@@ -298,6 +301,11 @@ + + valid_mask <<= (find_addr - real_offset) << 3; + ptr_val = (uint8_t *)&val + (real_offset & 3); ++ if (reg->emu_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) { ++ wb_mask &= ~((reg->emu_mask ++ >> ((find_addr - real_offset) << 3)) ++ << ((len - emul_len) << 3)); ++ } + + /* do emulation based on register size */ + switch (reg->size) { +@@ -350,10 +358,19 @@ + memory_region_transaction_commit(); + + out: +- if (!(reg && reg->no_wb)) { ++ for (index = 0; wb_mask; index += len) { + /* unknown regs are passed through */ +- rc = xen_host_pci_set_block(&s->real_device, addr, +- (uint8_t *)&val, len); ++ while (!(wb_mask & 0xff)) { ++ index++; ++ wb_mask >>= 8; ++ } ++ len = 0; ++ do { ++ len++; ++ wb_mask >>= 8; ++ } while (wb_mask & 0xff); ++ rc = xen_host_pci_set_block(&s->real_device, addr + index, ++ (uint8_t *)&val + index, len); + + if (rc < 0) { + XEN_PT_ERR(d, "pci_write_block failed. return value: %d.\n", rc); +Index: qemu-2.2+dfsg/hw/xen/xen_pt.h +=================================================================== +--- qemu-2.2+dfsg.orig/hw/xen/xen_pt.h 2015-06-09 07:39:00.848182115 -0400 ++++ qemu-2.2+dfsg/hw/xen/xen_pt.h 2015-06-09 07:39:00.844182073 -0400 +@@ -105,8 +105,6 @@ + uint32_t ro_mask; + /* reg emulate field mask (ON:emu, OFF:passthrough) */ + uint32_t emu_mask; +- /* no write back allowed */ +- uint32_t no_wb; + xen_pt_conf_reg_init init; + /* read/write function pointer + * for double_word/word/byte size */ +Index: qemu-2.2+dfsg/hw/xen/xen_pt_config_init.c +=================================================================== +--- qemu-2.2+dfsg.orig/hw/xen/xen_pt_config_init.c 2015-06-09 07:39:00.848182115 -0400 ++++ qemu-2.2+dfsg/hw/xen/xen_pt_config_init.c 2015-06-09 07:39:00.844182073 -0400 +@@ -1281,7 +1281,6 @@ + .init_val = 0x00000000, + .ro_mask = 0x00000003, + .emu_mask = 0xFFFFFFFF, +- .no_wb = 1, + .init = xen_pt_common_reg_init, + .u.dw.read = xen_pt_long_reg_read, + .u.dw.write = xen_pt_msgaddr32_reg_write, +@@ -1293,7 +1292,6 @@ + .init_val = 0x00000000, + .ro_mask = 0x00000000, + .emu_mask = 0xFFFFFFFF, +- .no_wb = 1, + .init = xen_pt_msgaddr64_reg_init, + .u.dw.read = xen_pt_long_reg_read, + .u.dw.write = xen_pt_msgaddr64_reg_write, +@@ -1305,7 +1303,6 @@ + .init_val = 0x0000, + .ro_mask = 0x0000, + .emu_mask = 0xFFFF, +- .no_wb = 1, + .init = xen_pt_msgdata_reg_init, + .u.w.read = xen_pt_word_reg_read, + .u.w.write = xen_pt_msgdata_reg_write, +@@ -1317,7 +1314,6 @@ + .init_val = 0x0000, + .ro_mask = 0x0000, + .emu_mask = 0xFFFF, +- .no_wb = 1, + .init = xen_pt_msgdata_reg_init, + .u.w.read = xen_pt_word_reg_read, + .u.w.write = xen_pt_msgdata_reg_write, diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4104.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-4104.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4104.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-4104.patch 2015-06-09 13:37:38.000000000 +0000 @@ -0,0 +1,186 @@ +From 7611dae8a69f0f1775ba1a9a942961c2aa10d88e Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Tue, 2 Jun 2015 15:07:00 +0000 +Subject: [PATCH] xen: don't allow guest to control MSI mask register + +It's being used by the hypervisor. For now simply mimic a device not +capable of masking, and fully emulate any accesses a guest may issue +nevertheless as simple reads/writes without side effects. + +This is XSA-129. + +Signed-off-by: Jan Beulich +Reviewed-by: Stefano Stabellini +--- + hw/pci/msi.c | 4 -- + hw/xen/xen_pt_config_init.c | 98 ++++++++++++++++++++++++++++++++++++++---- + include/hw/pci/pci_regs.h | 2 + + 3 files changed, 90 insertions(+), 14 deletions(-) + +Index: qemu-2.2+dfsg/hw/pci/msi.c +=================================================================== +--- qemu-2.2+dfsg.orig/hw/pci/msi.c 2015-06-09 07:39:09.980277689 -0400 ++++ qemu-2.2+dfsg/hw/pci/msi.c 2015-06-09 07:39:09.976277646 -0400 +@@ -21,10 +21,6 @@ + #include "hw/pci/msi.h" + #include "qemu/range.h" + +-/* Eventually those constants should go to Linux pci_regs.h */ +-#define PCI_MSI_PENDING_32 0x10 +-#define PCI_MSI_PENDING_64 0x14 +- + /* PCI_MSI_ADDRESS_LO */ + #define PCI_MSI_ADDRESS_LO_MASK (~0x3) + +Index: qemu-2.2+dfsg/hw/xen/xen_pt_config_init.c +=================================================================== +--- qemu-2.2+dfsg.orig/hw/xen/xen_pt_config_init.c 2015-06-09 07:39:09.980277689 -0400 ++++ qemu-2.2+dfsg/hw/xen/xen_pt_config_init.c 2015-06-09 07:39:09.976277646 -0400 +@@ -1018,13 +1018,9 @@ + */ + + /* Helper */ +-static bool xen_pt_msgdata_check_type(uint32_t offset, uint16_t flags) +-{ +- /* check the offset whether matches the type or not */ +- bool is_32 = (offset == PCI_MSI_DATA_32) && !(flags & PCI_MSI_FLAGS_64BIT); +- bool is_64 = (offset == PCI_MSI_DATA_64) && (flags & PCI_MSI_FLAGS_64BIT); +- return is_32 || is_64; +-} ++#define xen_pt_msi_check_type(offset, flags, what) \ ++ ((offset) == ((flags) & PCI_MSI_FLAGS_64BIT ? \ ++ PCI_MSI_##what##_64 : PCI_MSI_##what##_32)) + + /* Message Control register */ + static int xen_pt_msgctrl_reg_init(XenPCIPassthroughState *s, +@@ -1136,7 +1132,45 @@ + uint32_t offset = reg->offset; + + /* check the offset whether matches the type or not */ +- if (xen_pt_msgdata_check_type(offset, flags)) { ++ if (xen_pt_msi_check_type(offset, flags, DATA)) { ++ *data = reg->init_val; ++ } else { ++ *data = XEN_PT_INVALID_REG; ++ } ++ return 0; ++} ++ ++/* this function will be called twice (for 32 bit and 64 bit type) */ ++/* initialize Mask register */ ++static int xen_pt_mask_reg_init(XenPCIPassthroughState *s, ++ XenPTRegInfo *reg, uint32_t real_offset, ++ uint32_t *data) ++{ ++ uint32_t flags = s->msi->flags; ++ ++ /* check the offset whether matches the type or not */ ++ if (!(flags & PCI_MSI_FLAGS_MASKBIT)) { ++ *data = XEN_PT_INVALID_REG; ++ } else if (xen_pt_msi_check_type(reg->offset, flags, MASK)) { ++ *data = reg->init_val; ++ } else { ++ *data = XEN_PT_INVALID_REG; ++ } ++ return 0; ++} ++ ++/* this function will be called twice (for 32 bit and 64 bit type) */ ++/* initialize Pending register */ ++static int xen_pt_pending_reg_init(XenPCIPassthroughState *s, ++ XenPTRegInfo *reg, uint32_t real_offset, ++ uint32_t *data) ++{ ++ uint32_t flags = s->msi->flags; ++ ++ /* check the offset whether matches the type or not */ ++ if (!(flags & PCI_MSI_FLAGS_MASKBIT)) { ++ *data = XEN_PT_INVALID_REG; ++ } else if (xen_pt_msi_check_type(reg->offset, flags, PENDING)) { + *data = reg->init_val; + } else { + *data = XEN_PT_INVALID_REG; +@@ -1224,7 +1258,7 @@ + uint32_t offset = reg->offset; + + /* check the offset whether matches the type or not */ +- if (!xen_pt_msgdata_check_type(offset, msi->flags)) { ++ if (!xen_pt_msi_check_type(offset, msi->flags, DATA)) { + /* exit I/O emulator */ + XEN_PT_ERR(&s->dev, "the offset does not match the 32/64 bit type!\n"); + return -1; +@@ -1269,7 +1303,7 @@ + .size = 2, + .init_val = 0x0000, + .ro_mask = 0xFF8E, +- .emu_mask = 0x007F, ++ .emu_mask = 0x017F, + .init = xen_pt_msgctrl_reg_init, + .u.w.read = xen_pt_word_reg_read, + .u.w.write = xen_pt_msgctrl_reg_write, +@@ -1318,6 +1352,50 @@ + .u.w.read = xen_pt_word_reg_read, + .u.w.write = xen_pt_msgdata_reg_write, + }, ++ /* Mask reg (if PCI_MSI_FLAGS_MASKBIT set, for 32-bit devices) */ ++ { ++ .offset = PCI_MSI_MASK_32, ++ .size = 4, ++ .init_val = 0x00000000, ++ .ro_mask = 0xFFFFFFFF, ++ .emu_mask = 0xFFFFFFFF, ++ .init = xen_pt_mask_reg_init, ++ .u.dw.read = xen_pt_long_reg_read, ++ .u.dw.write = xen_pt_long_reg_write, ++ }, ++ /* Mask reg (if PCI_MSI_FLAGS_MASKBIT set, for 64-bit devices) */ ++ { ++ .offset = PCI_MSI_MASK_64, ++ .size = 4, ++ .init_val = 0x00000000, ++ .ro_mask = 0xFFFFFFFF, ++ .emu_mask = 0xFFFFFFFF, ++ .init = xen_pt_mask_reg_init, ++ .u.dw.read = xen_pt_long_reg_read, ++ .u.dw.write = xen_pt_long_reg_write, ++ }, ++ /* Pending reg (if PCI_MSI_FLAGS_MASKBIT set, for 32-bit devices) */ ++ { ++ .offset = PCI_MSI_MASK_32 + 4, ++ .size = 4, ++ .init_val = 0x00000000, ++ .ro_mask = 0xFFFFFFFF, ++ .emu_mask = 0x00000000, ++ .init = xen_pt_pending_reg_init, ++ .u.dw.read = xen_pt_long_reg_read, ++ .u.dw.write = xen_pt_long_reg_write, ++ }, ++ /* Pending reg (if PCI_MSI_FLAGS_MASKBIT set, for 64-bit devices) */ ++ { ++ .offset = PCI_MSI_MASK_64 + 4, ++ .size = 4, ++ .init_val = 0x00000000, ++ .ro_mask = 0xFFFFFFFF, ++ .emu_mask = 0x00000000, ++ .init = xen_pt_pending_reg_init, ++ .u.dw.read = xen_pt_long_reg_read, ++ .u.dw.write = xen_pt_long_reg_write, ++ }, + { + .size = 0, + }, +Index: qemu-2.2+dfsg/include/hw/pci/pci_regs.h +=================================================================== +--- qemu-2.2+dfsg.orig/include/hw/pci/pci_regs.h 2015-06-09 07:39:09.980277689 -0400 ++++ qemu-2.2+dfsg/include/hw/pci/pci_regs.h 2015-06-09 07:39:09.976277646 -0400 +@@ -298,8 +298,10 @@ + #define PCI_MSI_ADDRESS_HI 8 /* Upper 32 bits (if PCI_MSI_FLAGS_64BIT set) */ + #define PCI_MSI_DATA_32 8 /* 16 bits of data for 32-bit devices */ + #define PCI_MSI_MASK_32 12 /* Mask bits register for 32-bit devices */ ++#define PCI_MSI_PENDING_32 16 /* Pending bits register for 32-bit devices */ + #define PCI_MSI_DATA_64 12 /* 16 bits of data for 64-bit devices */ + #define PCI_MSI_MASK_64 16 /* Mask bits register for 64-bit devices */ ++#define PCI_MSI_PENDING_64 20 /* Pending bits register for 32-bit devices */ + + /* MSI-X registers */ + #define PCI_MSIX_FLAGS 2 diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4105.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-4105.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4105.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-4105.patch 2015-06-09 13:37:49.000000000 +0000 @@ -0,0 +1,82 @@ +From b38ec5ee7a581776bbce0bdaecb397632c3c4791 Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Tue, 2 Jun 2015 15:07:00 +0000 +Subject: [PATCH] xen/MSI-X: limit error messages + +Limit error messages resulting from bad guest behavior to avoid allowing +the guest to cause the control domain's disk to fill. + +The first message in pci_msix_write() can simply be deleted, as this +is indeed bad guest behavior, but such out of bounds writes don't +really need to be logged. + +The second one is more problematic, as there guest behavior may only +appear to be wrong: For one, the old logic didn't take the mask-all bit +into account. And then this shouldn't depend on host device state (i.e. +the host may have masked the entry without the guest having done so). +Plus these writes shouldn't be dropped even when an entry is unmasked. +Instead, if they can't be made take effect right away, they should take +effect on the next unmasking or enabling operation - the specification +explicitly describes such caching behavior. Until we can validly drop +the message (implementing such caching/latching behavior), issue the +message just once per MSI-X table entry. + +Note that the log message in pci_msix_read() similar to the one being +removed here is not an issue: "addr" being of unsigned type, and the +maximum size of the MSI-X table being 32k, entry_nr simply can't be +negative and hence the conditonal guarding issuing of the message will +never be true. + +This is XSA-130. + +Signed-off-by: Jan Beulich +Reviewed-by: Stefano Stabellini +--- + hw/xen/xen_pt.h | 1 + + hw/xen/xen_pt_msi.c | 12 +++++++----- + 2 files changed, 8 insertions(+), 5 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/xen/xen_pt.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/xen/xen_pt.h 2015-06-09 09:37:46.258649571 -0400 ++++ qemu-2.0.0+dfsg/hw/xen/xen_pt.h 2015-06-09 09:37:46.214649058 -0400 +@@ -175,6 +175,7 @@ + uint32_t data; + uint32_t vector_ctrl; + bool updated; /* indicate whether MSI ADDR or DATA is updated */ ++ bool warned; /* avoid issuing (bogus) warning more than once */ + } XenPTMSIXEntry; + typedef struct XenPTMSIX { + uint32_t ctrl_offset; +Index: qemu-2.0.0+dfsg/hw/xen/xen_pt_msi.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/xen/xen_pt_msi.c 2015-06-09 09:37:46.258649571 -0400 ++++ qemu-2.0.0+dfsg/hw/xen/xen_pt_msi.c 2015-06-09 09:37:46.214649058 -0400 +@@ -433,11 +433,10 @@ + XenPCIPassthroughState *s = opaque; + XenPTMSIX *msix = s->msix; + XenPTMSIXEntry *entry; +- int entry_nr, offset; ++ unsigned int entry_nr, offset; + + entry_nr = addr / PCI_MSIX_ENTRY_SIZE; +- if (entry_nr < 0 || entry_nr >= msix->total_entries) { +- XEN_PT_ERR(&s->dev, "asked MSI-X entry '%i' invalid!\n", entry_nr); ++ if (entry_nr >= msix->total_entries) { + return; + } + entry = &msix->msix_entry[entry_nr]; +@@ -458,8 +457,11 @@ + + PCI_MSIX_ENTRY_VECTOR_CTRL; + + if (msix->enabled && !(*vec_ctrl & PCI_MSIX_ENTRY_CTRL_MASKBIT)) { +- XEN_PT_ERR(&s->dev, "Can't update msix entry %d since MSI-X is" +- " already enabled.\n", entry_nr); ++ if (!entry->warned) { ++ entry->warned = true; ++ XEN_PT_ERR(&s->dev, "Can't update msix entry %d since MSI-X is" ++ " already enabled.\n", entry_nr); ++ } + return; + } + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4106-1.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-4106-1.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4106-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-4106-1.patch 2015-06-09 13:38:16.000000000 +0000 @@ -0,0 +1,68 @@ +From d1d35cf4ffb6a60a356193397919e83306d0bb74 Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Tue, 2 Jun 2015 15:07:01 +0000 +Subject: [PATCH] xen/MSI: don't open-code pass-through of enable bit modifications + +Without this the actual XSA-131 fix would cause the enable bit to not +get set anymore (due to the write back getting suppressed there based +on the OR of emu_mask, ro_mask, and res_mask). + +Note that the fiddling with the enable bit shouldn't really be done by +qemu, but making this work right (via libxc and the hypervisor) will +require more extensive changes, which can be postponed until after the +security issue got addressed. + +This is a preparatory patch for XSA-131. + +Signed-off-by: Jan Beulich +Acked-by: Stefano Stabellini +--- + hw/xen/xen_pt_config_init.c | 10 ++-------- + 1 files changed, 2 insertions(+), 8 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/xen/xen_pt_config_init.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/xen/xen_pt_config_init.c 2015-06-09 09:38:12.426954670 -0400 ++++ qemu-2.0.0+dfsg/hw/xen/xen_pt_config_init.c 2015-06-09 09:38:12.386954203 -0400 +@@ -1055,7 +1055,6 @@ + XenPTMSI *msi = s->msi; + uint16_t writable_mask = 0; + uint16_t throughable_mask = 0; +- uint16_t raw_val; + + /* Currently no support for multi-vector */ + if (*val & PCI_MSI_FLAGS_QSIZE) { +@@ -1068,12 +1067,11 @@ + msi->flags |= cfg_entry->data & ~PCI_MSI_FLAGS_ENABLE; + + /* create value for writing to I/O device register */ +- raw_val = *val; + throughable_mask = ~reg->emu_mask & valid_mask; + *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); + + /* update MSI */ +- if (raw_val & PCI_MSI_FLAGS_ENABLE) { ++ if (*val & PCI_MSI_FLAGS_ENABLE) { + /* setup MSI pirq for the first time */ + if (!msi->initialized) { + /* Init physical one */ +@@ -1101,10 +1099,6 @@ + msi->flags &= ~PCI_MSI_FLAGS_ENABLE; + } + +- /* pass through MSI_ENABLE bit */ +- *val &= ~PCI_MSI_FLAGS_ENABLE; +- *val |= raw_val & PCI_MSI_FLAGS_ENABLE; +- + return 0; + } + +@@ -1303,7 +1297,7 @@ + .size = 2, + .init_val = 0x0000, + .ro_mask = 0xFF8E, +- .emu_mask = 0x017F, ++ .emu_mask = 0x017E, + .init = xen_pt_msgctrl_reg_init, + .u.w.read = xen_pt_word_reg_read, + .u.w.write = xen_pt_msgctrl_reg_write, diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4106-2.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-4106-2.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4106-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-4106-2.patch 2015-06-09 13:39:19.000000000 +0000 @@ -0,0 +1,78 @@ +From d61bb2482dc0c7426f451f23ba7e2748ae2cc06d Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Tue, 2 Jun 2015 15:07:01 +0000 +Subject: [PATCH] xen/pt: consolidate PM capability emu_mask + +There's no point in xen_pt_pmcsr_reg_{read,write}() each ORing +PCI_PM_CTRL_STATE_MASK and PCI_PM_CTRL_NO_SOFT_RESET into a local +emu_mask variable - we can have the same effect by setting the field +descriptor's emu_mask member suitably right away. Note that +xen_pt_pmcsr_reg_write() is being retained in order to allow later +patches to be less intrusive. + +This is a preparatory patch for XSA-131. + +Signed-off-by: Jan Beulich +Acked-by: Stefano Stabellini +Acked-by: Ian Campbell +--- + hw/xen/xen_pt_config_init.c | 25 ++++--------------------- + 1 files changed, 4 insertions(+), 21 deletions(-) + +Index: qemu-2.2+dfsg/hw/xen/xen_pt_config_init.c +=================================================================== +--- qemu-2.2+dfsg.orig/hw/xen/xen_pt_config_init.c 2015-06-09 07:39:31.276500556 -0400 ++++ qemu-2.2+dfsg/hw/xen/xen_pt_config_init.c 2015-06-09 07:39:31.272500515 -0400 +@@ -935,38 +935,21 @@ + * Power Management Capability + */ + +-/* read Power Management Control/Status register */ +-static int xen_pt_pmcsr_reg_read(XenPCIPassthroughState *s, XenPTReg *cfg_entry, +- uint16_t *value, uint16_t valid_mask) +-{ +- XenPTRegInfo *reg = cfg_entry->reg; +- uint16_t valid_emu_mask = reg->emu_mask; +- +- valid_emu_mask |= PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET; +- +- valid_emu_mask = valid_emu_mask & valid_mask; +- *value = XEN_PT_MERGE_VALUE(*value, cfg_entry->data, ~valid_emu_mask); +- +- return 0; +-} + /* write Power Management Control/Status register */ + static int xen_pt_pmcsr_reg_write(XenPCIPassthroughState *s, + XenPTReg *cfg_entry, uint16_t *val, + uint16_t dev_value, uint16_t valid_mask) + { + XenPTRegInfo *reg = cfg_entry->reg; +- uint16_t emu_mask = reg->emu_mask; + uint16_t writable_mask = 0; + uint16_t throughable_mask = 0; + +- emu_mask |= PCI_PM_CTRL_STATE_MASK | PCI_PM_CTRL_NO_SOFT_RESET; +- + /* modify emulate register */ +- writable_mask = emu_mask & ~reg->ro_mask & valid_mask; ++ writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; + cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); + + /* create value for writing to I/O device register */ +- throughable_mask = ~emu_mask & valid_mask; ++ throughable_mask = ~reg->emu_mask & valid_mask; + *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); + + return 0; +@@ -1002,9 +985,9 @@ + .size = 2, + .init_val = 0x0008, + .ro_mask = 0xE1FC, +- .emu_mask = 0x8100, ++ .emu_mask = 0x810B, + .init = xen_pt_common_reg_init, +- .u.w.read = xen_pt_pmcsr_reg_read, ++ .u.w.read = xen_pt_word_reg_read, + .u.w.write = xen_pt_pmcsr_reg_write, + }, + { diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4106-3.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-4106-3.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4106-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-4106-3.patch 2015-06-09 13:39:25.000000000 +0000 @@ -0,0 +1,30 @@ +From c4ff1e68c621928abc680266cad0a451686c403b Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Tue, 2 Jun 2015 15:07:01 +0000 +Subject: [PATCH] xen/pt: correctly handle PM status bit + +xen_pt_pmcsr_reg_write() needs an adjustment to deal with the RW1C +nature of the not passed through bit 15 (PCI_PM_CTRL_PME_STATUS). + +This is a preparatory patch for XSA-131. + +Signed-off-by: Jan Beulich +Reviewed-by: Stefano Stabellini +--- + hw/xen/xen_pt_config_init.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +Index: qemu-2.2+dfsg/hw/xen/xen_pt_config_init.c +=================================================================== +--- qemu-2.2+dfsg.orig/hw/xen/xen_pt_config_init.c 2015-06-09 07:39:37.520565899 -0400 ++++ qemu-2.2+dfsg/hw/xen/xen_pt_config_init.c 2015-06-09 07:39:37.520565899 -0400 +@@ -950,7 +950,8 @@ + + /* create value for writing to I/O device register */ + throughable_mask = ~reg->emu_mask & valid_mask; +- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); ++ *val = XEN_PT_MERGE_VALUE(*val, dev_value & ~PCI_PM_CTRL_PME_STATUS, ++ throughable_mask); + + return 0; + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4106-4.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-4106-4.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4106-4.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-4106-4.patch 2015-06-09 13:39:32.000000000 +0000 @@ -0,0 +1,256 @@ +From 0e7ef22136955169a0fd03c4e41af95662352733 Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Tue, 2 Jun 2015 15:07:01 +0000 +Subject: [PATCH] xen/pt: split out calculation of throughable mask in PCI config space handling + +This is just to avoid having to adjust that calculation later in +multiple places. + +Note that including ->ro_mask in get_throughable_mask()'s calculation +is only an apparent (i.e. benign) behavioral change: For r/o fields it +doesn't matter > whether they get passed through - either the same flag +is also set in emu_mask (then there's no change at all) or the field is +r/o in hardware (and hence a write won't change it anyway). + +This is a preparatory patch for XSA-131. + +Signed-off-by: Jan Beulich +Acked-by: Stefano Stabellini +Reviewed-by: Anthony PERARD +--- + hw/xen/xen_pt_config_init.c | 51 ++++++++++++++++-------------------------- + 1 files changed, 20 insertions(+), 31 deletions(-) + +Index: qemu-2.2+dfsg/hw/xen/xen_pt_config_init.c +=================================================================== +--- qemu-2.2+dfsg.orig/hw/xen/xen_pt_config_init.c 2015-06-09 07:39:44.220636012 -0400 ++++ qemu-2.2+dfsg/hw/xen/xen_pt_config_init.c 2015-06-09 07:39:44.216635969 -0400 +@@ -95,6 +95,14 @@ + return NULL; + } + ++static uint32_t get_throughable_mask(const XenPCIPassthroughState *s, ++ const XenPTRegInfo *reg, ++ uint32_t valid_mask) ++{ ++ uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask); ++ ++ return throughable_mask & valid_mask; ++} + + /**************** + * general register functions +@@ -157,14 +165,13 @@ + { + XenPTRegInfo *reg = cfg_entry->reg; + uint8_t writable_mask = 0; +- uint8_t throughable_mask = 0; ++ uint8_t throughable_mask = get_throughable_mask(s, reg, valid_mask); + + /* modify emulate register */ + writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; + cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); + + /* create value for writing to I/O device register */ +- throughable_mask = ~reg->emu_mask & valid_mask; + *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); + + return 0; +@@ -175,14 +182,13 @@ + { + XenPTRegInfo *reg = cfg_entry->reg; + uint16_t writable_mask = 0; +- uint16_t throughable_mask = 0; ++ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); + + /* modify emulate register */ + writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; + cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); + + /* create value for writing to I/O device register */ +- throughable_mask = ~reg->emu_mask & valid_mask; + *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); + + return 0; +@@ -193,14 +199,13 @@ + { + XenPTRegInfo *reg = cfg_entry->reg; + uint32_t writable_mask = 0; +- uint32_t throughable_mask = 0; ++ uint32_t throughable_mask = get_throughable_mask(s, reg, valid_mask); + + /* modify emulate register */ + writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; + cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); + + /* create value for writing to I/O device register */ +- throughable_mask = ~reg->emu_mask & valid_mask; + *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); + + return 0; +@@ -292,15 +297,13 @@ + { + XenPTRegInfo *reg = cfg_entry->reg; + uint16_t writable_mask = 0; +- uint16_t throughable_mask = 0; ++ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); + + /* modify emulate register */ + writable_mask = ~reg->ro_mask & valid_mask; + cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); + + /* create value for writing to I/O device register */ +- throughable_mask = ~reg->emu_mask & valid_mask; +- + if (*val & PCI_COMMAND_INTX_DISABLE) { + throughable_mask |= PCI_COMMAND_INTX_DISABLE; + } else { +@@ -456,7 +459,6 @@ + PCIDevice *d = &s->dev; + const PCIIORegion *r; + uint32_t writable_mask = 0; +- uint32_t throughable_mask = 0; + uint32_t bar_emu_mask = 0; + uint32_t bar_ro_mask = 0; + uint32_t r_size = 0; +@@ -513,8 +515,7 @@ + } + + /* create value for writing to I/O device register */ +- throughable_mask = ~bar_emu_mask & valid_mask; +- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); ++ *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0); + + return 0; + } +@@ -528,9 +529,8 @@ + XenPTRegion *base = NULL; + PCIDevice *d = (PCIDevice *)&s->dev; + uint32_t writable_mask = 0; +- uint32_t throughable_mask = 0; ++ uint32_t throughable_mask = get_throughable_mask(s, reg, valid_mask); + pcibus_t r_size = 0; +- uint32_t bar_emu_mask = 0; + uint32_t bar_ro_mask = 0; + + r_size = d->io_regions[PCI_ROM_SLOT].size; +@@ -539,7 +539,6 @@ + r_size = xen_pt_get_emul_size(base->bar_flag, r_size); + + /* set emulate mask and read-only mask */ +- bar_emu_mask = reg->emu_mask; + bar_ro_mask = (reg->ro_mask | (r_size - 1)) & ~PCI_ROM_ADDRESS_ENABLE; + + /* modify emulate register */ +@@ -547,7 +546,6 @@ + cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); + + /* create value for writing to I/O device register */ +- throughable_mask = ~bar_emu_mask & valid_mask; + *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); + + return 0; +@@ -942,14 +940,13 @@ + { + XenPTRegInfo *reg = cfg_entry->reg; + uint16_t writable_mask = 0; +- uint16_t throughable_mask = 0; ++ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); + + /* modify emulate register */ + writable_mask = reg->emu_mask & ~reg->ro_mask & valid_mask; + cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); + + /* create value for writing to I/O device register */ +- throughable_mask = ~reg->emu_mask & valid_mask; + *val = XEN_PT_MERGE_VALUE(*val, dev_value & ~PCI_PM_CTRL_PME_STATUS, + throughable_mask); + +@@ -1038,7 +1035,7 @@ + XenPTRegInfo *reg = cfg_entry->reg; + XenPTMSI *msi = s->msi; + uint16_t writable_mask = 0; +- uint16_t throughable_mask = 0; ++ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); + + /* Currently no support for multi-vector */ + if (*val & PCI_MSI_FLAGS_QSIZE) { +@@ -1051,7 +1048,6 @@ + msi->flags |= cfg_entry->data & ~PCI_MSI_FLAGS_ENABLE; + + /* create value for writing to I/O device register */ +- throughable_mask = ~reg->emu_mask & valid_mask; + *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); + + /* update MSI */ +@@ -1163,7 +1159,6 @@ + { + XenPTRegInfo *reg = cfg_entry->reg; + uint32_t writable_mask = 0; +- uint32_t throughable_mask = 0; + uint32_t old_addr = cfg_entry->data; + + /* modify emulate register */ +@@ -1172,8 +1167,7 @@ + s->msi->addr_lo = cfg_entry->data; + + /* create value for writing to I/O device register */ +- throughable_mask = ~reg->emu_mask & valid_mask; +- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); ++ *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0); + + /* update MSI */ + if (cfg_entry->data != old_addr) { +@@ -1191,7 +1185,6 @@ + { + XenPTRegInfo *reg = cfg_entry->reg; + uint32_t writable_mask = 0; +- uint32_t throughable_mask = 0; + uint32_t old_addr = cfg_entry->data; + + /* check whether the type is 64 bit or not */ +@@ -1208,8 +1201,7 @@ + s->msi->addr_hi = cfg_entry->data; + + /* create value for writing to I/O device register */ +- throughable_mask = ~reg->emu_mask & valid_mask; +- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); ++ *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0); + + /* update MSI */ + if (cfg_entry->data != old_addr) { +@@ -1231,7 +1223,6 @@ + XenPTRegInfo *reg = cfg_entry->reg; + XenPTMSI *msi = s->msi; + uint16_t writable_mask = 0; +- uint16_t throughable_mask = 0; + uint16_t old_data = cfg_entry->data; + uint32_t offset = reg->offset; + +@@ -1249,8 +1240,7 @@ + msi->data = cfg_entry->data; + + /* create value for writing to I/O device register */ +- throughable_mask = ~reg->emu_mask & valid_mask; +- *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); ++ *val = XEN_PT_MERGE_VALUE(*val, dev_value, 0); + + /* update MSI */ + if (cfg_entry->data != old_data) { +@@ -1412,7 +1402,7 @@ + { + XenPTRegInfo *reg = cfg_entry->reg; + uint16_t writable_mask = 0; +- uint16_t throughable_mask = 0; ++ uint16_t throughable_mask = get_throughable_mask(s, reg, valid_mask); + int debug_msix_enabled_old; + + /* modify emulate register */ +@@ -1420,7 +1410,6 @@ + cfg_entry->data = XEN_PT_MERGE_VALUE(*val, cfg_entry->data, writable_mask); + + /* create value for writing to I/O device register */ +- throughable_mask = ~reg->emu_mask & valid_mask; + *val = XEN_PT_MERGE_VALUE(*val, dev_value, throughable_mask); + + /* update MSI-X */ diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4106-5.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-4106-5.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4106-5.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-4106-5.patch 2015-06-09 13:39:37.000000000 +0000 @@ -0,0 +1,30 @@ +From 45ebe3916ab16f859ed930e92fbd52d84d5dcdaf Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Tue, 2 Jun 2015 15:07:01 +0000 +Subject: [PATCH] xen/pt: mark all PCIe capability bits read-only + +xen_pt_emu_reg_pcie[]'s PCI_EXP_DEVCAP needs to cover all bits as read- +only to avoid unintended write-back (just a precaution, the field ought +to be read-only in hardware). + +This is a preparatory patch for XSA-131. + +Signed-off-by: Jan Beulich +Reviewed-by: Stefano Stabellini +--- + hw/xen/xen_pt_config_init.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +Index: qemu-2.2+dfsg/hw/xen/xen_pt_config_init.c +=================================================================== +--- qemu-2.2+dfsg.orig/hw/xen/xen_pt_config_init.c 2015-06-09 07:39:52.832726130 -0400 ++++ qemu-2.2+dfsg/hw/xen/xen_pt_config_init.c 2015-06-09 07:39:52.828726088 -0400 +@@ -873,7 +873,7 @@ + .offset = PCI_EXP_DEVCAP, + .size = 4, + .init_val = 0x00000000, +- .ro_mask = 0x1FFCFFFF, ++ .ro_mask = 0xFFFFFFFF, + .emu_mask = 0x10000000, + .init = xen_pt_common_reg_init, + .u.dw.read = xen_pt_long_reg_read, diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4106-6.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-4106-6.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4106-6.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-4106-6.patch 2015-06-09 13:39:49.000000000 +0000 @@ -0,0 +1,86 @@ +From 0ad3393ad032f76e88b4dbd04d36ad84dff75dd6 Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Tue, 2 Jun 2015 15:07:01 +0000 +Subject: [PATCH] xen/pt: mark reserved bits in PCI config space fields + +The adjustments are solely to make the subsequent patches work right +(and hence make the patch set consistent), namely if permissive mode +(introduced by the last patch) gets used (as both reserved registers +and reserved fields must be similarly protected from guest access in +default mode, but the guest should be allowed access to them in +permissive mode). + +This is a preparatory patch for XSA-131. + +Signed-off-by: Jan Beulich +--- + hw/xen/xen_pt.h | 2 ++ + hw/xen/xen_pt_config_init.c | 14 +++++++++----- + 2 files changed, 11 insertions(+), 5 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/xen/xen_pt.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/xen/xen_pt.h 2015-06-09 09:39:44.964032643 -0400 ++++ qemu-2.0.0+dfsg/hw/xen/xen_pt.h 2015-06-09 09:39:44.924032178 -0400 +@@ -101,6 +101,8 @@ + uint32_t offset; + uint32_t size; + uint32_t init_val; ++ /* reg reserved field mask (ON:reserved, OFF:defined) */ ++ uint32_t res_mask; + /* reg read only field mask (ON:RO/ROS, OFF:other) */ + uint32_t ro_mask; + /* reg emulate field mask (ON:emu, OFF:passthrough) */ +Index: qemu-2.0.0+dfsg/hw/xen/xen_pt_config_init.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/xen/xen_pt_config_init.c 2015-06-09 09:39:44.964032643 -0400 ++++ qemu-2.0.0+dfsg/hw/xen/xen_pt_config_init.c 2015-06-09 09:39:44.928032225 -0400 +@@ -580,7 +580,7 @@ + .offset = PCI_COMMAND, + .size = 2, + .init_val = 0x0000, +- .ro_mask = 0xF880, ++ .res_mask = 0xF880, + .emu_mask = 0x0743, + .init = xen_pt_common_reg_init, + .u.w.read = xen_pt_word_reg_read, +@@ -605,7 +605,8 @@ + .offset = PCI_STATUS, + .size = 2, + .init_val = 0x0000, +- .ro_mask = 0x06FF, ++ .res_mask = 0x0007, ++ .ro_mask = 0x06F8, + .emu_mask = 0x0010, + .init = xen_pt_status_reg_init, + .u.w.read = xen_pt_word_reg_read, +@@ -982,7 +983,8 @@ + .offset = PCI_PM_CTRL, + .size = 2, + .init_val = 0x0008, +- .ro_mask = 0xE1FC, ++ .res_mask = 0x00F0, ++ .ro_mask = 0xE10C, + .emu_mask = 0x810B, + .init = xen_pt_common_reg_init, + .u.w.read = xen_pt_word_reg_read, +@@ -1270,7 +1272,8 @@ + .offset = PCI_MSI_FLAGS, + .size = 2, + .init_val = 0x0000, +- .ro_mask = 0xFF8E, ++ .res_mask = 0xFE00, ++ .ro_mask = 0x018E, + .emu_mask = 0x017E, + .init = xen_pt_msgctrl_reg_init, + .u.w.read = xen_pt_word_reg_read, +@@ -1446,7 +1449,8 @@ + .offset = PCI_MSI_FLAGS, + .size = 2, + .init_val = 0x0000, +- .ro_mask = 0x3FFF, ++ .res_mask = 0x3800, ++ .ro_mask = 0x07FF, + .emu_mask = 0x0000, + .init = xen_pt_msixctrl_reg_init, + .u.w.read = xen_pt_word_reg_read, diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4106-7.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-4106-7.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4106-7.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-4106-7.patch 2015-06-09 13:39:53.000000000 +0000 @@ -0,0 +1,69 @@ +From a88a3f887181605f4487a22bdfb7d87ffafde5d9 Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Tue, 2 Jun 2015 15:07:01 +0000 +Subject: [PATCH] xen/pt: add a few PCI config space field descriptions + +Since the next patch will turn all not explicitly described fields +read-only by default, those fields that have guest writable bits need +to be given explicit descriptors. + +This is a preparatory patch for XSA-131. + +Signed-off-by: Jan Beulich +--- + hw/xen/xen_pt_config_init.c | 28 ++++++++++++++++++++++++++++ + 1 files changed, 28 insertions(+), 0 deletions(-) + +Index: qemu-2.2+dfsg/hw/xen/xen_pt_config_init.c +=================================================================== +--- qemu-2.2+dfsg.orig/hw/xen/xen_pt_config_init.c 2015-06-09 07:40:04.992853372 -0400 ++++ qemu-2.2+dfsg/hw/xen/xen_pt_config_init.c 2015-06-09 07:40:04.992853372 -0400 +@@ -756,6 +756,15 @@ + .u.b.write = xen_pt_byte_reg_write, + }, + { ++ .offset = PCI_VPD_ADDR, ++ .size = 2, ++ .ro_mask = 0x0003, ++ .emu_mask = 0x0003, ++ .init = xen_pt_common_reg_init, ++ .u.w.read = xen_pt_word_reg_read, ++ .u.w.write = xen_pt_word_reg_write, ++ }, ++ { + .size = 0, + }, + }; +@@ -891,6 +900,16 @@ + .u.w.read = xen_pt_word_reg_read, + .u.w.write = xen_pt_word_reg_write, + }, ++ /* Device Status reg */ ++ { ++ .offset = PCI_EXP_DEVSTA, ++ .size = 2, ++ .res_mask = 0xFFC0, ++ .ro_mask = 0x0030, ++ .init = xen_pt_common_reg_init, ++ .u.w.read = xen_pt_word_reg_read, ++ .u.w.write = xen_pt_word_reg_write, ++ }, + /* Link Control reg */ + { + .offset = PCI_EXP_LNKCTL, +@@ -902,6 +921,15 @@ + .u.w.read = xen_pt_word_reg_read, + .u.w.write = xen_pt_word_reg_write, + }, ++ /* Link Status reg */ ++ { ++ .offset = PCI_EXP_LNKSTA, ++ .size = 2, ++ .ro_mask = 0x3FFF, ++ .init = xen_pt_common_reg_init, ++ .u.w.read = xen_pt_word_reg_read, ++ .u.w.write = xen_pt_word_reg_write, ++ }, + /* Device Control 2 reg */ + { + .offset = 0x28, diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4106-8.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-4106-8.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-4106-8.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-4106-8.patch 2015-06-09 13:39:58.000000000 +0000 @@ -0,0 +1,129 @@ +From c25bbf1545a53ac051f9e51d4140e397660c10ae Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Tue, 2 Jun 2015 15:07:01 +0000 +Subject: [PATCH] xen/pt: unknown PCI config space fields should be read-only + +... by default. Add a per-device "permissive" mode similar to pciback's +to allow restoring previous behavior (and hence break security again, +i.e. should be used only for trusted guests). + +This is part of XSA-131. + +Signed-off-by: Jan Beulich +Acked-by: Stefano Stabellini +Reviewed-by: Anthony PERARD ) +--- + hw/xen/xen_pt.c | 32 +++++++++++++++++++++++++++++--- + hw/xen/xen_pt.h | 2 ++ + hw/xen/xen_pt_config_init.c | 4 ++++ + 3 files changed, 35 insertions(+), 3 deletions(-) + +Index: qemu-2.1+dfsg/hw/xen/xen_pt.c +=================================================================== +--- qemu-2.1+dfsg.orig/hw/xen/xen_pt.c 2015-06-09 08:16:56.464361355 -0400 ++++ qemu-2.1+dfsg/hw/xen/xen_pt.c 2015-06-09 08:16:56.424360904 -0400 +@@ -239,6 +239,7 @@ + XenPTReg *reg_entry = NULL; + uint32_t find_addr = addr; + XenPTRegInfo *reg = NULL; ++ bool wp_flag = false; + + if (xen_pt_pci_config_access_check(d, addr, len)) { + return; +@@ -278,6 +279,10 @@ + + /* pass directly to the real device for passthrough type register group */ + if (reg_grp_entry == NULL) { ++ if (!s->permissive) { ++ wb_mask = 0; ++ wp_flag = true; ++ } + goto out; + } + +@@ -298,12 +303,15 @@ + uint32_t real_offset = reg_grp_entry->base_offset + reg->offset; + uint32_t valid_mask = 0xFFFFFFFF >> ((4 - emul_len) << 3); + uint8_t *ptr_val = NULL; ++ uint32_t wp_mask = reg->emu_mask | reg->ro_mask; + + valid_mask <<= (find_addr - real_offset) << 3; + ptr_val = (uint8_t *)&val + (real_offset & 3); +- if (reg->emu_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) { +- wb_mask &= ~((reg->emu_mask +- >> ((find_addr - real_offset) << 3)) ++ if (!s->permissive) { ++ wp_mask |= reg->res_mask; ++ } ++ if (wp_mask == (0xFFFFFFFF >> ((4 - reg->size) << 3))) { ++ wb_mask &= ~((wp_mask >> ((find_addr - real_offset) << 3)) + << ((len - emul_len) << 3)); + } + +@@ -347,6 +355,16 @@ + } else { + /* nothing to do with passthrough type register, + * continue to find next byte */ ++ if (!s->permissive) { ++ wb_mask &= ~(0xff << ((len - emul_len) << 3)); ++ /* Unused BARs will make it here, but we don't want to issue ++ * warnings for writes to them (bogus writes get dealt with ++ * above). ++ */ ++ if (index < 0) { ++ wp_flag = true; ++ } ++ } + emul_len--; + find_addr++; + } +@@ -358,6 +376,13 @@ + memory_region_transaction_commit(); + + out: ++ if (wp_flag && !s->permissive_warned) { ++ s->permissive_warned = true; ++ xen_pt_log(d, "Write-back to unknown field 0x%02x (partially) inhibited (0x%0*x)\n", ++ addr, len * 2, wb_mask); ++ xen_pt_log(d, "If the device doesn't work, try enabling permissive mode\n"); ++ xen_pt_log(d, "(unsafe) and if it helps report the problem to xen-devel\n"); ++ } + for (index = 0; wb_mask; index += len) { + /* unknown regs are passed through */ + while (!(wb_mask & 0xff)) { +@@ -844,6 +869,7 @@ + + static Property xen_pci_passthrough_properties[] = { + DEFINE_PROP_PCI_HOST_DEVADDR("hostaddr", XenPCIPassthroughState, hostaddr), ++ DEFINE_PROP_BOOL("permissive", XenPCIPassthroughState, permissive, false), + DEFINE_PROP_END_OF_LIST(), + }; + +Index: qemu-2.1+dfsg/hw/xen/xen_pt.h +=================================================================== +--- qemu-2.1+dfsg.orig/hw/xen/xen_pt.h 2015-06-09 08:16:56.464361355 -0400 ++++ qemu-2.1+dfsg/hw/xen/xen_pt.h 2015-06-09 08:16:56.424360904 -0400 +@@ -197,6 +197,8 @@ + + PCIHostDeviceAddress hostaddr; + bool is_virtfn; ++ bool permissive; ++ bool permissive_warned; + XenHostPCIDevice real_device; + XenPTRegion bases[PCI_NUM_REGIONS]; /* Access regions */ + QLIST_HEAD(, XenPTRegGroup) reg_grps; +Index: qemu-2.1+dfsg/hw/xen/xen_pt_config_init.c +=================================================================== +--- qemu-2.1+dfsg.orig/hw/xen/xen_pt_config_init.c 2015-06-09 08:16:56.464361355 -0400 ++++ qemu-2.1+dfsg/hw/xen/xen_pt_config_init.c 2015-06-09 08:16:56.424360904 -0400 +@@ -101,6 +101,10 @@ + { + uint32_t throughable_mask = ~(reg->emu_mask | reg->ro_mask); + ++ if (!s->permissive) { ++ throughable_mask &= ~reg->res_mask; ++ } ++ + return throughable_mask & valid_mask; + } + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-5154.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-5154.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-5154.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-5154.patch 2015-07-27 18:23:06.000000000 +0000 @@ -0,0 +1,97 @@ +Description: fix heap overflow when processing ATAPI commands +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=d2ff85854512574e7209f295e87b0835d5b032c6 +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=03441c3a4a42beb25460dd11592539030337d0f8 +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=cb72cba83021fa42719e73a5249c12096a4d1cfc + +Index: qemu-2.0.0+dfsg/hw/ide/atapi.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/ide/atapi.c 2015-07-27 14:23:03.366669357 -0400 ++++ qemu-2.0.0+dfsg/hw/ide/atapi.c 2015-07-27 14:23:03.358669269 -0400 +@@ -879,6 +879,7 @@ + + if (pwrcnd) { + /* eject/load only happens for power condition == 0 */ ++ ide_atapi_cmd_ok(s); + return; + } + +Index: qemu-2.0.0+dfsg/hw/ide/core.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/ide/core.c 2015-07-27 14:23:03.366669357 -0400 ++++ qemu-2.0.0+dfsg/hw/ide/core.c 2015-07-27 14:23:03.366669357 -0400 +@@ -1901,11 +1901,17 @@ + } + + p = s->data_ptr; ++ if (p + 2 > s->data_end) { ++ return; ++ } ++ + *(uint16_t *)p = le16_to_cpu(val); + p += 2; + s->data_ptr = p; +- if (p >= s->data_end) ++ if (p >= s->data_end) { ++ s->status &= ~DRQ_STAT; + s->end_transfer_func(s); ++ } + } + + uint32_t ide_data_readw(void *opaque, uint32_t addr) +@@ -1922,11 +1928,17 @@ + } + + p = s->data_ptr; ++ if (p + 2 > s->data_end) { ++ return 0; ++ } ++ + ret = cpu_to_le16(*(uint16_t *)p); + p += 2; + s->data_ptr = p; +- if (p >= s->data_end) ++ if (p >= s->data_end) { ++ s->status &= ~DRQ_STAT; + s->end_transfer_func(s); ++ } + return ret; + } + +@@ -1943,11 +1955,17 @@ + } + + p = s->data_ptr; ++ if (p + 4 > s->data_end) { ++ return; ++ } ++ + *(uint32_t *)p = le32_to_cpu(val); + p += 4; + s->data_ptr = p; +- if (p >= s->data_end) ++ if (p >= s->data_end) { ++ s->status &= ~DRQ_STAT; + s->end_transfer_func(s); ++ } + } + + uint32_t ide_data_readl(void *opaque, uint32_t addr) +@@ -1964,11 +1982,17 @@ + } + + p = s->data_ptr; ++ if (p + 4 > s->data_end) { ++ return 0; ++ } ++ + ret = cpu_to_le32(*(uint32_t *)p); + p += 4; + s->data_ptr = p; +- if (p >= s->data_end) ++ if (p >= s->data_end) { ++ s->status &= ~DRQ_STAT; + s->end_transfer_func(s); ++ } + return ret; + } + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-5165.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-5165.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-5165.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-5165.patch 2015-08-25 14:02:56.000000000 +0000 @@ -0,0 +1,429 @@ +Description: fix process heap memory disclosure +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=39b8e7dcaf04cbdb926b478f825b160d852752b5 +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=d6812d60e7932de3cd0f602c0ee63dd3d09f1847 +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=e1c120a9c54872f8a538ff9129d928de4e865cbd +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=03247d43c577dfea8181cd40177ad5ba77c8db76 +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=c6296ea88df040054ccd781f3945fe103f8c7c17 +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=4240be45632db7831129f124bcf53c1223825b0f +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=8357946b15f0a31f73dd691b7da95f29318ed310 +Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=794610 + +Index: qemu-2.0.0+dfsg/hw/net/rtl8139.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/rtl8139.c 2015-08-25 10:02:53.232032873 -0400 ++++ qemu-2.0.0+dfsg/hw/net/rtl8139.c 2015-08-25 10:02:53.176032292 -0400 +@@ -2161,6 +2161,11 @@ + { + DPRINTF("+++ C+ mode offloaded task checksum\n"); + ++ /* Large enough for Ethernet and IP headers? */ ++ if (saved_size < ETH_HLEN + sizeof(ip_header)) { ++ goto skip_offload; ++ } ++ + /* ip packet header */ + ip_header *ip = NULL; + int hlen = 0; +@@ -2171,223 +2176,230 @@ + size_t eth_payload_len = 0; + + int proto = be16_to_cpu(*(uint16_t *)(saved_buffer + 12)); +- if (proto == ETH_P_IP) ++ if (proto != ETH_P_IP) + { +- DPRINTF("+++ C+ mode has IP packet\n"); ++ goto skip_offload; ++ } + +- /* not aligned */ +- eth_payload_data = saved_buffer + ETH_HLEN; +- eth_payload_len = saved_size - ETH_HLEN; +- +- ip = (ip_header*)eth_payload_data; +- +- if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) { +- DPRINTF("+++ C+ mode packet has bad IP version %d " +- "expected %d\n", IP_HEADER_VERSION(ip), +- IP_HEADER_VERSION_4); +- ip = NULL; +- } else { +- hlen = IP_HEADER_LENGTH(ip); +- ip_protocol = ip->ip_p; +- ip_data_len = be16_to_cpu(ip->ip_len) - hlen; +- } ++ DPRINTF("+++ C+ mode has IP packet\n"); ++ ++ /* not aligned */ ++ eth_payload_data = saved_buffer + ETH_HLEN; ++ eth_payload_len = saved_size - ETH_HLEN; ++ ++ ip = (ip_header*)eth_payload_data; ++ ++ if (IP_HEADER_VERSION(ip) != IP_HEADER_VERSION_4) { ++ DPRINTF("+++ C+ mode packet has bad IP version %d " ++ "expected %d\n", IP_HEADER_VERSION(ip), ++ IP_HEADER_VERSION_4); ++ goto skip_offload; ++ } ++ ++ hlen = IP_HEADER_LENGTH(ip); ++ if (hlen < sizeof(ip_header) || hlen > eth_payload_len) { ++ goto skip_offload; + } + +- if (ip) ++ ip_protocol = ip->ip_p; ++ ip_data_len = be16_to_cpu(ip->ip_len) - hlen; ++ ++ if (txdw0 & CP_TX_IPCS) + { +- if (txdw0 & CP_TX_IPCS) +- { +- DPRINTF("+++ C+ mode need IP checksum\n"); ++ DPRINTF("+++ C+ mode need IP checksum\n"); + +- if (hleneth_payload_len) {/* min header length */ +- /* bad packet header len */ +- /* or packet too short */ +- } +- else +- { +- ip->ip_sum = 0; +- ip->ip_sum = ip_checksum(ip, hlen); +- DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n", +- hlen, ip->ip_sum); +- } +- } ++ ip->ip_sum = 0; ++ ip->ip_sum = ip_checksum(ip, hlen); ++ DPRINTF("+++ C+ mode IP header len=%d checksum=%04x\n", ++ hlen, ip->ip_sum); ++ } + +- if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) +- { +- int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK; ++ if ((txdw0 & CP_TX_LGSEN) && ip_protocol == IP_PROTO_TCP) ++ { ++ /* Large enough for the TCP header? */ ++ if (ip_data_len < sizeof(tcp_header)) { ++ goto skip_offload; ++ } + +- DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d " +- "frame data %d specified MSS=%d\n", ETH_MTU, +- ip_data_len, saved_size - ETH_HLEN, large_send_mss); ++ int large_send_mss = (txdw0 >> 16) & CP_TC_LGSEN_MSS_MASK; + +- int tcp_send_offset = 0; +- int send_count = 0; ++ DPRINTF("+++ C+ mode offloaded task TSO MTU=%d IP data %d " ++ "frame data %d specified MSS=%d\n", ETH_MTU, ++ ip_data_len, saved_size - ETH_HLEN, large_send_mss); + +- /* maximum IP header length is 60 bytes */ +- uint8_t saved_ip_header[60]; ++ int tcp_send_offset = 0; ++ int send_count = 0; + +- /* save IP header template; data area is used in tcp checksum calculation */ +- memcpy(saved_ip_header, eth_payload_data, hlen); ++ /* maximum IP header length is 60 bytes */ ++ uint8_t saved_ip_header[60]; + +- /* a placeholder for checksum calculation routine in tcp case */ +- uint8_t *data_to_checksum = eth_payload_data + hlen - 12; +- // size_t data_to_checksum_len = eth_payload_len - hlen + 12; ++ /* save IP header template; data area is used in tcp checksum calculation */ ++ memcpy(saved_ip_header, eth_payload_data, hlen); + +- /* pointer to TCP header */ +- tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen); ++ /* a placeholder for checksum calculation routine in tcp case */ ++ uint8_t *data_to_checksum = eth_payload_data + hlen - 12; ++ // size_t data_to_checksum_len = eth_payload_len - hlen + 12; + +- int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); ++ /* pointer to TCP header */ ++ tcp_header *p_tcp_hdr = (tcp_header*)(eth_payload_data + hlen); + +- /* ETH_MTU = ip header len + tcp header len + payload */ +- int tcp_data_len = ip_data_len - tcp_hlen; +- int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen; ++ int tcp_hlen = TCP_HEADER_DATA_OFFSET(p_tcp_hdr); + +- DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP " +- "data len %d TCP chunk size %d\n", ip_data_len, +- tcp_hlen, tcp_data_len, tcp_chunk_size); ++ /* Invalid TCP data offset? */ ++ if (tcp_hlen < sizeof(tcp_header) || tcp_hlen > ip_data_len) { ++ goto skip_offload; ++ } + +- /* note the cycle below overwrites IP header data, +- but restores it from saved_ip_header before sending packet */ ++ /* ETH_MTU = ip header len + tcp header len + payload */ ++ int tcp_data_len = ip_data_len - tcp_hlen; ++ int tcp_chunk_size = ETH_MTU - hlen - tcp_hlen; + +- int is_last_frame = 0; ++ DPRINTF("+++ C+ mode TSO IP data len %d TCP hlen %d TCP " ++ "data len %d TCP chunk size %d\n", ip_data_len, ++ tcp_hlen, tcp_data_len, tcp_chunk_size); + +- for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size) +- { +- uint16_t chunk_size = tcp_chunk_size; ++ /* note the cycle below overwrites IP header data, ++ but restores it from saved_ip_header before sending packet */ + +- /* check if this is the last frame */ +- if (tcp_send_offset + tcp_chunk_size >= tcp_data_len) +- { +- is_last_frame = 1; +- chunk_size = tcp_data_len - tcp_send_offset; +- } +- +- DPRINTF("+++ C+ mode TSO TCP seqno %08x\n", +- be32_to_cpu(p_tcp_hdr->th_seq)); +- +- /* add 4 TCP pseudoheader fields */ +- /* copy IP source and destination fields */ +- memcpy(data_to_checksum, saved_ip_header + 12, 8); +- +- DPRINTF("+++ C+ mode TSO calculating TCP checksum for " +- "packet with %d bytes data\n", tcp_hlen + +- chunk_size); +- +- if (tcp_send_offset) +- { +- memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size); +- } +- +- /* keep PUSH and FIN flags only for the last frame */ +- if (!is_last_frame) +- { +- TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN); +- } +- +- /* recalculate TCP checksum */ +- ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; +- p_tcpip_hdr->zeros = 0; +- p_tcpip_hdr->ip_proto = IP_PROTO_TCP; +- p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size); +- +- p_tcp_hdr->th_sum = 0; +- +- int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12); +- DPRINTF("+++ C+ mode TSO TCP checksum %04x\n", +- tcp_checksum); +- +- p_tcp_hdr->th_sum = tcp_checksum; +- +- /* restore IP header */ +- memcpy(eth_payload_data, saved_ip_header, hlen); +- +- /* set IP data length and recalculate IP checksum */ +- ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size); +- +- /* increment IP id for subsequent frames */ +- ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id)); +- +- ip->ip_sum = 0; +- ip->ip_sum = ip_checksum(eth_payload_data, hlen); +- DPRINTF("+++ C+ mode TSO IP header len=%d " +- "checksum=%04x\n", hlen, ip->ip_sum); +- +- int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size; +- DPRINTF("+++ C+ mode TSO transferring packet size " +- "%d\n", tso_send_size); +- rtl8139_transfer_frame(s, saved_buffer, tso_send_size, +- 0, (uint8_t *) dot1q_buffer); +- +- /* add transferred count to TCP sequence number */ +- p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq)); +- ++send_count; +- } ++ int is_last_frame = 0; + +- /* Stop sending this frame */ +- saved_size = 0; +- } +- else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS)) ++ for (tcp_send_offset = 0; tcp_send_offset < tcp_data_len; tcp_send_offset += tcp_chunk_size) + { +- DPRINTF("+++ C+ mode need TCP or UDP checksum\n"); ++ uint16_t chunk_size = tcp_chunk_size; + +- /* maximum IP header length is 60 bytes */ +- uint8_t saved_ip_header[60]; +- memcpy(saved_ip_header, eth_payload_data, hlen); ++ /* check if this is the last frame */ ++ if (tcp_send_offset + tcp_chunk_size >= tcp_data_len) ++ { ++ is_last_frame = 1; ++ chunk_size = tcp_data_len - tcp_send_offset; ++ } + +- uint8_t *data_to_checksum = eth_payload_data + hlen - 12; +- // size_t data_to_checksum_len = eth_payload_len - hlen + 12; ++ DPRINTF("+++ C+ mode TSO TCP seqno %08x\n", ++ be32_to_cpu(p_tcp_hdr->th_seq)); + + /* add 4 TCP pseudoheader fields */ + /* copy IP source and destination fields */ + memcpy(data_to_checksum, saved_ip_header + 12, 8); + +- if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP) ++ DPRINTF("+++ C+ mode TSO calculating TCP checksum for " ++ "packet with %d bytes data\n", tcp_hlen + ++ chunk_size); ++ ++ if (tcp_send_offset) ++ { ++ memcpy((uint8_t*)p_tcp_hdr + tcp_hlen, (uint8_t*)p_tcp_hdr + tcp_hlen + tcp_send_offset, chunk_size); ++ } ++ ++ /* keep PUSH and FIN flags only for the last frame */ ++ if (!is_last_frame) + { +- DPRINTF("+++ C+ mode calculating TCP checksum for " +- "packet with %d bytes data\n", ip_data_len); ++ TCP_HEADER_CLEAR_FLAGS(p_tcp_hdr, TCP_FLAG_PUSH|TCP_FLAG_FIN); ++ } + +- ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; +- p_tcpip_hdr->zeros = 0; +- p_tcpip_hdr->ip_proto = IP_PROTO_TCP; +- p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len); ++ /* recalculate TCP checksum */ ++ ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; ++ p_tcpip_hdr->zeros = 0; ++ p_tcpip_hdr->ip_proto = IP_PROTO_TCP; ++ p_tcpip_hdr->ip_payload = cpu_to_be16(tcp_hlen + chunk_size); ++ ++ p_tcp_hdr->th_sum = 0; ++ ++ int tcp_checksum = ip_checksum(data_to_checksum, tcp_hlen + chunk_size + 12); ++ DPRINTF("+++ C+ mode TSO TCP checksum %04x\n", ++ tcp_checksum); + +- tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12); ++ p_tcp_hdr->th_sum = tcp_checksum; + +- p_tcp_hdr->th_sum = 0; ++ /* restore IP header */ ++ memcpy(eth_payload_data, saved_ip_header, hlen); + +- int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); +- DPRINTF("+++ C+ mode TCP checksum %04x\n", +- tcp_checksum); ++ /* set IP data length and recalculate IP checksum */ ++ ip->ip_len = cpu_to_be16(hlen + tcp_hlen + chunk_size); + +- p_tcp_hdr->th_sum = tcp_checksum; +- } +- else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP) +- { +- DPRINTF("+++ C+ mode calculating UDP checksum for " +- "packet with %d bytes data\n", ip_data_len); ++ /* increment IP id for subsequent frames */ ++ ip->ip_id = cpu_to_be16(tcp_send_offset/tcp_chunk_size + be16_to_cpu(ip->ip_id)); + +- ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum; +- p_udpip_hdr->zeros = 0; +- p_udpip_hdr->ip_proto = IP_PROTO_UDP; +- p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len); ++ ip->ip_sum = 0; ++ ip->ip_sum = ip_checksum(eth_payload_data, hlen); ++ DPRINTF("+++ C+ mode TSO IP header len=%d " ++ "checksum=%04x\n", hlen, ip->ip_sum); ++ ++ int tso_send_size = ETH_HLEN + hlen + tcp_hlen + chunk_size; ++ DPRINTF("+++ C+ mode TSO transferring packet size " ++ "%d\n", tso_send_size); ++ rtl8139_transfer_frame(s, saved_buffer, tso_send_size, ++ 0, (uint8_t *) dot1q_buffer); ++ ++ /* add transferred count to TCP sequence number */ ++ p_tcp_hdr->th_seq = cpu_to_be32(chunk_size + be32_to_cpu(p_tcp_hdr->th_seq)); ++ ++send_count; ++ } + +- udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12); ++ /* Stop sending this frame */ ++ saved_size = 0; ++ } ++ else if (txdw0 & (CP_TX_TCPCS|CP_TX_UDPCS)) ++ { ++ DPRINTF("+++ C+ mode need TCP or UDP checksum\n"); + +- p_udp_hdr->uh_sum = 0; ++ /* maximum IP header length is 60 bytes */ ++ uint8_t saved_ip_header[60]; ++ memcpy(saved_ip_header, eth_payload_data, hlen); + +- int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); +- DPRINTF("+++ C+ mode UDP checksum %04x\n", +- udp_checksum); ++ uint8_t *data_to_checksum = eth_payload_data + hlen - 12; ++ // size_t data_to_checksum_len = eth_payload_len - hlen + 12; + +- p_udp_hdr->uh_sum = udp_checksum; +- } ++ /* add 4 TCP pseudoheader fields */ ++ /* copy IP source and destination fields */ ++ memcpy(data_to_checksum, saved_ip_header + 12, 8); + +- /* restore IP header */ +- memcpy(eth_payload_data, saved_ip_header, hlen); ++ if ((txdw0 & CP_TX_TCPCS) && ip_protocol == IP_PROTO_TCP) ++ { ++ DPRINTF("+++ C+ mode calculating TCP checksum for " ++ "packet with %d bytes data\n", ip_data_len); ++ ++ ip_pseudo_header *p_tcpip_hdr = (ip_pseudo_header *)data_to_checksum; ++ p_tcpip_hdr->zeros = 0; ++ p_tcpip_hdr->ip_proto = IP_PROTO_TCP; ++ p_tcpip_hdr->ip_payload = cpu_to_be16(ip_data_len); ++ ++ tcp_header* p_tcp_hdr = (tcp_header *) (data_to_checksum+12); ++ ++ p_tcp_hdr->th_sum = 0; ++ ++ int tcp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); ++ DPRINTF("+++ C+ mode TCP checksum %04x\n", ++ tcp_checksum); ++ ++ p_tcp_hdr->th_sum = tcp_checksum; + } ++ else if ((txdw0 & CP_TX_UDPCS) && ip_protocol == IP_PROTO_UDP) ++ { ++ DPRINTF("+++ C+ mode calculating UDP checksum for " ++ "packet with %d bytes data\n", ip_data_len); ++ ++ ip_pseudo_header *p_udpip_hdr = (ip_pseudo_header *)data_to_checksum; ++ p_udpip_hdr->zeros = 0; ++ p_udpip_hdr->ip_proto = IP_PROTO_UDP; ++ p_udpip_hdr->ip_payload = cpu_to_be16(ip_data_len); ++ ++ udp_header *p_udp_hdr = (udp_header *) (data_to_checksum+12); ++ ++ p_udp_hdr->uh_sum = 0; ++ ++ int udp_checksum = ip_checksum(data_to_checksum, ip_data_len + 12); ++ DPRINTF("+++ C+ mode UDP checksum %04x\n", ++ udp_checksum); ++ ++ p_udp_hdr->uh_sum = udp_checksum; ++ } ++ ++ /* restore IP header */ ++ memcpy(eth_payload_data, saved_ip_header, hlen); + } + } + ++skip_offload: + /* update tally counter */ + ++s->tally_counters.TxOk; + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-5239.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-5239.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-5239.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-5239.patch 2015-09-23 19:13:02.000000000 +0000 @@ -0,0 +1,50 @@ +From f9a70e79391f6d7c2a912d785239ee8effc1922d Mon Sep 17 00:00:00 2001 +From: Peter Lieven +Date: Mon, 30 Jun 2014 10:07:54 +0200 +Subject: [PATCH] ui/vnc: limit client_cut_text msg payload size + +currently a malicious client could define a payload +size of 2^32 - 1 bytes and send up to that size of +data to the vnc server. The server would allocated +that amount of memory which could easily create an +out of memory condition. + +This patch limits the payload size to 1MB max. + +Please note that client_cut_text messages are currently +silently ignored. + +Signed-off-by: Peter Lieven +Signed-off-by: Gerd Hoffmann +--- + ui/vnc.c | 13 ++++++++++--- + 1 files changed, 10 insertions(+), 3 deletions(-) + +Index: qemu-2.0.0+dfsg/ui/vnc.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/ui/vnc.c 2015-09-23 15:13:00.485557480 -0400 ++++ qemu-2.0.0+dfsg/ui/vnc.c 2015-09-23 15:13:00.481557431 -0400 +@@ -2149,13 +2149,20 @@ + pointer_event(vs, read_u8(data, 1), read_u16(data, 2), read_u16(data, 4)); + break; + case VNC_MSG_CLIENT_CUT_TEXT: +- if (len == 1) ++ if (len == 1) { + return 8; +- ++ } + if (len == 8) { + uint32_t dlen = read_u32(data, 4); +- if (dlen > 0) ++ if (dlen > (1 << 20)) { ++ error_report("vnc: client_cut_text msg payload has %u bytes" ++ " which exceeds our limit of 1MB.", dlen); ++ vnc_client_error(vs); ++ break; ++ } ++ if (dlen > 0) { + return 8 + dlen; ++ } + } + + client_cut_text(vs, read_u32(data, 4), data + 8); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-5278.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-5278.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-5278.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-5278.patch 2015-09-23 19:13:10.000000000 +0000 @@ -0,0 +1,31 @@ +From 737d2b3c41d59eb8f94ab7eb419b957938f24943 Mon Sep 17 00:00:00 2001 +From: P J P +Date: Tue, 15 Sep 2015 16:46:59 +0530 +Subject: [PATCH] net: avoid infinite loop when receiving packets(CVE-2015-5278) + +Ne2000 NIC uses ring buffer of NE2000_MEM_SIZE(49152) +bytes to process network packets. While receiving packets +via ne2000_receive() routine, a local 'index' variable +could exceed the ring buffer size, leading to an infinite +loop situation. + +Reported-by: Qinghao Tang +Signed-off-by: P J P +Signed-off-by: Stefan Hajnoczi +--- + hw/net/ne2000.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/ne2000.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/ne2000.c 2015-09-23 15:13:08.353653802 -0400 ++++ qemu-2.0.0+dfsg/hw/net/ne2000.c 2015-09-23 15:13:08.353653802 -0400 +@@ -253,7 +253,7 @@ + if (index <= s->stop) + avail = s->stop - index; + else +- avail = 0; ++ break; + len = size; + if (len > avail) + len = avail; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-5279.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-5279.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-5279.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-5279.patch 2015-09-23 19:13:15.000000000 +0000 @@ -0,0 +1,66 @@ +From 9bbdbc66e5765068dce76e9269dce4547afd8ad4 Mon Sep 17 00:00:00 2001 +From: P J P +Date: Tue, 15 Sep 2015 16:40:49 +0530 +Subject: [PATCH] net: add checks to validate ring buffer pointers(CVE-2015-5279) + +Ne2000 NIC uses ring buffer of NE2000_MEM_SIZE(49152) +bytes to process network packets. While receiving packets +via ne2000_receive() routine, a local 'index' variable +could exceed the ring buffer size, which could lead to a +memory buffer overflow. Added other checks at initialisation. + +Reported-by: Qinghao Tang +Signed-off-by: P J P +Signed-off-by: Stefan Hajnoczi +--- + hw/net/ne2000.c | 19 +++++++++++++++---- + 1 files changed, 15 insertions(+), 4 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/ne2000.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/ne2000.c 2015-09-23 15:13:13.997722905 -0400 ++++ qemu-2.0.0+dfsg/hw/net/ne2000.c 2015-09-23 15:13:13.993722856 -0400 +@@ -230,6 +230,9 @@ + } + + index = s->curpag << 8; ++ if (index >= NE2000_PMEM_END) { ++ index = s->start; ++ } + /* 4 bytes for header */ + total_len = size + 4; + /* address for next packet (4 bytes for CRC) */ +@@ -315,13 +318,19 @@ + offset = addr | (page << 4); + switch(offset) { + case EN0_STARTPG: +- s->start = val << 8; ++ if (val << 8 <= NE2000_PMEM_END) { ++ s->start = val << 8; ++ } + break; + case EN0_STOPPG: +- s->stop = val << 8; ++ if (val << 8 <= NE2000_PMEM_END) { ++ s->stop = val << 8; ++ } + break; + case EN0_BOUNDARY: +- s->boundary = val; ++ if (val << 8 < NE2000_PMEM_END) { ++ s->boundary = val; ++ } + break; + case EN0_IMR: + s->imr = val; +@@ -362,7 +371,9 @@ + s->phys[offset - EN1_PHYS] = val; + break; + case EN1_CURPAG: +- s->curpag = val; ++ if (val << 8 < NE2000_PMEM_END) { ++ s->curpag = val; ++ } + break; + case EN1_MULT ... EN1_MULT + 7: + s->mult[offset - EN1_MULT] = val; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-5745.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-5745.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-5745.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-5745.patch 2015-08-25 14:03:16.000000000 +0000 @@ -0,0 +1,29 @@ +From 7882080388be5088e72c425b02223c02e6cb4295 Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Thu, 23 Jul 2015 17:52:02 +0300 +Subject: [PATCH] virtio-serial: fix ANY_LAYOUT + +Don't assume a specific layout for control messages. +Required by virtio 1. + +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Amit Shah +Reviewed-by: Jason Wang +--- + hw/char/virtio-serial-bus.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/char/virtio-serial-bus.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/char/virtio-serial-bus.c 2015-08-25 10:03:12.388231214 -0400 ++++ qemu-2.0.0+dfsg/hw/char/virtio-serial-bus.c 2015-08-25 10:03:12.348230799 -0400 +@@ -173,7 +173,8 @@ + return 0; + } + +- memcpy(elem.in_sg[0].iov_base, buf, len); ++ /* TODO: detect a buffer that's too short, set NEEDS_RESET */ ++ iov_from_buf(elem.in_sg, elem.in_num, 0, buf, len); + + virtqueue_push(vq, &elem, len); + virtio_notify(VIRTIO_DEVICE(vser), vq); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-6815.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-6815.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-6815.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-6815.patch 2015-09-23 19:13:23.000000000 +0000 @@ -0,0 +1,34 @@ +From b947ac2bf26479e710489739c465c8af336599e7 Mon Sep 17 00:00:00 2001 +From: P J P +Date: Fri, 4 Sep 2015 17:21:06 +0100 +Subject: [PATCH] e1000: Avoid infinite loop in processing transmit descriptor (CVE-2015-6815) + +While processing transmit descriptors, it could lead to an infinite +loop if 'bytes' was to become zero; Add a check to avoid it. + +[The guest can force 'bytes' to 0 by setting the hdr_len and mss +descriptor fields to 0. +--Stefan] + +Signed-off-by: P J P +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Thomas Huth +Message-id: 1441383666-6590-1-git-send-email-stefanha@redhat.com +--- + hw/net/e1000.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/e1000.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/e1000.c 2015-09-23 15:13:21.441814055 -0400 ++++ qemu-2.0.0+dfsg/hw/net/e1000.c 2015-09-23 15:13:21.441814055 -0400 +@@ -707,7 +707,8 @@ + memmove(tp->data, tp->header, tp->hdr_len); + tp->size = tp->hdr_len; + } +- } while (split_size -= bytes); ++ split_size -= bytes; ++ } while (bytes && split_size); + } else if (!tp->tse && tp->cptse) { + // context descriptor TSE is not set, while data descriptor TSE is set + DBGOUT(TXERR, "TCP segmentation error\n"); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-6855.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-6855.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-6855.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-6855.patch 2015-09-23 19:13:31.000000000 +0000 @@ -0,0 +1,141 @@ +From d9033e1d3aa666c5071580617a57bd853c5d794a Mon Sep 17 00:00:00 2001 +From: John Snow +Date: Thu, 17 Sep 2015 14:17:05 -0400 +Subject: [PATCH] ide: fix ATAPI command permissions + +We're a little too lenient with what we'll let an ATAPI drive handle. +Clamp down on the IDE command execution table to remove CD_OK permissions +from commands that are not and have never been ATAPI commands. + +For ATAPI command validity, please see: +- ATA4 Section 6.5 ("PACKET Command feature set") +- ATA8/ACS Section 4.3 ("The PACKET feature set") +- ACS3 Section 4.3 ("The PACKET feature set") + +ACS3 has a historical command validity table in Table B.4 +("Historical Command Assignments") that can be referenced to find when +a command was introduced, deprecated, obsoleted, etc. + +The only reference for ATAPI command validity is by checking that +version's PACKET feature set section. + +ATAPI was introduced by T13 into ATA4, all commands retired prior to ATA4 +therefore are assumed to have never been ATAPI commands. + +Mandatory commands, as listed in ATA8-ACS3, are: + +- DEVICE RESET +- EXECUTE DEVICE DIAGNOSTIC +- IDENTIFY DEVICE +- IDENTIFY PACKET DEVICE +- NOP +- PACKET +- READ SECTOR(S) +- SET FEATURES + +Optional commands as listed in ATA8-ACS3, are: + +- FLUSH CACHE +- READ LOG DMA EXT +- READ LOG EXT +- WRITE LOG DMA EXT +- WRITE LOG EXT + +All other commands are illegal to send to an ATAPI device and should +be rejected by the device. + +CD_OK removal justifications: + +0x06 WIN_DSM Defined in ACS2. Not valid for ATAPI. +0x21 WIN_READ_ONCE Retired in ATA5. Not ATAPI in ATA4. +0x94 WIN_STANDBYNOW2 Retired in ATA4. Did not coexist with ATAPI. +0x95 WIN_IDLEIMMEDIATE2 Retired in ATA4. Did not coexist with ATAPI. +0x96 WIN_STANDBY2 Retired in ATA4. Did not coexist with ATAPI. +0x97 WIN_SETIDLE2 Retired in ATA4. Did not coexist with ATAPI. +0x98 WIN_CHECKPOWERMODE2 Retired in ATA4. Did not coexist with ATAPI. +0x99 WIN_SLEEPNOW2 Retired in ATA4. Did not coexist with ATAPI. +0xE0 WIN_STANDBYNOW1 Not part of ATAPI in ATA4, ACS or ACS3. +0xE1 WIN_IDLEIMMDIATE Not part of ATAPI in ATA4, ACS or ACS3. +0xE2 WIN_STANDBY Not part of ATAPI in ATA4, ACS or ACS3. +0xE3 WIN_SETIDLE1 Not part of ATAPI in ATA4, ACS or ACS3. +0xE4 WIN_CHECKPOWERMODE1 Not part of ATAPI in ATA4, ACS or ACS3. +0xE5 WIN_SLEEPNOW1 Not part of ATAPI in ATA4, ACS or ACS3. +0xF8 WIN_READ_NATIVE_MAX Obsoleted in ACS3. Not ATAPI in ATA4 or ACS. + +This patch fixes a divide by zero fault that can be caused by sending +the WIN_READ_NATIVE_MAX command to an ATAPI drive, which causes it to +attempt to use zeroed CHS values to perform sector arithmetic. + +Reported-by: Qinghao Tang +Signed-off-by: John Snow +Reviewed-by: Markus Armbruster +Message-id: 1441816082-21031-1-git-send-email-jsnow@redhat.com +CC: qemu-stable@nongnu.org +--- + hw/ide/core.c | 30 +++++++++++++++--------------- + 1 files changed, 15 insertions(+), 15 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/ide/core.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/ide/core.c 2015-09-23 15:13:28.877905118 -0400 ++++ qemu-2.0.0+dfsg/hw/ide/core.c 2015-09-23 15:13:28.873905069 -0400 +@@ -1639,11 +1639,11 @@ + } ide_cmd_table[0x100] = { + /* NOP not implemented, mandatory for CD */ + [CFA_REQ_EXT_ERROR_CODE] = { cmd_cfa_req_ext_error_code, CFA_OK }, +- [WIN_DSM] = { cmd_data_set_management, ALL_OK }, ++ [WIN_DSM] = { cmd_data_set_management, HD_CFA_OK }, + [WIN_DEVICE_RESET] = { cmd_device_reset, CD_OK }, + [WIN_RECAL] = { cmd_nop, HD_CFA_OK | SET_DSC}, + [WIN_READ] = { cmd_read_pio, ALL_OK }, +- [WIN_READ_ONCE] = { cmd_read_pio, ALL_OK }, ++ [WIN_READ_ONCE] = { cmd_read_pio, HD_CFA_OK }, + [WIN_READ_EXT] = { cmd_read_pio, HD_CFA_OK }, + [WIN_READDMA_EXT] = { cmd_read_dma, HD_CFA_OK }, + [WIN_READ_NATIVE_MAX_EXT] = { cmd_read_native_max, HD_CFA_OK | SET_DSC }, +@@ -1662,12 +1662,12 @@ + [CFA_TRANSLATE_SECTOR] = { cmd_cfa_translate_sector, CFA_OK }, + [WIN_DIAGNOSE] = { cmd_exec_dev_diagnostic, ALL_OK }, + [WIN_SPECIFY] = { cmd_nop, HD_CFA_OK | SET_DSC }, +- [WIN_STANDBYNOW2] = { cmd_nop, ALL_OK }, +- [WIN_IDLEIMMEDIATE2] = { cmd_nop, ALL_OK }, +- [WIN_STANDBY2] = { cmd_nop, ALL_OK }, +- [WIN_SETIDLE2] = { cmd_nop, ALL_OK }, +- [WIN_CHECKPOWERMODE2] = { cmd_check_power_mode, ALL_OK | SET_DSC }, +- [WIN_SLEEPNOW2] = { cmd_nop, ALL_OK }, ++ [WIN_STANDBYNOW2] = { cmd_nop, HD_CFA_OK }, ++ [WIN_IDLEIMMEDIATE2] = { cmd_nop, HD_CFA_OK }, ++ [WIN_STANDBY2] = { cmd_nop, HD_CFA_OK }, ++ [WIN_SETIDLE2] = { cmd_nop, HD_CFA_OK }, ++ [WIN_CHECKPOWERMODE2] = { cmd_check_power_mode, HD_CFA_OK | SET_DSC }, ++ [WIN_SLEEPNOW2] = { cmd_nop, HD_CFA_OK }, + [WIN_PACKETCMD] = { cmd_packet, CD_OK }, + [WIN_PIDENTIFY] = { cmd_identify_packet, CD_OK }, + [WIN_SMART] = { cmd_smart, HD_CFA_OK | SET_DSC }, +@@ -1681,19 +1681,19 @@ + [WIN_WRITEDMA] = { cmd_write_dma, HD_CFA_OK }, + [WIN_WRITEDMA_ONCE] = { cmd_write_dma, HD_CFA_OK }, + [CFA_WRITE_MULTI_WO_ERASE] = { cmd_write_multiple, CFA_OK }, +- [WIN_STANDBYNOW1] = { cmd_nop, ALL_OK }, +- [WIN_IDLEIMMEDIATE] = { cmd_nop, ALL_OK }, +- [WIN_STANDBY] = { cmd_nop, ALL_OK }, +- [WIN_SETIDLE1] = { cmd_nop, ALL_OK }, +- [WIN_CHECKPOWERMODE1] = { cmd_check_power_mode, ALL_OK | SET_DSC }, +- [WIN_SLEEPNOW1] = { cmd_nop, ALL_OK }, ++ [WIN_STANDBYNOW1] = { cmd_nop, HD_CFA_OK }, ++ [WIN_IDLEIMMEDIATE] = { cmd_nop, HD_CFA_OK }, ++ [WIN_STANDBY] = { cmd_nop, HD_CFA_OK }, ++ [WIN_SETIDLE1] = { cmd_nop, HD_CFA_OK }, ++ [WIN_CHECKPOWERMODE1] = { cmd_check_power_mode, HD_CFA_OK | SET_DSC }, ++ [WIN_SLEEPNOW1] = { cmd_nop, HD_CFA_OK }, + [WIN_FLUSH_CACHE] = { cmd_flush_cache, ALL_OK }, + [WIN_FLUSH_CACHE_EXT] = { cmd_flush_cache, HD_CFA_OK }, + [WIN_IDENTIFY] = { cmd_identify, ALL_OK }, + [WIN_SETFEATURES] = { cmd_set_features, ALL_OK | SET_DSC }, + [IBM_SENSE_CONDITION] = { cmd_ibm_sense_condition, CFA_OK | SET_DSC }, + [CFA_WEAR_LEVEL] = { cmd_cfa_erase_sectors, HD_CFA_OK | SET_DSC }, +- [WIN_READ_NATIVE_MAX] = { cmd_read_native_max, ALL_OK | SET_DSC }, ++ [WIN_READ_NATIVE_MAX] = { cmd_read_native_max, HD_CFA_OK | SET_DSC }, + }; + + static bool ide_cmd_permitted(IDEState *s, uint32_t cmd) diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-7295.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-7295.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-7295.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-7295.patch 2015-12-01 21:00:53.000000000 +0000 @@ -0,0 +1,81 @@ +Description: fix denial of service via jumbo frame flood in virtio +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=ce317461573bac12b10d67699b4ddf1f97cf066c +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=29b9f5efd78ae0f9cc02dd169b6e80d2c404bade +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=0cf33fb6b49a19de32859e2cdc6021334f448fb3 +Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=799452 + +Index: qemu-2.0.0+dfsg/hw/net/virtio-net.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/virtio-net.c 2015-12-01 16:00:51.324389271 -0500 ++++ qemu-2.0.0+dfsg/hw/net/virtio-net.c 2015-12-01 16:00:51.296389018 -0500 +@@ -1032,13 +1032,7 @@ + * must have consumed the complete packet. + * Otherwise, drop it. */ + if (!n->mergeable_rx_bufs && offset < size) { +-#if 0 +- error_report("virtio-net truncated non-mergeable packet: " +- "i %zd mergeable %d offset %zd, size %zd, " +- "guest hdr len %zd, host hdr len %zd", +- i, n->mergeable_rx_bufs, +- offset, size, n->guest_hdr_len, n->host_hdr_len); +-#endif ++ virtqueue_discard(q->rx_vq, &elem, total); + return size; + } + +Index: qemu-2.0.0+dfsg/hw/virtio/virtio.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/virtio/virtio.c 2015-12-01 16:00:51.324389271 -0500 ++++ qemu-2.0.0+dfsg/hw/virtio/virtio.c 2015-12-01 16:00:51.308389127 -0500 +@@ -235,14 +235,12 @@ + return vring_avail_idx(vq) == vq->last_avail_idx; + } + +-void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem, +- unsigned int len, unsigned int idx) ++static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem, ++ unsigned int len) + { + unsigned int offset; + int i; + +- trace_virtqueue_fill(vq, elem, len, idx); +- + offset = 0; + for (i = 0; i < elem->in_num; i++) { + size_t size = MIN(len - offset, elem->in_sg[i].iov_len); +@@ -258,6 +256,21 @@ + cpu_physical_memory_unmap(elem->out_sg[i].iov_base, + elem->out_sg[i].iov_len, + 0, elem->out_sg[i].iov_len); ++} ++ ++void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem, ++ unsigned int len) ++{ ++ vq->last_avail_idx--; ++ virtqueue_unmap_sg(vq, elem, len); ++} ++ ++void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem, ++ unsigned int len, unsigned int idx) ++{ ++ trace_virtqueue_fill(vq, elem, len, idx); ++ ++ virtqueue_unmap_sg(vq, elem, len); + + idx = (idx + vring_used_idx(vq)) % vq->vring.num; + +Index: qemu-2.0.0+dfsg/include/hw/virtio/virtio.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/include/hw/virtio/virtio.h 2015-12-01 16:00:51.324389271 -0500 ++++ qemu-2.0.0+dfsg/include/hw/virtio/virtio.h 2015-12-01 16:00:51.324389271 -0500 +@@ -168,6 +168,8 @@ + void virtqueue_push(VirtQueue *vq, const VirtQueueElement *elem, + unsigned int len); + void virtqueue_flush(VirtQueue *vq, unsigned int count); ++void virtqueue_discard(VirtQueue *vq, const VirtQueueElement *elem, ++ unsigned int len); + void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem, + unsigned int len, unsigned int idx); + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-7504.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-7504.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-7504.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-7504.patch 2015-12-01 21:01:01.000000000 +0000 @@ -0,0 +1,45 @@ +From: Jason Wang +Subject: [Qemu-devel] [PATCH for 2.5 1/2] net: pcnet: add check to validate receive data size(CVE-2015-7504) +Date: Mon, 30 Nov 2015 15:38:22 +0800 + +From: Prasad J Pandit + +In loopback mode, pcnet_receive routine appends CRC code to the +receive buffer. If the data size given is same as the buffer size, +the appended CRC code overwrites 4 bytes after s->buffer. Added a +check to avoid that. + +Reported by: Qinghao Tang +Cc: address@hidden +Signed-off-by: Prasad J Pandit +Signed-off-by: Jason Wang +--- + hw/net/pcnet.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/pcnet.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/pcnet.c 2015-12-01 16:00:58.496454009 -0500 ++++ qemu-2.0.0+dfsg/hw/net/pcnet.c 2015-12-01 16:00:58.492453973 -0500 +@@ -1107,7 +1107,7 @@ + uint32_t fcs = ~0; + uint8_t *p = src; + +- while (p != &src[size-4]) ++ while (p != &src[size]) + CRC(fcs, *p++); + crc_err = (*(uint32_t *)p != htonl(fcs)); + } +@@ -1256,8 +1256,10 @@ + bcnt = 4096 - GET_FIELD(tmd.length, TMDL, BCNT); + + /* if multi-tmd packet outsizes s->buffer then skip it silently. +- Note: this is not what real hw does */ +- if (s->xmit_pos + bcnt > sizeof(s->buffer)) { ++ * Note: this is not what real hw does. ++ * Last four bytes of s->buffer are used to store CRC FCS code. ++ */ ++ if (s->xmit_pos + bcnt > sizeof(s->buffer) - 4) { + s->xmit_pos = -1; + goto txdone; + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-7512.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-7512.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-7512.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-7512.patch 2015-12-01 21:01:09.000000000 +0000 @@ -0,0 +1,32 @@ +From: Jason Wang +Subject: [Qemu-devel] [PATCH for 2.5 2/2] pcnet: fix rx buffer overflow(CVE-2015-7512) +Date: Mon, 30 Nov 2015 15:38:23 +0800 + +Backends could provide a packet whose length is greater than buffer +size. Check for this and truncate the packet to avoid rx buffer +overflow in this case. + +Cc: Prasad J Pandit +Cc: address@hidden +Signed-off-by: Jason Wang +--- + hw/net/pcnet.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +Index: qemu-2.0.0+dfsg/hw/net/pcnet.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/pcnet.c 2015-12-01 16:01:06.620527330 -0500 ++++ qemu-2.0.0+dfsg/hw/net/pcnet.c 2015-12-01 16:01:06.620527330 -0500 +@@ -1087,6 +1087,12 @@ + int pktcount = 0; + + if (!s->looptest) { ++ if (size > 4092) { ++#ifdef PCNET_DEBUG_RMD ++ fprintf(stderr, "pcnet: truncates rx packet.\n"); ++#endif ++ size = 4092; ++ } + memcpy(src, buf, size); + /* no need to compute the CRC */ + src[size] = 0; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-7549.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-7549.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-7549.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-7549.patch 2016-02-02 12:23:24.000000000 +0000 @@ -0,0 +1,60 @@ +From 43b11a91dd861a946b231b89b7542856ade23d1b Mon Sep 17 00:00:00 2001 +From: =?utf8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Fri, 26 Jun 2015 14:25:29 +0200 +Subject: [PATCH] msix: implement pba write (but read-only) +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf8 +Content-Transfer-Encoding: 8bit + +qpci_msix_pending() writes on pba region, causing qemu to SEGV: + + Program received signal SIGSEGV, Segmentation fault. + [Switching to Thread 0x7ffff7fba8c0 (LWP 25882)] + 0x0000000000000000 in ?? () + (gdb) bt + #0 0x0000000000000000 in () + #1 0x00005555556556c5 in memory_region_oldmmio_write_accessor (mr=0x5555579f3f80, addr=0, value=0x7fffffffbf68, size=4, shift=0, mask=4294967295, attrs=...) at /home/elmarco/src/qemu/memory.c:434 + #2 0x00005555556558e1 in access_with_adjusted_size (addr=0, value=0x7fffffffbf68, size=4, access_size_min=1, access_size_max=4, access=0x55555565563e , mr=0x5555579f3f80, attrs=...) at /home/elmarco/src/qemu/memory.c:506 + #3 0x00005555556581eb in memory_region_dispatch_write (mr=0x5555579f3f80, addr=0, data=0, size=4, attrs=...) at /home/elmarco/src/qemu/memory.c:1176 + #4 0x000055555560b6f9 in address_space_rw (as=0x555555eff4e0 , addr=3759147008, attrs=..., buf=0x7fffffffc1b0 "", len=4, is_write=true) at /home/elmarco/src/qemu/exec.c:2439 + #5 0x000055555560baa2 in cpu_physical_memory_rw (addr=3759147008, buf=0x7fffffffc1b0 "", len=4, is_write=1) at /home/elmarco/src/qemu/exec.c:2534 + #6 0x000055555564c005 in cpu_physical_memory_write (addr=3759147008, buf=0x7fffffffc1b0, len=4) at /home/elmarco/src/qemu/include/exec/cpu-common.h:80 + #7 0x000055555564cd9c in qtest_process_command (chr=0x55555642b890, words=0x5555578de4b0) at /home/elmarco/src/qemu/qtest.c:378 + #8 0x000055555564db77 in qtest_process_inbuf (chr=0x55555642b890, inbuf=0x55555641b340) at /home/elmarco/src/qemu/qtest.c:569 + #9 0x000055555564dc07 in qtest_read (opaque=0x55555642b890, buf=0x7fffffffc2e0 "writel 0xe0100800 0x0\n", size=22) at /home/elmarco/src/qemu/qtest.c:581 + #10 0x000055555574ce3e in qemu_chr_be_write (s=0x55555642b890, buf=0x7fffffffc2e0 "writel 0xe0100800 0x0\n", len=22) at qemu-char.c:306 + #11 0x0000555555751263 in tcp_chr_read (chan=0x55555642bcf0, cond=G_IO_IN, opaque=0x55555642b890) at qemu-char.c:2876 + #12 0x00007ffff64c9a8a in g_main_context_dispatch (context=0x55555641c400) at gmain.c:3122 + +(without this patch, this can be reproduced with the ivshmem qtest) + +Implement an empty mmio write to avoid the crash. + +Signed-off-by: Marc-André Lureau +Reviewed-by: Paolo Bonzini +--- + hw/pci/msix.c | 6 ++++++ + 1 files changed, 6 insertions(+), 0 deletions(-) + +diff --git a/hw/pci/msix.c b/hw/pci/msix.c +index 2fdada4..64c93d8 100644 +--- a/hw/pci/msix.c ++++ b/hw/pci/msix.c +@@ -200,8 +200,14 @@ static uint64_t msix_pba_mmio_read(void *opaque, hwaddr addr, + return pci_get_long(dev->msix_pba + addr); + } + ++static void msix_pba_mmio_write(void *opaque, hwaddr addr, ++ uint64_t val, unsigned size) ++{ ++} ++ + static const MemoryRegionOps msix_pba_mmio_ops = { + .read = msix_pba_mmio_read, ++ .write = msix_pba_mmio_write, + .endianness = DEVICE_LITTLE_ENDIAN, + .valid = { + .min_access_size = 4, +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8345.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-8345.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8345.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-8345.patch 2015-12-01 21:01:12.000000000 +0000 @@ -0,0 +1,63 @@ +From 00837731d254908a841d69298a4f9f077babaf24 Mon Sep 17 00:00:00 2001 +From: Stefan Weil +Date: Fri, 20 Nov 2015 08:42:33 +0100 +Subject: [PATCH] eepro100: Prevent two endless loops + +http://lists.nongnu.org/archive/html/qemu-devel/2015-11/msg04592.html +shows an example how an endless loop in function action_command can +be achieved. + +During my code review, I noticed a 2nd case which can result in an +endless loop. + +Reported-by: Qinghao Tang +Signed-off-by: Stefan Weil +Signed-off-by: Jason Wang +--- + hw/net/eepro100.c | 16 ++++++++++++++++ + 1 files changed, 16 insertions(+), 0 deletions(-) + +diff --git a/hw/net/eepro100.c b/hw/net/eepro100.c +index 60333b7..685a478 100644 +--- a/hw/net/eepro100.c ++++ b/hw/net/eepro100.c +@@ -774,6 +774,11 @@ static void tx_command(EEPRO100State *s) + #if 0 + uint16_t tx_buffer_el = lduw_le_pci_dma(&s->dev, tbd_address + 6); + #endif ++ if (tx_buffer_size == 0) { ++ /* Prevent an endless loop. */ ++ logout("loop in %s:%u\n", __FILE__, __LINE__); ++ break; ++ } + tbd_address += 8; + TRACE(RXTX, logout + ("TBD (simplified mode): buffer address 0x%08x, size 0x%04x\n", +@@ -855,6 +860,10 @@ static void set_multicast_list(EEPRO100State *s) + + static void action_command(EEPRO100State *s) + { ++ /* The loop below won't stop if it gets special handcrafted data. ++ Therefore we limit the number of iterations. */ ++ unsigned max_loop_count = 16; ++ + for (;;) { + bool bit_el; + bool bit_s; +@@ -870,6 +879,13 @@ static void action_command(EEPRO100State *s) + #if 0 + bool bit_sf = ((s->tx.command & COMMAND_SF) != 0); + #endif ++ ++ if (max_loop_count-- == 0) { ++ /* Prevent an endless loop. */ ++ logout("loop in %s:%u\n", __FILE__, __LINE__); ++ break; ++ } ++ + s->cu_offset = s->tx.link; + TRACE(OTHER, + logout("val=(cu start), status=0x%04x, command=0x%04x, link=0x%08x\n", +-- +1.7.0.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8504.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-8504.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8504.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-8504.patch 2016-02-02 12:23:34.000000000 +0000 @@ -0,0 +1,41 @@ +From 4c65fed8bdf96780735dbdb92a8bd0d6b6526cc3 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Thu, 3 Dec 2015 18:54:17 +0530 +Subject: [PATCH] ui: vnc: avoid floating point exception + +While sending 'SetPixelFormat' messages to a VNC server, +the client could set the 'red-max', 'green-max' and 'blue-max' +values to be zero. This leads to a floating point exception in +write_png_palette while doing frame buffer updates. + +Reported-by: Lian Yihan +Signed-off-by: Prasad J Pandit +Reviewed-by: Gerd Hoffmann +Signed-off-by: Peter Maydell +--- + ui/vnc.c | 6 +++--- + 1 files changed, 3 insertions(+), 3 deletions(-) + +Index: qemu-2.0.0+dfsg/ui/vnc.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/ui/vnc.c 2016-02-02 07:23:31.660832466 -0500 ++++ qemu-2.0.0+dfsg/ui/vnc.c 2016-02-02 07:23:31.656832424 -0500 +@@ -2020,15 +2020,15 @@ + return; + } + +- vs->client_pf.rmax = red_max; ++ vs->client_pf.rmax = red_max ? red_max : 0xFF; + vs->client_pf.rbits = hweight_long(red_max); + vs->client_pf.rshift = red_shift; + vs->client_pf.rmask = red_max << red_shift; +- vs->client_pf.gmax = green_max; ++ vs->client_pf.gmax = green_max ? green_max : 0xFF; + vs->client_pf.gbits = hweight_long(green_max); + vs->client_pf.gshift = green_shift; + vs->client_pf.gmask = green_max << green_shift; +- vs->client_pf.bmax = blue_max; ++ vs->client_pf.bmax = blue_max ? blue_max : 0xFF; + vs->client_pf.bbits = hweight_long(blue_max); + vs->client_pf.bshift = blue_shift; + vs->client_pf.bmask = blue_max << blue_shift; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8550-1.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-8550-1.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8550-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-8550-1.patch 2016-02-02 12:25:51.000000000 +0000 @@ -0,0 +1,51 @@ +Backport of: + +From f9e98e5d7a67367b862941e339a98b8322fa0cea Mon Sep 17 00:00:00 2001 +From: Stefano Stabellini +Date: Fri, 18 Dec 2015 15:09:58 +0000 +Subject: [PATCH] xen/blkif: Avoid double access to src->nr_segments + +src is stored in shared memory and src->nr_segments is dereferenced +twice at the end of the function. If a compiler decides to compile this +into two separate memory accesses then the size limitation could be +bypassed. + +Fix it by removing the double access to src->nr_segments. + +This is part of XSA-155. + +Signed-off-by: Stefano Stabellini +--- + hw/block/xen_blkif.h | 12 ++++++++---- + 1 files changed, 8 insertions(+), 4 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/block/xen_blkif.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/block/xen_blkif.h 2016-02-02 07:23:50.573030994 -0500 ++++ qemu-2.0.0+dfsg/hw/block/xen_blkif.h 2016-02-02 07:25:26.142033886 -0500 +@@ -79,8 +79,10 @@ + dst->handle = src->handle; + dst->id = src->id; + dst->sector_number = src->sector_number; +- if (n > src->nr_segments) +- n = src->nr_segments; ++ /* prevent the compiler from optimizing the code and using src->nr_segments instead */ ++ barrier(); ++ if (n > dst->nr_segments) ++ n = dst->nr_segments; + for (i = 0; i < n; i++) + dst->seg[i] = src->seg[i]; + } +@@ -94,8 +96,10 @@ + dst->handle = src->handle; + dst->id = src->id; + dst->sector_number = src->sector_number; +- if (n > src->nr_segments) +- n = src->nr_segments; ++ /* prevent the compiler from optimizing the code and using src->nr_segments instead */ ++ barrier(); ++ if (n > dst->nr_segments) ++ n = dst->nr_segments; + for (i = 0; i < n; i++) + dst->seg[i] = src->seg[i]; + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8550-2.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-8550-2.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8550-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-8550-2.patch 2016-02-02 12:26:03.000000000 +0000 @@ -0,0 +1,46 @@ +From 7ea11bf376aea4bf8340eb363de9777c7f93e556 Mon Sep 17 00:00:00 2001 +From: Stefano Stabellini +Date: Fri, 18 Dec 2015 15:10:09 +0000 +Subject: [PATCH] xenfb: avoid reading twice the same fields from the shared page + +Reading twice the same field could give the guest an attack of +opportunity. In the case of event->type, gcc could compile the switch +statement into a jump table, effectively ending up reading the type +field multiple times. + +This is part of XSA-155. + +Signed-off-by: Stefano Stabellini +--- + hw/display/xenfb.c | 10 ++++++---- + 1 files changed, 6 insertions(+), 4 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/display/xenfb.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/display/xenfb.c 2016-02-02 07:26:01.502404816 -0500 ++++ qemu-2.0.0+dfsg/hw/display/xenfb.c 2016-02-02 07:26:01.498404774 -0500 +@@ -775,18 +775,20 @@ + + static void xenfb_handle_events(struct XenFB *xenfb) + { +- uint32_t prod, cons; ++ uint32_t prod, cons, out_cons; + struct xenfb_page *page = xenfb->c.page; + + prod = page->out_prod; +- if (prod == page->out_cons) ++ out_cons = page->out_cons; ++ if (prod == out_cons) + return; + xen_rmb(); /* ensure we see ring contents up to prod */ +- for (cons = page->out_cons; cons != prod; cons++) { ++ for (cons = out_cons; cons != prod; cons++) { + union xenfb_out_event *event = &XENFB_OUT_RING_REF(page, cons); ++ uint8_t type = event->type; + int x, y, w, h; + +- switch (event->type) { ++ switch (type) { + case XENFB_TYPE_UPDATE: + if (xenfb->up_count == UP_QUEUE) + xenfb->up_fullscreen = 1; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8558.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-8558.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8558.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-8558.patch 2016-02-02 12:26:14.000000000 +0000 @@ -0,0 +1,45 @@ +From 156a2e4dbffa85997636a7a39ef12da6f1b40254 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Mon, 14 Dec 2015 09:21:23 +0100 +Subject: [PATCH] ehci: make idt processing more robust + +Make ehci_process_itd return an error in case we didn't do any actual +iso transfer because we've found no active transaction. That'll avoid +ehci happily run in circles forever if the guest builds a loop out of +idts. + +This is CVE-2015-8558. + +Cc: qemu-stable@nongnu.org +Reported-by: Qinghao Tang +Tested-by: P J P +Signed-off-by: Gerd Hoffmann +--- + hw/usb/hcd-ehci.c | 5 +++-- + 1 files changed, 3 insertions(+), 2 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/usb/hcd-ehci.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/usb/hcd-ehci.c 2016-02-02 07:26:12.594521158 -0500 ++++ qemu-2.0.0+dfsg/hw/usb/hcd-ehci.c 2016-02-02 07:26:12.590521116 -0500 +@@ -1472,7 +1472,7 @@ + { + USBDevice *dev; + USBEndpoint *ep; +- uint32_t i, len, pid, dir, devaddr, endp; ++ uint32_t i, len, pid, dir, devaddr, endp, xfers = 0; + uint32_t pg, off, ptr1, ptr2, max, mult; + + ehci->periodic_sched_active = PERIODIC_ACTIVE; +@@ -1562,9 +1562,10 @@ + ehci_raise_irq(ehci, USBSTS_INT); + } + itd->transact[i] &= ~ITD_XACT_ACTIVE; ++ xfers++; + } + } +- return 0; ++ return xfers ? 0 : -1; + } + + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-856x.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-856x.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-856x.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-856x.patch 2016-02-02 12:27:35.000000000 +0000 @@ -0,0 +1,92 @@ +Backport of: + +From aa4a3dce1c88ed51b616806b8214b7c8428b7470 Mon Sep 17 00:00:00 2001 +From: P J P +Date: Tue, 15 Dec 2015 12:27:54 +0530 +Subject: [PATCH] net: vmxnet3: avoid memory leakage in activate_device + +Vmxnet3 device emulator does not check if the device is active +before activating it, also it did not free the transmit & receive +buffers while deactivating the device, thus resulting in memory +leakage on the host. This patch fixes both these issues to avoid +host memory leakage. + +Reported-by: Qinghao Tang +Reviewed-by: Dmitry Fleytman +Signed-off-by: Prasad J Pandit +Cc: qemu-stable@nongnu.org +Signed-off-by: Jason Wang +--- + hw/net/vmxnet3.c | 24 ++++++++++++++++-------- + 1 files changed, 16 insertions(+), 8 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/vmxnet3.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/vmxnet3.c 2016-02-02 07:26:27.046672730 -0500 ++++ qemu-2.0.0+dfsg/hw/net/vmxnet3.c 2016-02-02 07:27:00.611024701 -0500 +@@ -1134,8 +1134,13 @@ + + static void vmxnet3_deactivate_device(VMXNET3State *s) + { +- VMW_CBPRN("Deactivating vmxnet3..."); +- s->device_active = false; ++ if (s->device_active) { ++ VMW_CBPRN("Deactivating vmxnet3..."); ++ vmxnet_tx_pkt_reset(s->tx_pkt); ++ vmxnet_tx_pkt_uninit(s->tx_pkt); ++ vmxnet_rx_pkt_uninit(s->rx_pkt); ++ s->device_active = false; ++ } + } + + static void vmxnet3_reset(VMXNET3State *s) +@@ -1144,7 +1149,6 @@ + + vmxnet3_deactivate_device(s); + vmxnet3_reset_interrupt_states(s); +- vmxnet_tx_pkt_reset(s->tx_pkt); + s->drv_shmem = 0; + s->tx_sop = true; + s->skip_current_tx_pkt = false; +@@ -1367,6 +1371,12 @@ + return; + } + ++ /* Verify if device is active */ ++ if (s->device_active) { ++ VMW_CFPRN("Vmxnet3 device is active"); ++ return; ++ } ++ + vmxnet3_adjust_by_guest_type(s); + vmxnet3_update_features(s); + vmxnet3_update_pm_state(s); +@@ -1563,7 +1573,7 @@ + break; + + case VMXNET3_CMD_QUIESCE_DEV: +- VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - pause the device"); ++ VMW_CBPRN("Set: VMXNET3_CMD_QUIESCE_DEV - deactivate the device"); + vmxnet3_deactivate_device(s); + break; + +@@ -1668,7 +1678,7 @@ + * shared address only after we get the high part + */ + if (0 == val) { +- s->device_active = false; ++ vmxnet3_deactivate_device(s); + } + s->temp_shared_guest_driver_memory = val; + s->drv_shmem = 0; +@@ -1946,9 +1956,7 @@ + static void vmxnet3_net_uninit(VMXNET3State *s) + { + g_free(s->mcast_list); +- vmxnet_tx_pkt_reset(s->tx_pkt); +- vmxnet_tx_pkt_uninit(s->tx_pkt); +- vmxnet_rx_pkt_uninit(s->rx_pkt); ++ vmxnet3_deactivate_device(s); + qemu_del_nic(s->nic); + } + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8613.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-8613.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8613.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-8613.patch 2016-02-02 12:27:51.000000000 +0000 @@ -0,0 +1,32 @@ +From 36fef36b91f7ec0435215860f1458b5342ce2811 Mon Sep 17 00:00:00 2001 +From: P J P +Date: Mon, 21 Dec 2015 15:13:13 +0530 +Subject: [PATCH] scsi: initialise info object with appropriate size + +While processing controller 'CTRL_GET_INFO' command, the routine +'megasas_ctrl_get_info' overflows the '&info' object size. Use its +appropriate size to null initialise it. + +Reported-by: Qinghao Tang +Signed-off-by: Prasad J Pandit +Message-Id: +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +Signed-off-by: P J P +--- + hw/scsi/megasas.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/scsi/megasas.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/scsi/megasas.c 2016-02-02 07:27:49.395536163 -0500 ++++ qemu-2.0.0+dfsg/hw/scsi/megasas.c 2016-02-02 07:27:49.391536121 -0500 +@@ -676,7 +676,7 @@ + int num_ld_disks = 0; + uint16_t sdev_id; + +- memset(&info, 0x0, cmd->iov_size); ++ memset(&info, 0x0, dcmd_size); + if (cmd->iov_size < dcmd_size) { + trace_megasas_dcmd_invalid_xfer_len(cmd->index, cmd->iov_size, + dcmd_size); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8619.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-8619.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8619.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-8619.patch 2016-02-02 12:28:40.000000000 +0000 @@ -0,0 +1,118 @@ +From b5d69f04c7c5223f4b72f1ccdc461c037cafd1ca Mon Sep 17 00:00:00 2001 +From: Wolfgang Bumiller +Date: Wed, 13 Jan 2016 09:09:58 +0100 +Subject: [PATCH] hmp: fix sendkey out of bounds write (CVE-2015-8619) + +When processing 'sendkey' command, hmp_sendkey routine null +terminates the 'keyname_buf' array. This results in an OOB +write issue, if 'keyname_len' was to fall outside of +'keyname_buf' array. + +Since the keyname's length is known the keyname_buf can be +removed altogether by adding a length parameter to +index_from_key() and using it for the error output as well. + +Reported-by: Ling Liu +Signed-off-by: Wolfgang Bumiller +Message-Id: <20160113080958.GA18934@olga> +[Comparison with "<" dumbed down, test for junk after strtoul() +tweaked] +Signed-off-by: Markus Armbruster +--- + hmp.c | 18 ++++++++---------- + include/ui/console.h | 2 +- + ui/input-legacy.c | 5 +++-- + 3 files changed, 12 insertions(+), 13 deletions(-) + +Index: qemu-2.0.0+dfsg/hmp.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hmp.c 2016-02-02 07:28:38.200047697 -0500 ++++ qemu-2.0.0+dfsg/hmp.c 2016-02-02 07:28:38.192047613 -0500 +@@ -1443,21 +1443,18 @@ + int has_hold_time = qdict_haskey(qdict, "hold-time"); + int hold_time = qdict_get_try_int(qdict, "hold-time", -1); + Error *err = NULL; +- char keyname_buf[16]; + char *separator; + int keyname_len; + + while (1) { + separator = strchr(keys, '-'); + keyname_len = separator ? separator - keys : strlen(keys); +- pstrcpy(keyname_buf, sizeof(keyname_buf), keys); + + /* Be compatible with old interface, convert user inputted "<" */ +- if (!strncmp(keyname_buf, "<", 1) && keyname_len == 1) { +- pstrcpy(keyname_buf, sizeof(keyname_buf), "less"); ++ if (keys[0] == '<' && keyname_len == 1) { ++ keys = "less"; + keyname_len = 4; + } +- keyname_buf[keyname_len] = 0; + + keylist = g_malloc0(sizeof(*keylist)); + keylist->value = g_malloc0(sizeof(*keylist->value)); +@@ -1470,16 +1467,17 @@ + } + tmp = keylist; + +- if (strstart(keyname_buf, "0x", NULL)) { ++ if (strstart(keys, "0x", NULL)) { + char *endp; +- int value = strtoul(keyname_buf, &endp, 0); +- if (*endp != '\0') { ++ int value = strtoul(keys, &endp, 0); ++ assert(endp <= keys + keyname_len); ++ if (endp != keys + keyname_len) { + goto err_out; + } + keylist->value->kind = KEY_VALUE_KIND_NUMBER; + keylist->value->number = value; + } else { +- int idx = index_from_key(keyname_buf); ++ int idx = index_from_key(keys, keyname_len); + if (idx == Q_KEY_CODE_MAX) { + goto err_out; + } +@@ -1501,7 +1499,7 @@ + return; + + err_out: +- monitor_printf(mon, "invalid parameter: %s\n", keyname_buf); ++ monitor_printf(mon, "invalid parameter: %.*s\n", keyname_len, keys); + goto out; + } + +Index: qemu-2.0.0+dfsg/include/ui/console.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/include/ui/console.h 2016-02-02 07:28:38.200047697 -0500 ++++ qemu-2.0.0+dfsg/include/ui/console.h 2016-02-02 07:28:38.192047613 -0500 +@@ -341,7 +341,7 @@ + void curses_display_init(DisplayState *ds, int full_screen); + + /* input.c */ +-int index_from_key(const char *key); ++int index_from_key(const char *key, size_t key_length); + + /* gtk.c */ + void early_gtk_display_init(void); +Index: qemu-2.0.0+dfsg/ui/input-legacy.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/ui/input-legacy.c 2016-02-02 07:28:38.200047697 -0500 ++++ qemu-2.0.0+dfsg/ui/input-legacy.c 2016-02-02 07:28:38.196047655 -0500 +@@ -206,12 +206,13 @@ + [Q_KEY_CODE_MAX] = 0, + }; + +-int index_from_key(const char *key) ++int index_from_key(const char *key, size_t key_length) + { + int i; + + for (i = 0; QKeyCode_lookup[i] != NULL; i++) { +- if (!strcmp(key, QKeyCode_lookup[i])) { ++ if (!strncmp(key, QKeyCode_lookup[i], key_length) && ++ !QKeyCode_lookup[i][key_length]) { + break; + } + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8666.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-8666.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8666.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-8666.patch 2016-02-02 12:29:14.000000000 +0000 @@ -0,0 +1,42 @@ +From d9a3b33d2c9f996537b7f1d0246dee2d0120cefb Mon Sep 17 00:00:00 2001 +From: Michael S. Tsirkin +Date: Thu, 19 Nov 2015 15:14:07 +0200 +Subject: [PATCH] acpi: fix buffer overrun on migration + +ich calls acpi_gpe_init with length ICH9_PMIO_GPE0_LEN so +ICH9_PMIO_GPE0_LEN/2 bytes are allocated, but then the full +ICH9_PMIO_GPE0_LEN bytes are migrated. + +As a quick work-around, allocate twice the memory. +We'll probably want to tweak code to avoid +migrating the extra ICH9_PMIO_GPE0_LEN/2 bytes, +but that is a bit trickier to do without breaking +migration compatibility. + +Tested-by: "Dr. David Alan Gilbert" +Reported-by: "Dr. David Alan Gilbert" +Cc: qemu-stable@nongnu.org +Signed-off-by: Michael S. Tsirkin +--- + hw/acpi/core.c | 8 ++++++-- + 1 files changed, 6 insertions(+), 2 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/acpi/core.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/acpi/core.c 2016-02-02 07:29:11.904400883 -0500 ++++ qemu-2.0.0+dfsg/hw/acpi/core.c 2016-02-02 07:29:11.900400841 -0500 +@@ -608,8 +608,12 @@ + void acpi_gpe_init(ACPIREGS *ar, uint8_t len) + { + ar->gpe.len = len; +- ar->gpe.sts = g_malloc0(len / 2); +- ar->gpe.en = g_malloc0(len / 2); ++ /* Only first len / 2 bytes are ever used, ++ * but the caller in ich9.c migrates full len bytes. ++ * TODO: fix ich9.c and drop the extra allocation. ++ */ ++ ar->gpe.sts = g_malloc0(len); ++ ar->gpe.en = g_malloc0(len); + } + + void acpi_gpe_reset(ACPIREGS *ar) diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8743.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-8743.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8743.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-8743.patch 2016-02-02 12:29:24.000000000 +0000 @@ -0,0 +1,45 @@ +From aa7f9966dfdff500bbbf1956d9e115b1fa8987a6 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Thu, 31 Dec 2015 17:05:27 +0530 +Subject: [PATCH] net: ne2000: fix bounds check in ioport operations + +While doing ioport r/w operations, ne2000 device emulation suffers +from OOB r/w errors. Update respective array bounds check to avoid +OOB access. + +Reported-by: Ling Liu +Cc: qemu-stable@nongnu.org +Signed-off-by: Prasad J Pandit +Signed-off-by: Jason Wang +--- + hw/net/ne2000.c | 10 ++++++---- + 1 files changed, 6 insertions(+), 4 deletions(-) + +Index: qemu-2.3+dfsg/hw/net/ne2000.c +=================================================================== +--- qemu-2.3+dfsg.orig/hw/net/ne2000.c 2016-02-01 15:25:32.763667437 -0500 ++++ qemu-2.3+dfsg/hw/net/ne2000.c 2016-02-01 15:25:32.759667384 -0500 +@@ -476,8 +476,9 @@ + uint32_t val) + { + addr &= ~1; /* XXX: check exact behaviour if not even */ +- if (addr < 32 || +- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { ++ if (addr < 32 ++ || (addr >= NE2000_PMEM_START ++ && addr + sizeof(uint32_t) <= NE2000_MEM_SIZE)) { + stl_le_p(s->mem + addr, val); + } + } +@@ -506,8 +507,9 @@ + static inline uint32_t ne2000_mem_readl(NE2000State *s, uint32_t addr) + { + addr &= ~1; /* XXX: check exact behaviour if not even */ +- if (addr < 32 || +- (addr >= NE2000_PMEM_START && addr < NE2000_MEM_SIZE)) { ++ if (addr < 32 ++ || (addr >= NE2000_PMEM_START ++ && addr + sizeof(uint32_t) <= NE2000_MEM_SIZE)) { + return ldl_le_p(s->mem + addr); + } else { + return 0xffffffff; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8744.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-8744.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8744.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-8744.patch 2016-02-02 12:29:35.000000000 +0000 @@ -0,0 +1,73 @@ +From a7278b36fcab9af469563bd7b9dadebe2ae25e48 Mon Sep 17 00:00:00 2001 +From: Dana Rubin +Date: Tue, 18 Aug 2015 12:45:55 +0300 +Subject: [PATCH] net/vmxnet3: Refine l2 header validation + +Validation of l2 header length assumed minimal packet size as +eth_header + 2 * vlan_header regardless of the actual protocol. + +This caused crash for valid non-IP packets shorter than 22 bytes, as +'tx_pkt->packet_type' hasn't been assigned for such packets, and +'vmxnet3_on_tx_done_update_stats()' expects it to be properly set. + +Refine header length validation in 'vmxnet_tx_pkt_parse_headers'. +Check its return value during packet processing flow. + +As a side effect, in case IPv4 and IPv6 header validation failure, +corrupt packets will be dropped. + +Signed-off-by: Dana Rubin +Signed-off-by: Shmulik Ladkani +Signed-off-by: Jason Wang +--- + hw/net/vmxnet3.c | 4 +--- + hw/net/vmxnet_tx_pkt.c | 19 ++++++++++++++++--- + 2 files changed, 17 insertions(+), 6 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/vmxnet3.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/vmxnet3.c 2016-02-02 07:29:31.572606956 -0500 ++++ qemu-2.0.0+dfsg/hw/net/vmxnet3.c 2016-02-02 07:29:31.568606914 -0500 +@@ -728,9 +728,7 @@ + } + + if (txd.eop) { +- if (!s->skip_current_tx_pkt) { +- vmxnet_tx_pkt_parse(s->tx_pkt); +- ++ if (!s->skip_current_tx_pkt && vmxnet_tx_pkt_parse(s->tx_pkt)) { + if (s->needs_vlan) { + vmxnet_tx_pkt_setup_vlan_header(s->tx_pkt, s->tci); + } +Index: qemu-2.0.0+dfsg/hw/net/vmxnet_tx_pkt.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/vmxnet_tx_pkt.c 2016-02-02 07:29:31.572606956 -0500 ++++ qemu-2.0.0+dfsg/hw/net/vmxnet_tx_pkt.c 2016-02-02 07:29:31.568606914 -0500 +@@ -142,11 +142,24 @@ + + bytes_read = iov_to_buf(pkt->raw, pkt->raw_frags, 0, l2_hdr->iov_base, + ETH_MAX_L2_HDR_LEN); +- if (bytes_read < ETH_MAX_L2_HDR_LEN) { ++ if (bytes_read < sizeof(struct eth_header)) { ++ l2_hdr->iov_len = 0; ++ return false; ++ } ++ ++ l2_hdr->iov_len = sizeof(struct eth_header); ++ switch (be16_to_cpu(PKT_GET_ETH_HDR(l2_hdr->iov_base)->h_proto)) { ++ case ETH_P_VLAN: ++ l2_hdr->iov_len += sizeof(struct vlan_header); ++ break; ++ case ETH_P_DVLAN: ++ l2_hdr->iov_len += 2 * sizeof(struct vlan_header); ++ break; ++ } ++ ++ if (bytes_read < l2_hdr->iov_len) { + l2_hdr->iov_len = 0; + return false; +- } else { +- l2_hdr->iov_len = eth_get_l2_hdr_length(l2_hdr->iov_base); + } + + l3_proto = eth_get_l3_proto(l2_hdr->iov_base, l2_hdr->iov_len); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8745.patch qemu-2.0.0+dfsg/debian/patches/CVE-2015-8745.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2015-8745.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2015-8745.patch 2016-02-02 12:29:44.000000000 +0000 @@ -0,0 +1,34 @@ +From c6048f849c7e3f009786df76206e895a69de032c Mon Sep 17 00:00:00 2001 +From: Shmulik Ladkani +Date: Mon, 21 Sep 2015 17:09:02 +0300 +Subject: [PATCH] vmxnet3: Support reading IMR registers on bar0 + +Instead of asserting, return the actual IMR register value. +This is aligned with what's returned on ESXi. + +Signed-off-by: Shmulik Ladkani +Tested-by: Dana Rubin +Signed-off-by: Jason Wang +--- + hw/net/vmxnet3.c | 6 +++++- + 1 files changed, 5 insertions(+), 1 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/vmxnet3.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/vmxnet3.c 2016-02-02 07:29:41.592711932 -0500 ++++ qemu-2.0.0+dfsg/hw/net/vmxnet3.c 2016-02-02 07:29:41.588711890 -0500 +@@ -1105,9 +1105,13 @@ + static uint64_t + vmxnet3_io_bar0_read(void *opaque, hwaddr addr, unsigned size) + { ++ VMXNET3State *s = opaque; ++ + if (VMW_IS_MULTIREG_ADDR(addr, VMXNET3_REG_IMR, + VMXNET3_MAX_INTRS, VMXNET3_REG_ALIGN)) { +- g_assert_not_reached(); ++ int l = VMW_MULTIREG_IDX_BY_ADDR(addr, VMXNET3_REG_IMR, ++ VMXNET3_REG_ALIGN); ++ return s->interrupt_states[l].is_masked; + } + + VMW_CBPRN("BAR0 unknown read [%" PRIx64 "], size %d", addr, size); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-10155.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-10155.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-10155.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-10155.patch 2017-04-06 13:53:08.000000000 +0000 @@ -0,0 +1,31 @@ +Backport of: + +From eb7a20a3616085d46aa6b4b4224e15587ec67e6e Mon Sep 17 00:00:00 2001 +From: Li Qiang +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 +Message-Id: <583cde9c.3223ed0a.7f0c2.886e@mx.google.com> +Signed-off-by: Paolo Bonzini +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-1568.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-1568.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-1568.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-1568.patch 2016-02-02 12:30:35.000000000 +0000 @@ -0,0 +1,38 @@ +Backport of: + +From 4ab0359a8ae182a7ac5c99609667273167703fab Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Mon, 11 Jan 2016 14:10:42 -0500 +Subject: [PATCH] ide: ahci: reset ncq object to unused on error + +When processing NCQ commands, AHCI device emulation prepares a +NCQ transfer object; To which an aio control block(aiocb) object +is assigned in 'execute_ncq_command'. In case, when the NCQ +command is invalid, the 'aiocb' object is not assigned, and NCQ +transfer object is left as 'used'. This leads to a use after +free kind of error in 'bdrv_aio_cancel_async' via 'ahci_reset_port'. +Reset NCQ transfer object to 'unused' to avoid it. + +[Maintainer edit: s/ACHI/AHCI/ in the commit message. --js] + +Reported-by: Qinghao Tang +Signed-off-by: Prasad J Pandit +Reviewed-by: John Snow +Message-id: 1452282511-4116-1-git-send-email-ppandit@redhat.com +Signed-off-by: John Snow +--- + hw/ide/ahci.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/ide/ahci.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/ide/ahci.c 2016-02-02 07:29:56.668869869 -0500 ++++ qemu-2.0.0+dfsg/hw/ide/ahci.c 2016-02-02 07:30:26.677184196 -0500 +@@ -826,6 +826,7 @@ + default: + DPRINTF(port, "error: tried to process non-NCQ command as NCQ\n"); + qemu_sglist_destroy(&ncq_tfs->sglist); ++ ncq_tfs->used = 0; + break; + } + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-1714.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-1714.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-1714.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-1714.patch 2016-02-02 12:30:56.000000000 +0000 @@ -0,0 +1,94 @@ +From 5d12c17191e042a57e02749cedc55104a8251ac3 Mon Sep 17 00:00:00 2001 +From: Miroslav Rezanina +Date: Thu, 21 Jan 2016 07:17:43 +0100 +Subject: [PATCH] fw_cfg: add check to validate current entry value + (CVE-2016-1714) +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Message-id: <1453360663-5066-1-git-send-email-mrezanin@redhat.com> +Patchwork-id: 68834 +O-Subject: [RHEL-7.2.z/RHEL-7.3 qemu-kvm PATCH] fw_cfg: add check to validate current entry value (CVE-2016-1714) +Bugzilla: 1298047 +RH-Acked-by: Laurent Vivier +RH-Acked-by: Laszlo Ersek +RH-Acked-by: Gerd Hoffmann + +From: Prasad J Pandit + +When processing firmware configurations, an OOB r/w access occurs +if 's->cur_entry' is set to be invalid(FW_CFG_INVALID=0xffff). +Add a check to validate 's->cur_entry' to avoid such access. + +This patch is based on upstream commit 66f8fd9dda312191b78d2a2ba2848bcee76127a2 + Author: Gabriel L. Somlo + Date: Thu Nov 5 09:32:50 2015 -0500 + + fw_cfg: avoid calculating invalid current entry pointer + + When calculating a pointer to the currently selected fw_cfg item, the + following is used: + + FWCfgEntry *e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK]; + + When s->cur_entry is FW_CFG_INVALID, we are calculating the address of + a non-existent element in s->entries[arch][...], which is undefined. + + This patch ensures the resulting entry pointer is set to NULL whenever + s->cur_entry is FW_CFG_INVALID. + + Reported-by: Laszlo Ersek + Reviewed-by: Laszlo Ersek + Signed-off-by: Gabriel Somlo + Message-id: 1446733972-1602-5-git-send-email-somlo@cmu.edu + Cc: Marc Marí + Signed-off-by: Gabriel Somlo + Reviewed-by: Laszlo Ersek + Signed-off-by: Gerd Hoffmann + +with added chunk for fw_cfg_write() that was removed in commit +023e3148567ac898c7258138f8e86c3c2bb40d07 +and missing chunk for fw_cfg_dma_transfer that was added in commit +a4c0d1deb785611c96a455f65ec032976b00b36f. + +Reported-by: Donghai Zdh +Signed-off-by: Prasad J Pandit +Signed-off-by: Miroslav Rezanina +--- + hw/nvram/fw_cfg.c | 12 ++++++++---- + 1 file changed, 8 insertions(+), 4 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/nvram/fw_cfg.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/nvram/fw_cfg.c 2016-02-02 07:30:53.533465464 -0500 ++++ qemu-2.0.0+dfsg/hw/nvram/fw_cfg.c 2016-02-02 07:30:53.529465422 -0500 +@@ -211,12 +211,15 @@ + static void fw_cfg_write(FWCfgState *s, uint8_t value) + { + int arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL); +- FWCfgEntry *e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK]; ++ FWCfgEntry *e = (s->cur_entry == FW_CFG_INVALID) ? NULL : ++ &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK]; + + trace_fw_cfg_write(s, value); + +- if (s->cur_entry & FW_CFG_WRITE_CHANNEL && e->callback && +- s->cur_offset < e->len) { ++ if (s->cur_entry & FW_CFG_WRITE_CHANNEL ++ && e != NULL ++ && e->callback ++ && s->cur_offset < e->len) { + e->data[s->cur_offset++] = value; + if (s->cur_offset == e->len) { + e->callback(e->callback_opaque, e->data); +@@ -245,7 +248,8 @@ + static uint8_t fw_cfg_read(FWCfgState *s) + { + int arch = !!(s->cur_entry & FW_CFG_ARCH_LOCAL); +- FWCfgEntry *e = &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK]; ++ FWCfgEntry *e = (s->cur_entry == FW_CFG_INVALID) ? NULL : ++ &s->entries[arch][s->cur_entry & FW_CFG_ENTRY_MASK]; + uint8_t ret; + + if (s->cur_entry == FW_CFG_INVALID || !e->data || s->cur_offset >= e->len) diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-1922.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-1922.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-1922.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-1922.patch 2016-02-02 12:31:07.000000000 +0000 @@ -0,0 +1,62 @@ +From 4c1396cb576c9b14425558b73de1584c7a9735d7 Mon Sep 17 00:00:00 2001 +From: P J P +Date: Fri, 18 Dec 2015 11:35:07 +0530 +Subject: [PATCH] i386: avoid null pointer dereference + + Hello, + +A null pointer dereference issue was reported by Mr Ling Liu, CC'd here. It +occurs while doing I/O port write operations via hmp interface. In that, +'current_cpu' remains null as it is not called from cpu_exec loop, which +results in the said issue. + +Below is a proposed (tested)patch to fix this issue; Does it look okay? + +=== +From ae88a4947fab9a148cd794f8ad2d812e7f5a1d0f Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Fri, 18 Dec 2015 11:16:07 +0530 +Subject: [PATCH] i386: avoid null pointer dereference + +When I/O port write operation is called from hmp interface, +'current_cpu' remains null, as it is not called from cpu_exec() +loop. This leads to a null pointer dereference in vapic_write +routine. Add check to avoid it. + +Reported-by: Ling Liu +Signed-off-by: Prasad J Pandit +Message-Id: +Signed-off-by: Paolo Bonzini +Signed-off-by: P J P +--- + hw/i386/kvmvapic.c | 15 ++++++++++----- + 1 files changed, 10 insertions(+), 5 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/i386/kvmvapic.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/i386/kvmvapic.c 2016-02-02 07:31:04.809586034 -0500 ++++ qemu-2.0.0+dfsg/hw/i386/kvmvapic.c 2016-02-02 07:31:04.805585991 -0500 +@@ -637,13 +637,18 @@ + static void vapic_write(void *opaque, hwaddr addr, uint64_t data, + unsigned int size) + { +- CPUState *cs = current_cpu; +- X86CPU *cpu = X86_CPU(cs); +- CPUX86State *env = &cpu->env; +- hwaddr rom_paddr; + VAPICROMState *s = opaque; ++ X86CPU *cpu; ++ CPUX86State *env; ++ hwaddr rom_paddr; ++ ++ if (!current_cpu) { ++ return; ++ } + +- cpu_synchronize_state(cs); ++ cpu_synchronize_state(current_cpu); ++ cpu = X86_CPU(current_cpu); ++ env = &cpu->env; + + /* + * The VAPIC supports two PIO-based hypercalls, both via port 0x7E. diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-1981.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-1981.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-1981.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-1981.patch 2016-02-02 12:31:13.000000000 +0000 @@ -0,0 +1,27 @@ +Description: eliminate infinite loops on out-of-bounds transfer start +Origin: other, https://lists.gnu.org/archive/html/qemu-devel/2016-01/msg03454.html + +Index: qemu-2.0.0+dfsg/hw/net/e1000.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/e1000.c 2016-02-02 07:31:11.641660063 -0500 ++++ qemu-2.0.0+dfsg/hw/net/e1000.c 2016-02-02 07:31:11.637660021 -0500 +@@ -786,7 +786,8 @@ + * bogus values to TDT/TDLEN. + * there's nothing too intelligent we could do about this. + */ +- if (s->mac_reg[TDH] == tdh_start) { ++ if (s->mac_reg[TDH] == tdh_start || ++ tdh_start >= s->mac_reg[TDLEN] / sizeof(desc)) { + DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n", + tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]); + break; +@@ -1023,7 +1024,8 @@ + if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN]) + s->mac_reg[RDH] = 0; + /* see comment in start_xmit; same here */ +- if (s->mac_reg[RDH] == rdh_start) { ++ if (s->mac_reg[RDH] == rdh_start || ++ rdh_start >= s->mac_reg[RDLEN] / sizeof(desc)) { + DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n", + rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]); + set_ics(s, 0, E1000_ICS_RXO); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-2198.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-2198.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-2198.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-2198.patch 2016-02-02 12:32:26.000000000 +0000 @@ -0,0 +1,27 @@ +Description: add capability mmio write function +Origin: other, https://lists.gnu.org/archive/html/qemu-devel/2016-01/msg05899.html + +Index: qemu-2.0.0+dfsg/hw/usb/hcd-ehci.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/usb/hcd-ehci.c 2016-02-02 07:32:23.894442564 -0500 ++++ qemu-2.0.0+dfsg/hw/usb/hcd-ehci.c 2016-02-02 07:32:23.890442521 -0500 +@@ -976,6 +976,11 @@ + 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) + { +@@ -2394,6 +2399,7 @@ + + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-2391.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-2391.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-2391.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-2391.patch 2016-05-10 18:40:53.000000000 +0000 @@ -0,0 +1,36 @@ +Backport of: + +From: Prasad J Pandit + +When transitioning an OHCI controller to the OHCI_USB_OPERATIONAL +state, it creates an eof timer object in 'ohci_bus_start'. +It does not check if one already exists. This results in memory +leakage and null dereference issue. Add a check to avoid it. + +Reported-by: Zuozhi Fzz +Signed-off-by: Prasad J Pandit +--- + hw/usb/hcd-ohci.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/usb/hcd-ohci.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/usb/hcd-ohci.c 2016-05-10 14:39:10.846642571 -0400 ++++ qemu-2.0.0+dfsg/hw/usb/hcd-ohci.c 2016-05-10 14:40:17.947474551 -0400 +@@ -1351,11 +1351,11 @@ + */ + static int ohci_bus_start(OHCIState *ohci) + { +- ohci->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, +- ohci_frame_boundary, +- ohci); +- +- if (ohci->eof_timer == NULL) { ++ if (!ohci->eof_timer) { ++ ohci->eof_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, ++ ohci_frame_boundary, ohci); ++ } ++ if (!ohci->eof_timer) { + fprintf(stderr, "usb-ohci: %s: timer_new_ns failed\n", ohci->name); + ohci_die(ohci); + return 0; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-2392.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-2392.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-2392.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-2392.patch 2016-05-10 18:48:51.000000000 +0000 @@ -0,0 +1,32 @@ +From 80eecda8e5d09c442c24307f340840a5b70ea3b9 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Thu, 11 Feb 2016 16:31:20 +0530 +Subject: [PATCH] usb: check USB configuration descriptor object + +When processing remote NDIS control message packets, the USB Net +device emulator checks to see if the USB configuration descriptor +object is of RNDIS type(2). But it does not check if it is null, +which leads to a null dereference error. Add check to avoid it. + +Reported-by: Qinghao Tang +Signed-off-by: Prasad J Pandit +Message-id: 1455188480-14688-1-git-send-email-ppandit@redhat.com +Signed-off-by: Gerd Hoffmann +--- + hw/usb/dev-network.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +Index: qemu-2.3+dfsg/hw/usb/dev-network.c +=================================================================== +--- qemu-2.3+dfsg.orig/hw/usb/dev-network.c 2016-05-10 14:21:30.021388570 -0400 ++++ qemu-2.3+dfsg/hw/usb/dev-network.c 2016-05-10 14:21:30.017388519 -0400 +@@ -650,7 +650,8 @@ + + static int is_rndis(USBNetState *s) + { +- return s->dev.config->bConfigurationValue == DEV_RNDIS_CONFIG_VALUE; ++ return s->dev.config ? ++ s->dev.config->bConfigurationValue == DEV_RNDIS_CONFIG_VALUE : 0; + } + + static int ndis_query(USBNetState *s, uint32_t oid, diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-2538.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-2538.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-2538.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-2538.patch 2016-05-10 18:48:59.000000000 +0000 @@ -0,0 +1,56 @@ +From fe3c546c5ff2a6210f9a4d8561cc64051ca8603e Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Wed, 17 Feb 2016 00:23:41 +0530 +Subject: [PATCH] usb: check RNDIS buffer offsets & length + +When processing remote NDIS control message packets, +the USB Net device emulator uses a fixed length(4096) data buffer. +The incoming informationBufferOffset & Length combination could +overflow and cross that range. Check control message buffer +offsets and length to avoid it. + +Reported-by: Qinghao Tang +Signed-off-by: Prasad J Pandit +Message-id: 1455648821-17340-3-git-send-email-ppandit@redhat.com +Signed-off-by: Gerd Hoffmann +--- + hw/usb/dev-network.c | 9 ++++++--- + 1 files changed, 6 insertions(+), 3 deletions(-) + +Index: qemu-2.3+dfsg/hw/usb/dev-network.c +=================================================================== +--- qemu-2.3+dfsg.orig/hw/usb/dev-network.c 2016-05-10 14:21:40.481520369 -0400 ++++ qemu-2.3+dfsg/hw/usb/dev-network.c 2016-05-10 14:21:40.477520319 -0400 +@@ -912,8 +912,9 @@ + + bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8; + buflen = le32_to_cpu(buf->InformationBufferLength); +- if (bufoffs + buflen > length) ++ if (buflen > length || bufoffs >= length || bufoffs + buflen > length) { + return USB_RET_STALL; ++ } + + infobuflen = ndis_query(s, le32_to_cpu(buf->OID), + bufoffs + (uint8_t *) buf, buflen, infobuf, +@@ -958,8 +959,9 @@ + + bufoffs = le32_to_cpu(buf->InformationBufferOffset) + 8; + buflen = le32_to_cpu(buf->InformationBufferLength); +- if (bufoffs + buflen > length) ++ if (buflen > length || bufoffs >= length || bufoffs + buflen > length) { + return USB_RET_STALL; ++ } + + ret = ndis_set(s, le32_to_cpu(buf->OID), + bufoffs + (uint8_t *) buf, buflen); +@@ -1209,8 +1211,9 @@ + if (le32_to_cpu(msg->MessageType) == RNDIS_PACKET_MSG) { + uint32_t offs = 8 + le32_to_cpu(msg->DataOffset); + uint32_t size = le32_to_cpu(msg->DataLength); +- if (offs + size <= len) ++ if (offs < len && size < len && offs + size <= len) { + qemu_send_packet(qemu_get_queue(s->nic), s->out_buf + offs, size); ++ } + } + s->out_ptr -= len; + memmove(s->out_buf, &s->out_buf[len], s->out_ptr); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-2841.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-2841.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-2841.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-2841.patch 2016-05-10 18:49:09.000000000 +0000 @@ -0,0 +1,34 @@ +From 415ab35a441eca767d033a2702223e785b9d5190 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Wed, 24 Feb 2016 11:41:33 +0530 +Subject: [PATCH] net: ne2000: check ring buffer control registers + +Ne2000 NIC uses ring buffer of NE2000_MEM_SIZE(49152) +bytes to process network packets. Registers PSTART & PSTOP +define ring buffer size & location. Setting these registers +to invalid values could lead to infinite loop or OOB r/w +access issues. Add check to avoid it. + +Reported-by: Yang Hongke +Tested-by: Yang Hongke +Signed-off-by: Prasad J Pandit +Signed-off-by: Jason Wang +--- + hw/net/ne2000.c | 4 ++++ + 1 files changed, 4 insertions(+), 0 deletions(-) + +Index: qemu-2.5+dfsg/hw/net/ne2000.c +=================================================================== +--- qemu-2.5+dfsg.orig/hw/net/ne2000.c 2016-05-10 12:54:04.004399892 -0400 ++++ qemu-2.5+dfsg/hw/net/ne2000.c 2016-05-10 12:54:04.000399857 -0400 +@@ -154,6 +154,10 @@ + { + int avail, index, boundary; + ++ if (s->stop <= s->start) { ++ return 1; ++ } ++ + index = s->curpag << 8; + boundary = s->boundary << 8; + if (index < boundary) diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-2857.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-2857.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-2857.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-2857.patch 2016-05-10 18:49:16.000000000 +0000 @@ -0,0 +1,44 @@ +From 362786f14a753d8a5256ef97d7c10ed576d6572b Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Wed, 2 Mar 2016 17:29:58 +0530 +Subject: [PATCH] net: check packet payload length + +While computing IP checksum, 'net_checksum_calculate' reads +payload length from the packet. It could exceed the given 'data' +buffer size. Add a check to avoid it. + +Reported-by: Liu Ling +Signed-off-by: Prasad J Pandit +Signed-off-by: Jason Wang +--- + net/checksum.c | 10 ++++++++-- + 1 files changed, 8 insertions(+), 2 deletions(-) + +Index: qemu-2.5+dfsg/net/checksum.c +=================================================================== +--- qemu-2.5+dfsg.orig/net/checksum.c 2016-05-10 12:54:14.280491190 -0400 ++++ qemu-2.5+dfsg/net/checksum.c 2016-05-10 12:54:14.280491190 -0400 +@@ -59,6 +59,11 @@ + int hlen, plen, proto, csum_offset; + uint16_t csum; + ++ /* Ensure data has complete L2 & L3 headers. */ ++ if (length < 14 + 20) { ++ return; ++ } ++ + if ((data[14] & 0xf0) != 0x40) + return; /* not IPv4 */ + hlen = (data[14] & 0x0f) * 4; +@@ -76,8 +81,9 @@ + return; + } + +- if (plen < csum_offset+2) +- return; ++ if (plen < csum_offset + 2 || 14 + hlen + plen > length) { ++ return; ++ } + + data[14+hlen+csum_offset] = 0; + data[14+hlen+csum_offset+1] = 0; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-2858.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-2858.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-2858.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-2858.patch 2016-05-10 18:49:39.000000000 +0000 @@ -0,0 +1,372 @@ +Description: fix denial of service in PRNG support +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=3c52ddcdc548e7fbe65112d8a7bdc9cd105b4750 +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=74074e8a7c60592cf1cc6469dbc2550d24aeded3 +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=9f14b0add1dcdbfa2ee61051d068211fb0a1fcc9 +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=60253ed1e6ec6d8e5ef2efe7bf755f475dce9956 +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=443590c2044968a97f5e7cddd35100c6075856a4 +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=817183 + +Index: qemu-2.0.0+dfsg/backends/rng-egd.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/backends/rng-egd.c 2016-05-10 14:49:34.458352586 -0400 ++++ qemu-2.0.0+dfsg/backends/rng-egd.c 2016-05-10 14:49:34.418352093 -0400 +@@ -24,33 +24,12 @@ + + CharDriverState *chr; + char *chr_name; +- +- GSList *requests; + } RngEgd; + +-typedef struct RngRequest +-{ +- EntropyReceiveFunc *receive_entropy; +- uint8_t *data; +- void *opaque; +- size_t offset; +- size_t size; +-} RngRequest; +- +-static void rng_egd_request_entropy(RngBackend *b, size_t size, +- EntropyReceiveFunc *receive_entropy, +- void *opaque) ++static void rng_egd_request_entropy(RngBackend *b, RngRequest *req) + { + RngEgd *s = RNG_EGD(b); +- RngRequest *req; +- +- req = g_malloc(sizeof(*req)); +- +- req->offset = 0; +- req->size = size; +- req->receive_entropy = receive_entropy; +- req->opaque = opaque; +- req->data = g_malloc(req->size); ++ size_t size = req->size; + + while (size > 0) { + uint8_t header[2]; +@@ -64,24 +43,15 @@ + + size -= len; + } +- +- s->requests = g_slist_append(s->requests, req); +-} +- +-static void rng_egd_free_request(RngRequest *req) +-{ +- g_free(req->data); +- g_free(req); + } + + static int rng_egd_chr_can_read(void *opaque) + { + RngEgd *s = RNG_EGD(opaque); +- GSList *i; ++ RngRequest *req; + int size = 0; + +- for (i = s->requests; i; i = i->next) { +- RngRequest *req = i->data; ++ QSIMPLEQ_FOREACH(req, &s->parent.requests, next) { + size += req->size - req->offset; + } + +@@ -93,8 +63,8 @@ + RngEgd *s = RNG_EGD(opaque); + size_t buf_offset = 0; + +- while (size > 0 && s->requests) { +- RngRequest *req = s->requests->data; ++ while (size > 0 && !QSIMPLEQ_EMPTY(&s->parent.requests)) { ++ RngRequest *req = QSIMPLEQ_FIRST(&s->parent.requests); + int len = MIN(size, req->size - req->offset); + + memcpy(req->data + req->offset, buf + buf_offset, len); +@@ -103,38 +73,13 @@ + size -= len; + + if (req->offset == req->size) { +- s->requests = g_slist_remove_link(s->requests, s->requests); +- + req->receive_entropy(req->opaque, req->data, req->size); + +- rng_egd_free_request(req); ++ rng_backend_finalize_request(&s->parent, req); + } + } + } + +-static void rng_egd_free_requests(RngEgd *s) +-{ +- GSList *i; +- +- for (i = s->requests; i; i = i->next) { +- rng_egd_free_request(i->data); +- } +- +- g_slist_free(s->requests); +- s->requests = NULL; +-} +- +-static void rng_egd_cancel_requests(RngBackend *b) +-{ +- RngEgd *s = RNG_EGD(b); +- +- /* We simply delete the list of pending requests. If there is data in the +- * queue waiting to be read, this is okay, because there will always be +- * more data than we requested originally +- */ +- rng_egd_free_requests(s); +-} +- + static void rng_egd_opened(RngBackend *b, Error **errp) + { + RngEgd *s = RNG_EGD(b); +@@ -201,8 +146,6 @@ + } + + g_free(s->chr_name); +- +- rng_egd_free_requests(s); + } + + static void rng_egd_class_init(ObjectClass *klass, void *data) +@@ -210,7 +153,6 @@ + RngBackendClass *rbc = RNG_BACKEND_CLASS(klass); + + rbc->request_entropy = rng_egd_request_entropy; +- rbc->cancel_requests = rng_egd_cancel_requests; + rbc->opened = rng_egd_opened; + } + +Index: qemu-2.0.0+dfsg/backends/rng-random.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/backends/rng-random.c 2016-05-10 14:49:34.458352586 -0400 ++++ qemu-2.0.0+dfsg/backends/rng-random.c 2016-05-10 14:49:34.418352093 -0400 +@@ -21,10 +21,6 @@ + + int fd; + char *filename; +- +- EntropyReceiveFunc *receive_func; +- void *opaque; +- size_t size; + }; + + /** +@@ -37,36 +33,35 @@ + static void entropy_available(void *opaque) + { + RndRandom *s = RNG_RANDOM(opaque); +- uint8_t buffer[s->size]; +- ssize_t len; + +- len = read(s->fd, buffer, s->size); +- if (len < 0 && errno == EAGAIN) { +- return; +- } +- g_assert(len != -1); ++ while (!QSIMPLEQ_EMPTY(&s->parent.requests)) { ++ RngRequest *req = QSIMPLEQ_FIRST(&s->parent.requests); ++ ssize_t len; ++ ++ len = read(s->fd, req->data, req->size); ++ if (len < 0 && errno == EAGAIN) { ++ return; ++ } ++ g_assert(len != -1); ++ ++ req->receive_entropy(req->opaque, req->data, len); + +- s->receive_func(s->opaque, buffer, len); +- s->receive_func = NULL; ++ rng_backend_finalize_request(&s->parent, req); ++ } + ++ /* We've drained all requests, the fd handler can be reset. */ + qemu_set_fd_handler(s->fd, NULL, NULL, NULL); + } + +-static void rng_random_request_entropy(RngBackend *b, size_t size, +- EntropyReceiveFunc *receive_entropy, +- void *opaque) ++static void rng_random_request_entropy(RngBackend *b, RngRequest *req) + { + RndRandom *s = RNG_RANDOM(b); + +- if (s->receive_func) { +- s->receive_func(s->opaque, NULL, 0); ++ if (QSIMPLEQ_EMPTY(&s->parent.requests)) { ++ /* If there are no pending requests yet, we need to ++ * install our fd handler. */ ++ qemu_set_fd_handler(s->fd, entropy_available, NULL, s); + } +- +- s->receive_func = receive_entropy; +- s->opaque = opaque; +- s->size = size; +- +- qemu_set_fd_handler(s->fd, entropy_available, NULL, s); + } + + static void rng_random_opened(RngBackend *b, Error **errp) +Index: qemu-2.0.0+dfsg/backends/rng.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/backends/rng.c 2016-05-10 14:49:34.458352586 -0400 ++++ qemu-2.0.0+dfsg/backends/rng.c 2016-05-10 14:49:34.418352093 -0400 +@@ -19,18 +19,20 @@ + void *opaque) + { + RngBackendClass *k = RNG_BACKEND_GET_CLASS(s); ++ RngRequest *req; + + if (k->request_entropy) { +- k->request_entropy(s, size, receive_entropy, opaque); +- } +-} ++ req = g_malloc(sizeof(*req)); + +-void rng_backend_cancel_requests(RngBackend *s) +-{ +- RngBackendClass *k = RNG_BACKEND_GET_CLASS(s); ++ req->offset = 0; ++ req->size = size; ++ req->receive_entropy = receive_entropy; ++ req->opaque = opaque; ++ req->data = g_malloc(req->size); + +- if (k->cancel_requests) { +- k->cancel_requests(s); ++ k->request_entropy(s, req); ++ ++ QSIMPLEQ_INSERT_TAIL(&s->requests, req, next); + } + } + +@@ -69,14 +71,48 @@ + } + } + ++static void rng_backend_free_request(RngRequest *req) ++{ ++ g_free(req->data); ++ g_free(req); ++} ++ ++static void rng_backend_free_requests(RngBackend *s) ++{ ++ RngRequest *req, *next; ++ ++ QSIMPLEQ_FOREACH_SAFE(req, &s->requests, next, next) { ++ rng_backend_free_request(req); ++ } ++ ++ QSIMPLEQ_INIT(&s->requests); ++} ++ ++void rng_backend_finalize_request(RngBackend *s, RngRequest *req) ++{ ++ QSIMPLEQ_REMOVE(&s->requests, req, RngRequest, next); ++ rng_backend_free_request(req); ++} ++ + static void rng_backend_init(Object *obj) + { ++ RngBackend *s = RNG_BACKEND(obj); ++ ++ QSIMPLEQ_INIT(&s->requests); ++ + object_property_add_bool(obj, "opened", + rng_backend_prop_get_opened, + rng_backend_prop_set_opened, + NULL); + } + ++static void rng_backend_finalize(Object *obj) ++{ ++ RngBackend *s = RNG_BACKEND(obj); ++ ++ rng_backend_free_requests(s); ++} ++ + static void rng_backend_class_init(ObjectClass *oc, void *data) + { + UserCreatableClass *ucc = USER_CREATABLE_CLASS(oc); +@@ -89,6 +125,7 @@ + .parent = TYPE_OBJECT, + .instance_size = sizeof(RngBackend), + .instance_init = rng_backend_init, ++ .instance_finalize = rng_backend_finalize, + .class_size = sizeof(RngBackendClass), + .class_init = rng_backend_class_init, + .abstract = true, +Index: qemu-2.0.0+dfsg/include/sysemu/rng.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/include/sysemu/rng.h 2016-05-10 14:49:34.458352586 -0400 ++++ qemu-2.0.0+dfsg/include/sysemu/rng.h 2016-05-10 14:49:34.418352093 -0400 +@@ -25,6 +25,7 @@ + #define RNG_BACKEND_CLASS(klass) \ + OBJECT_CLASS_CHECK(RngBackendClass, (klass), TYPE_RNG_BACKEND) + ++typedef struct RngRequest RngRequest; + typedef struct RngBackendClass RngBackendClass; + typedef struct RngBackend RngBackend; + +@@ -32,13 +33,21 @@ + const void *data, + size_t size); + ++struct RngRequest ++{ ++ EntropyReceiveFunc *receive_entropy; ++ uint8_t *data; ++ void *opaque; ++ size_t offset; ++ size_t size; ++ QSIMPLEQ_ENTRY(RngRequest) next; ++}; ++ + struct RngBackendClass + { + ObjectClass parent_class; + +- void (*request_entropy)(RngBackend *s, size_t size, +- EntropyReceiveFunc *receive_entropy, void *opaque); +- void (*cancel_requests)(RngBackend *s); ++ void (*request_entropy)(RngBackend *s, RngRequest *req); + + void (*opened)(RngBackend *s, Error **errp); + }; +@@ -49,8 +58,10 @@ + + /*< protected >*/ + bool opened; ++ QSIMPLEQ_HEAD(requests, RngRequest) requests; + }; + ++ + /** + * rng_backend_request_entropy: + * @s: the backend to request entropy from +@@ -71,12 +82,13 @@ + void *opaque); + + /** +- * rng_backend_cancel_requests: +- * @s: the backend to cancel all pending requests in ++ * rng_backend_free_request: ++ * @s: the backend that created the request ++ * @req: the request to finalize + * +- * Cancels all pending requests submitted by @rng_backend_request_entropy. This +- * should be used by a device during reset or in preparation for live migration +- * to stop tracking any request. ++ * Used by child rng backend classes to finalize requests once they've been ++ * processed. The request is removed from the list of active requests and ++ * deleted. + */ +-void rng_backend_cancel_requests(RngBackend *s); ++void rng_backend_finalize_request(RngBackend *s, RngRequest *req); + #endif diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-3710.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-3710.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-3710.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-3710.patch 2016-05-10 18:52:02.000000000 +0000 @@ -0,0 +1,106 @@ +Backport of: + +From 3bf1817079bb0d80c0d8a86a7c7dd0bfe90eb82e Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 26 Apr 2016 08:49:10 +0200 +Subject: [PATCH] vga: fix banked access bounds checking (CVE-2016-3710) + +vga allows banked access to video memory using the window at 0xa00000 +and it supports a different access modes with different address +calculations. + +The VBE bochs extentions support banked access too, using the +VBE_DISPI_INDEX_BANK register. The code tries to take the different +address calculations into account and applies different limits to +VBE_DISPI_INDEX_BANK depending on the current access mode. + +Which is probably effective in stopping misprogramming by accident. +But from a security point of view completely useless as an attacker +can easily change access modes after setting the bank register. + +Drop the bogus check, add range checks to vga_mem_{readb,writeb} +instead. + +Fixes: CVE-2016-3710 +Reported-by: Qinghao Tang +Signed-off-by: Gerd Hoffmann +--- + hw/display/vga.c | 24 ++++++++++++++++++------ + 1 files changed, 18 insertions(+), 6 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/display/vga.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/display/vga.c 2016-05-10 14:50:35.715107514 -0400 ++++ qemu-2.0.0+dfsg/hw/display/vga.c 2016-05-10 14:51:36.363854573 -0400 +@@ -198,6 +198,7 @@ + } + base += isa_mem_base; + region = g_malloc(sizeof(*region)); ++ assert(offset + size <= s->vram_size); + memory_region_init_alias(region, memory_region_owner(&s->vram), + "vga.chain4", &s->vram, offset, size); + memory_region_add_subregion_overlap(s->legacy_address_space, base, +@@ -741,11 +742,7 @@ + vbe_fixup_regs(s); + break; + case VBE_DISPI_INDEX_BANK: +- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) { +- val &= (s->vbe_bank_mask >> 2); +- } else { +- val &= s->vbe_bank_mask; +- } ++ val &= s->vbe_bank_mask; + s->vbe_regs[s->vbe_index] = val; + s->bank_offset = (val << 16); + vga_update_memory_access(s); +@@ -846,13 +843,21 @@ + + if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) { + /* chain 4 mode : simplest access */ ++ assert(addr < s->vram_size); + ret = s->vram_ptr[addr]; + } else if (s->gr[VGA_GFX_MODE] & 0x10) { + /* odd/even mode (aka text mode mapping) */ + plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1); +- ret = s->vram_ptr[((addr & ~1) << 1) | plane]; ++ addr = ((addr & ~1) << 1) | plane; ++ if (addr >= s->vram_size) { ++ return 0xff; ++ } ++ ret = s->vram_ptr[addr]; + } else { + /* standard VGA latched access */ ++ if (addr * sizeof(uint32_t) >= s->vram_size) { ++ return 0xff; ++ } + s->latch = ((uint32_t *)s->vram_ptr)[addr]; + + if (!(s->gr[VGA_GFX_MODE] & 0x08)) { +@@ -909,6 +914,7 @@ + plane = addr & 3; + mask = (1 << plane); + if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) { ++ assert(addr < s->vram_size); + s->vram_ptr[addr] = val; + #ifdef DEBUG_VGA_MEM + printf("vga: chain4: [0x" TARGET_FMT_plx "]\n", addr); +@@ -922,6 +928,9 @@ + mask = (1 << plane); + if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) { + addr = ((addr & ~1) << 1) | plane; ++ if (addr >= s->vram_size) { ++ return; ++ } + s->vram_ptr[addr] = val; + #ifdef DEBUG_VGA_MEM + printf("vga: odd/even: [0x" TARGET_FMT_plx "]\n", addr); +@@ -995,6 +1004,9 @@ + mask = s->sr[VGA_SEQ_PLANE_WRITE]; + s->plane_updated |= mask; /* only used to detect font change */ + write_mask = mask16[mask]; ++ if (addr * sizeof(uint32_t) >= s->vram_size) { ++ return; ++ } + ((uint32_t *)s->vram_ptr)[addr] = + (((uint32_t *)s->vram_ptr)[addr] & ~write_mask) | + (val & write_mask); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-3712.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-3712.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-3712.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-3712.patch 2016-05-10 18:54:30.000000000 +0000 @@ -0,0 +1,203 @@ +Description: fix denial of service via VGA module +Origin: backport, http://git.qemu.org/?p=qemu.git;a=commit;h=bfa0f151a564a83b5a26f3e917da98674bf3cf62 +Origin: backport, http://git.qemu.org/?p=qemu.git;a=commit;h=7fa5c2c5dc9f9bf878c1e8669eb9644d70a71e71 +Origin: backport, http://git.qemu.org/?p=qemu.git;a=commit;h=2068192dcccd8a80dddfcc8df6164cf9c26e0fc4 +Origin: backport, http://git.qemu.org/?p=qemu.git;a=commit;h=fd3c136b3e1482cd0ec7285d6bc2a3e6a62c38d7 +Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=823830 + +Index: qemu-2.0.0+dfsg/hw/display/vga.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/display/vga.c 2016-05-10 14:52:19.480385451 -0400 ++++ qemu-2.0.0+dfsg/hw/display/vga.c 2016-05-10 14:53:28.829238944 -0400 +@@ -166,6 +166,13 @@ + static uint16_t expand2[256]; + static uint8_t expand4to8[16]; + ++static void vbe_update_vgaregs(VGACommonState *s); ++ ++static inline bool vbe_enabled(VGACommonState *s) ++{ ++ return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED; ++} ++ + static void vga_update_memory_access(VGACommonState *s) + { + MemoryRegion *region, *old_region = s->chain4_alias; +@@ -504,6 +511,7 @@ + printf("vga: write SR%x = 0x%02x\n", s->sr_index, val); + #endif + s->sr[s->sr_index] = val & sr_mask[s->sr_index]; ++ vbe_update_vgaregs(s); + if (s->sr_index == VGA_SEQ_CLOCK_MODE) { + s->update_retrace_info(s); + } +@@ -535,6 +543,7 @@ + printf("vga: write GR%x = 0x%02x\n", s->gr_index, val); + #endif + s->gr[s->gr_index] = val & gr_mask[s->gr_index]; ++ vbe_update_vgaregs(s); + vga_update_memory_access(s); + break; + case VGA_CRT_IM: +@@ -553,10 +562,12 @@ + if (s->cr_index == VGA_CRTC_OVERFLOW) { + s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x10) | + (val & 0x10); ++ vbe_update_vgaregs(s); + } + return; + } + s->cr[s->cr_index] = val; ++ vbe_update_vgaregs(s); + + switch(s->cr_index) { + case VGA_CRTC_H_TOTAL: +@@ -589,7 +600,7 @@ + uint16_t *r = s->vbe_regs; + uint32_t bits, linelength, maxy, offset; + +- if (!(r[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) { ++ if (!vbe_enabled(s)) { + /* vbe is turned off -- nothing to do */ + return; + } +@@ -664,6 +675,49 @@ + s->vbe_start_addr = offset / 4; + } + ++/* we initialize the VGA graphic mode */ ++static void vbe_update_vgaregs(VGACommonState *s) ++{ ++ int h, shift_control; ++ ++ if (!vbe_enabled(s)) { ++ /* vbe is turned off -- nothing to do */ ++ return; ++ } ++ ++ /* graphic mode + memory map 1 */ ++ s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 | ++ VGA_GR06_GRAPHICS_MODE; ++ s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */ ++ s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3; ++ /* width */ ++ s->cr[VGA_CRTC_H_DISP] = ++ (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1; ++ /* height (only meaningful if < 1024) */ ++ h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1; ++ s->cr[VGA_CRTC_V_DISP_END] = h; ++ s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) | ++ ((h >> 7) & 0x02) | ((h >> 3) & 0x40); ++ /* line compare to 1023 */ ++ s->cr[VGA_CRTC_LINE_COMPARE] = 0xff; ++ s->cr[VGA_CRTC_OVERFLOW] |= 0x10; ++ s->cr[VGA_CRTC_MAX_SCAN] |= 0x40; ++ ++ if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) { ++ shift_control = 0; ++ s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */ ++ } else { ++ shift_control = 2; ++ /* set chain 4 mode */ ++ s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M; ++ /* activate all planes */ ++ s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES; ++ } ++ s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) | ++ (shift_control << 5); ++ s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */ ++} ++ + static uint32_t vbe_ioport_read_index(void *opaque, uint32_t addr) + { + VGACommonState *s = opaque; +@@ -740,6 +794,7 @@ + case VBE_DISPI_INDEX_Y_OFFSET: + s->vbe_regs[s->vbe_index] = val; + vbe_fixup_regs(s); ++ vbe_update_vgaregs(s); + break; + case VBE_DISPI_INDEX_BANK: + val &= s->vbe_bank_mask; +@@ -750,53 +805,19 @@ + case VBE_DISPI_INDEX_ENABLE: + if ((val & VBE_DISPI_ENABLED) && + !(s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED)) { +- int h, shift_control; + + s->vbe_regs[VBE_DISPI_INDEX_VIRT_WIDTH] = 0; + s->vbe_regs[VBE_DISPI_INDEX_X_OFFSET] = 0; + s->vbe_regs[VBE_DISPI_INDEX_Y_OFFSET] = 0; + s->vbe_regs[VBE_DISPI_INDEX_ENABLE] |= VBE_DISPI_ENABLED; + vbe_fixup_regs(s); ++ vbe_update_vgaregs(s); + + /* clear the screen (should be done in BIOS) */ + if (!(val & VBE_DISPI_NOCLEARMEM)) { + memset(s->vram_ptr, 0, + s->vbe_regs[VBE_DISPI_INDEX_YRES] * s->vbe_line_offset); + } +- +- /* we initialize the VGA graphic mode (should be done +- in BIOS) */ +- /* graphic mode + memory map 1 */ +- s->gr[VGA_GFX_MISC] = (s->gr[VGA_GFX_MISC] & ~0x0c) | 0x04 | +- VGA_GR06_GRAPHICS_MODE; +- s->cr[VGA_CRTC_MODE] |= 3; /* no CGA modes */ +- s->cr[VGA_CRTC_OFFSET] = s->vbe_line_offset >> 3; +- /* width */ +- s->cr[VGA_CRTC_H_DISP] = +- (s->vbe_regs[VBE_DISPI_INDEX_XRES] >> 3) - 1; +- /* height (only meaningful if < 1024) */ +- h = s->vbe_regs[VBE_DISPI_INDEX_YRES] - 1; +- s->cr[VGA_CRTC_V_DISP_END] = h; +- s->cr[VGA_CRTC_OVERFLOW] = (s->cr[VGA_CRTC_OVERFLOW] & ~0x42) | +- ((h >> 7) & 0x02) | ((h >> 3) & 0x40); +- /* line compare to 1023 */ +- s->cr[VGA_CRTC_LINE_COMPARE] = 0xff; +- s->cr[VGA_CRTC_OVERFLOW] |= 0x10; +- s->cr[VGA_CRTC_MAX_SCAN] |= 0x40; +- +- if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) { +- shift_control = 0; +- s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */ +- } else { +- shift_control = 2; +- /* set chain 4 mode */ +- s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M; +- /* activate all planes */ +- s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES; +- } +- s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) | +- (shift_control << 5); +- s->cr[VGA_CRTC_MAX_SCAN] &= ~0x9f; /* no double scan */ + } else { + /* XXX: the bios should do that */ + s->bank_offset = 0; +@@ -1170,7 +1191,7 @@ + { + uint32_t start_addr, line_offset, line_compare; + +- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) { ++ if (vbe_enabled(s)) { + line_offset = s->vbe_line_offset; + start_addr = s->vbe_start_addr; + line_compare = 65535; +@@ -1623,7 +1644,7 @@ + { + int ret; + +- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) { ++ if (vbe_enabled(s)) { + ret = s->vbe_regs[VBE_DISPI_INDEX_BPP]; + } else { + ret = 0; +@@ -1635,7 +1656,7 @@ + { + int width, height; + +- if (s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED) { ++ if (vbe_enabled(s)) { + width = s->vbe_regs[VBE_DISPI_INDEX_XRES]; + height = s->vbe_regs[VBE_DISPI_INDEX_YRES]; + } else { diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4001.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-4001.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4001.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-4001.patch 2016-05-10 18:57:28.000000000 +0000 @@ -0,0 +1,43 @@ +From 3a15cc0e1ee7168db0782133d2607a6bfa422d66 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Fri, 8 Apr 2016 11:33:48 +0530 +Subject: [PATCH] net: stellaris_enet: check packet length against receive buffer + +When receiving packets over Stellaris ethernet controller, it +uses receive buffer of size 2048 bytes. In case the controller +accepts large(MTU) packets, it could lead to memory corruption. +Add check to avoid it. + +Reported-by: Oleksandr Bazhaniuk +Signed-off-by: Prasad J Pandit +Message-id: 1460095428-22698-1-git-send-email-ppandit@redhat.com +Reviewed-by: Peter Maydell +Signed-off-by: Peter Maydell +--- + hw/net/stellaris_enet.c | 12 +++++++++++- + 1 files changed, 11 insertions(+), 1 deletions(-) + +Index: qemu-2.3+dfsg/hw/net/stellaris_enet.c +=================================================================== +--- qemu-2.3+dfsg.orig/hw/net/stellaris_enet.c 2016-05-10 14:22:26.418098873 -0400 ++++ qemu-2.3+dfsg/hw/net/stellaris_enet.c 2016-05-10 14:22:26.374098319 -0400 +@@ -236,8 +236,18 @@ + n = s->next_packet + s->np; + if (n >= 31) + n -= 31; +- s->np++; + ++ if (size >= sizeof(s->rx[n].data) - 6) { ++ /* If the packet won't fit into the ++ * emulated 2K RAM, this is reported ++ * as a FIFO overrun error. ++ */ ++ s->ris |= SE_INT_FOV; ++ stellaris_enet_update(s); ++ return -1; ++ } ++ ++ s->np++; + s->rx[n].len = size + 6; + p = s->rx[n].data; + *(p++) = (size + 6); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4002.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-4002.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4002.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-4002.patch 2016-05-10 18:57:33.000000000 +0000 @@ -0,0 +1,28 @@ +From: Prasad J Pandit + +When receiving packets over MIPSnet network device, it uses + receive buffer of size 1514 bytes. In case the controller +accepts large(MTU) packets, it could lead to memory corruption. +Add check to avoid it. + +Reported by: Oleksandr Bazhaniuk + +Signed-off-by: Prasad J Pandit +--- + hw/net/mipsnet.c | 3 +++ + 1 file changed, 3 insertions(+) + +Index: qemu-2.3+dfsg/hw/net/mipsnet.c +=================================================================== +--- qemu-2.3+dfsg.orig/hw/net/mipsnet.c 2016-05-10 14:22:36.426224845 -0400 ++++ qemu-2.3+dfsg/hw/net/mipsnet.c 2016-05-10 14:22:36.386224342 -0400 +@@ -82,6 +82,9 @@ + if (!mipsnet_can_receive(nc)) + return -1; + ++ if (size >= sizeof(s->rx_buffer)) { ++ return 0; ++ } + s->busy = 1; + + /* Just accept everything. */ diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4020.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-4020.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4020.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-4020.patch 2016-05-10 18:57:48.000000000 +0000 @@ -0,0 +1,26 @@ +From: Prasad J Pandit + +When processing Task Priorty Register(TPR) access, it could leak +automatic stack variable 'imm32' in patch_instruction(). +Initialise the variable to avoid it. + +Reported by: Donghai Zdh + +Signed-off-by: Prasad J Pandit +--- + hw/i386/kvmvapic.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: qemu-2.0.0+dfsg/hw/i386/kvmvapic.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/i386/kvmvapic.c 2016-05-10 14:57:45.112566229 -0400 ++++ qemu-2.0.0+dfsg/hw/i386/kvmvapic.c 2016-05-10 14:57:45.048565382 -0400 +@@ -394,7 +394,7 @@ + CPUX86State *env = &cpu->env; + VAPICHandlers *handlers; + uint8_t opcode[2]; +- uint32_t imm32; ++ uint32_t imm32 = 0; + target_ulong current_pc = 0; + target_ulong current_cs_base = 0; + int current_flags = 0; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4037.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-4037.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4037.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-4037.patch 2016-05-10 18:57:59.000000000 +0000 @@ -0,0 +1,59 @@ +From 1ae3f2f178087711f9591350abad133525ba93f2 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Mon, 18 Apr 2016 09:11:38 +0200 +Subject: [PATCH] ehci: apply limit to iTD/sidt descriptors +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf8 +Content-Transfer-Encoding: 8bit + +Commit "156a2e4 ehci: make idt processing more robust" tries to avoid a +DoS by the guest (create a circular iTD queue and let qemu ehci +emulation run in circles forever). Unfortunately this has two problems: +First it misses the case of siTDs, and second it reportedly breaks +FreeBSD. + +So lets go for a different approach: just count the number of iTDs and +siTDs we have seen per frame and apply a limit. That should really +catch all cases now. + +Reported-by: 杜少博 +Signed-off-by: Gerd Hoffmann +--- + hw/usb/hcd-ehci.c | 6 +++++- + 1 files changed, 5 insertions(+), 1 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/usb/hcd-ehci.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/usb/hcd-ehci.c 2016-05-10 14:57:55.660705784 -0400 ++++ qemu-2.0.0+dfsg/hw/usb/hcd-ehci.c 2016-05-10 14:57:55.612705149 -0400 +@@ -2089,6 +2089,7 @@ + static void ehci_advance_state(EHCIState *ehci, int async) + { + EHCIQueue *q = NULL; ++ int itd_count = 0; + int again; + + do { +@@ -2113,10 +2114,12 @@ + + case EST_FETCHITD: + again = ehci_state_fetchitd(ehci, async); ++ itd_count++; + break; + + case EST_FETCHSITD: + again = ehci_state_fetchsitd(ehci, async); ++ itd_count++; + break; + + case EST_ADVANCEQUEUE: +@@ -2165,7 +2168,8 @@ + break; + } + +- if (again < 0) { ++ if (again < 0 || itd_count > 16) { ++ /* TODO: notify guest (raise HSE irq?) */ + fprintf(stderr, "processing error - resetting ehci HC\n"); + ehci_reset(ehci); + again = 0; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4439.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-4439.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4439.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-4439.patch 2016-08-03 17:50:17.000000000 +0000 @@ -0,0 +1,39 @@ +From c98c6c105f66f05aa0b7c1d2a4a3f716450907ef Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Thu, 19 May 2016 16:09:30 +0530 +Subject: [PATCH] esp: check command buffer length before write(CVE-2016-4439) + +The 53C9X Fast SCSI Controller(FSC) comes with an internal 16-byte +FIFO buffer. It is used to handle command and data transfer. While +writing to this command buffer 's->cmdbuf[TI_BUFSZ=16]', a check +was missing to validate input length. Add check to avoid OOB write +access. + +Fixes CVE-2016-4439. + +Reported-by: Li Qiang +Cc: qemu-stable@nongnu.org +Signed-off-by: Prasad J Pandit +Message-Id: <1463654371-11169-2-git-send-email-ppandit@redhat.com> +Signed-off-by: Paolo Bonzini +--- + hw/scsi/esp.c | 6 +++++- + 1 files changed, 5 insertions(+), 1 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/scsi/esp.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/scsi/esp.c 2016-08-03 13:50:15.561472921 -0400 ++++ qemu-2.0.0+dfsg/hw/scsi/esp.c 2016-08-03 13:50:15.557472884 -0400 +@@ -439,7 +439,11 @@ + break; + case ESP_FIFO: + if (s->do_cmd) { +- s->cmdbuf[s->cmdlen++] = val & 0xff; ++ if (s->cmdlen < TI_BUFSZ) { ++ s->cmdbuf[s->cmdlen++] = val & 0xff; ++ } else { ++ trace_esp_error_fifo_overrun(); ++ } + } else if (s->ti_size == TI_BUFSZ - 1) { + trace_esp_error_fifo_overrun(); + } else { diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4441.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-4441.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4441.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-4441.patch 2016-08-03 17:50:21.000000000 +0000 @@ -0,0 +1,72 @@ +From 6c1fef6b59563cc415f21e03f81539ed4b33ad90 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Thu, 19 May 2016 16:09:31 +0530 +Subject: [PATCH] esp: check dma length before reading scsi command(CVE-2016-4441) + +The 53C9X Fast SCSI Controller(FSC) comes with an internal 16-byte +FIFO buffer. It is used to handle command and data transfer. +Routine get_cmd() uses DMA to read scsi commands into this buffer. +Add check to validate DMA length against buffer size to avoid any +overrun. + +Fixes CVE-2016-4441. + +Reported-by: Li Qiang +Cc: qemu-stable@nongnu.org +Signed-off-by: Prasad J Pandit +Message-Id: <1463654371-11169-3-git-send-email-ppandit@redhat.com> +Signed-off-by: Paolo Bonzini +--- + hw/scsi/esp.c | 11 +++++++---- + 1 files changed, 7 insertions(+), 4 deletions(-) + +Index: qemu-2.5+dfsg/hw/scsi/esp.c +=================================================================== +--- qemu-2.5+dfsg.orig/hw/scsi/esp.c 2016-08-03 12:36:47.488655041 -0400 ++++ qemu-2.5+dfsg/hw/scsi/esp.c 2016-08-03 12:36:47.488655041 -0400 +@@ -80,7 +80,7 @@ + } + } + +-static uint32_t get_cmd(ESPState *s, uint8_t *buf) ++static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen) + { + uint32_t dmalen; + int target; +@@ -90,6 +90,9 @@ + dmalen = s->rregs[ESP_TCLO]; + dmalen |= s->rregs[ESP_TCMID] << 8; + dmalen |= s->rregs[ESP_TCHI] << 16; ++ if (dmalen > buflen) { ++ return 0; ++ } + s->dma_memory_read(s->dma_opaque, buf, dmalen); + } else { + dmalen = s->ti_size; +@@ -164,7 +167,7 @@ + s->dma_cb = handle_satn; + return; + } +- len = get_cmd(s, buf); ++ len = get_cmd(s, buf, sizeof(buf)); + if (len) + do_cmd(s, buf); + } +@@ -178,7 +181,7 @@ + s->dma_cb = handle_s_without_atn; + return; + } +- len = get_cmd(s, buf); ++ len = get_cmd(s, buf, sizeof(buf)); + if (len) { + do_busid_cmd(s, buf, 0); + } +@@ -190,7 +193,7 @@ + s->dma_cb = handle_satn_stop; + return; + } +- s->cmdlen = get_cmd(s, s->cmdbuf); ++ s->cmdlen = get_cmd(s, s->cmdbuf, sizeof(s->cmdbuf)); + if (s->cmdlen) { + trace_esp_handle_satn_stop(s->cmdlen); + s->do_cmd = 1; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4453.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-4453.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4453.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-4453.patch 2016-08-03 17:50:33.000000000 +0000 @@ -0,0 +1,42 @@ +From 4e68a0ee17dad7b8d870df0081d4ab2e079016c2 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Mon, 30 May 2016 09:09:21 +0200 +Subject: [PATCH] vmsvga: don't process more than 1024 fifo commands at once +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf8 +Content-Transfer-Encoding: 8bit + +vmsvga_fifo_run is called in regular intervals (on each display update) +and will resume where it left off. So we can simply exit the loop, +without having to worry about how processing will continue. + +Fixes: CVE-2016-4453 +Cc: qemu-stable@nongnu.org +Cc: P J P +Reported-by: 李强 +Signed-off-by: Gerd Hoffmann +Message-id: 1464592161-18348-5-git-send-email-kraxel@redhat.com +--- + hw/display/vmware_vga.c | 4 ++-- + 1 files changed, 2 insertions(+), 2 deletions(-) + +Index: qemu-2.5+dfsg/hw/display/vmware_vga.c +=================================================================== +--- qemu-2.5+dfsg.orig/hw/display/vmware_vga.c 2016-08-03 12:37:33.717075881 -0400 ++++ qemu-2.5+dfsg/hw/display/vmware_vga.c 2016-08-03 12:37:33.713075845 -0400 +@@ -595,13 +595,13 @@ + static void vmsvga_fifo_run(struct vmsvga_state_s *s) + { + uint32_t cmd, colour; +- int args, len; ++ int args, len, maxloop = 1024; + int x, y, dx, dy, width, height; + struct vmsvga_cursor_definition_s cursor; + uint32_t cmd_start; + + len = vmsvga_fifo_length(s); +- while (len > 0) { ++ while (len > 0 && --maxloop > 0) { + /* May need to go back to the start of the command if incomplete */ + cmd_start = s->fifo_stop; + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4454.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-4454.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4454.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-4454.patch 2016-08-03 17:50:30.000000000 +0000 @@ -0,0 +1,141 @@ +Description: fix DoS or host memory leak in vmware_vga +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=521360267876d3b6518b328051a2e56bca55bef8 +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=c2e3c54d3960bc53bfa3a5ce7ea7a050b9be267e +Origin: upstream, http://git.qemu.org/?p=qemu.git;a=commit;h=7e486f7577764a07aa35588e119903c80a5c30a2 + +Index: qemu-2.0.0+dfsg/hw/display/vmware_vga.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/display/vmware_vga.c 2016-08-03 13:50:28.373594910 -0400 ++++ qemu-2.0.0+dfsg/hw/display/vmware_vga.c 2016-08-03 13:50:28.369594871 -0400 +@@ -64,17 +64,11 @@ + uint8_t *fifo_ptr; + unsigned int fifo_size; + +- union { +- uint32_t *fifo; +- struct QEMU_PACKED { +- uint32_t min; +- uint32_t max; +- uint32_t next_cmd; +- uint32_t stop; +- /* Add registers here when adding capabilities. */ +- uint32_t fifo[0]; +- } *cmd; +- }; ++ uint32_t *fifo; ++ uint32_t fifo_min; ++ uint32_t fifo_max; ++ uint32_t fifo_next; ++ uint32_t fifo_stop; + + #define REDRAW_FIFO_LEN 512 + struct vmsvga_rect_s { +@@ -196,7 +190,7 @@ + */ + SVGA_FIFO_MIN = 0, + SVGA_FIFO_MAX, /* The distance from MIN to MAX must be at least 10K */ +- SVGA_FIFO_NEXT_CMD, ++ SVGA_FIFO_NEXT, + SVGA_FIFO_STOP, + + /* +@@ -544,8 +538,6 @@ + } + #endif + +-#define CMD(f) le32_to_cpu(s->cmd->f) +- + static inline int vmsvga_fifo_length(struct vmsvga_state_s *s) + { + int num; +@@ -553,21 +545,45 @@ + if (!s->config || !s->enable) { + return 0; + } +- num = CMD(next_cmd) - CMD(stop); ++ ++ s->fifo_min = le32_to_cpu(s->fifo[SVGA_FIFO_MIN]); ++ s->fifo_max = le32_to_cpu(s->fifo[SVGA_FIFO_MAX]); ++ s->fifo_next = le32_to_cpu(s->fifo[SVGA_FIFO_NEXT]); ++ s->fifo_stop = le32_to_cpu(s->fifo[SVGA_FIFO_STOP]); ++ ++ /* Check range and alignment. */ ++ if ((s->fifo_min | s->fifo_max | s->fifo_next | s->fifo_stop) & 3) { ++ return 0; ++ } ++ if (s->fifo_min < sizeof(uint32_t) * 4) { ++ return 0; ++ } ++ if (s->fifo_max > SVGA_FIFO_SIZE || ++ s->fifo_min >= SVGA_FIFO_SIZE || ++ s->fifo_stop >= SVGA_FIFO_SIZE || ++ s->fifo_next >= SVGA_FIFO_SIZE) { ++ return 0; ++ } ++ if (s->fifo_max < s->fifo_min + 10 * 1024) { ++ return 0; ++ } ++ ++ num = s->fifo_next - s->fifo_stop; + if (num < 0) { +- num += CMD(max) - CMD(min); ++ num += s->fifo_max - s->fifo_min; + } + return num >> 2; + } + + static inline uint32_t vmsvga_fifo_read_raw(struct vmsvga_state_s *s) + { +- uint32_t cmd = s->fifo[CMD(stop) >> 2]; ++ uint32_t cmd = s->fifo[s->fifo_stop >> 2]; + +- s->cmd->stop = cpu_to_le32(CMD(stop) + 4); +- if (CMD(stop) >= CMD(max)) { +- s->cmd->stop = s->cmd->min; ++ s->fifo_stop += 4; ++ if (s->fifo_stop >= s->fifo_max) { ++ s->fifo_stop = s->fifo_min; + } ++ s->fifo[SVGA_FIFO_STOP] = cpu_to_le32(s->fifo_stop); + return cmd; + } + +@@ -587,7 +603,7 @@ + len = vmsvga_fifo_length(s); + while (len > 0) { + /* May need to go back to the start of the command if incomplete */ +- cmd_start = s->cmd->stop; ++ cmd_start = s->fifo_stop; + + switch (cmd = vmsvga_fifo_read(s)) { + case SVGA_CMD_UPDATE: +@@ -743,7 +759,8 @@ + break; + + rewind: +- s->cmd->stop = cmd_start; ++ s->fifo_stop = cmd_start; ++ s->fifo[SVGA_FIFO_STOP] = cpu_to_le32(s->fifo_stop); + break; + } + } +@@ -1000,19 +1017,6 @@ + case SVGA_REG_CONFIG_DONE: + if (value) { + s->fifo = (uint32_t *) s->fifo_ptr; +- /* Check range and alignment. */ +- if ((CMD(min) | CMD(max) | CMD(next_cmd) | CMD(stop)) & 3) { +- break; +- } +- if (CMD(min) < (uint8_t *) s->cmd->fifo - (uint8_t *) s->fifo) { +- break; +- } +- if (CMD(max) > SVGA_FIFO_SIZE) { +- break; +- } +- if (CMD(max) < CMD(min) + 10 * 1024) { +- break; +- } + vga_dirty_log_stop(&s->vga); + } + s->config = !!value; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4952.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-4952.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-4952.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-4952.patch 2016-08-03 17:50:44.000000000 +0000 @@ -0,0 +1,99 @@ +From 3e831b40e015ba34dfb55ff11f767001839425ff Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Mon, 23 May 2016 16:18:05 +0530 +Subject: [PATCH] scsi: pvscsi: check command descriptor ring buffer size (CVE-2016-4952) + +Vmware Paravirtual SCSI emulation uses command descriptors to +process SCSI commands. These descriptors come with their ring +buffers. A guest could set the ring buffer size to an arbitrary +value leading to OOB access issue. Add check to avoid it. + +Reported-by: Li Qiang +Signed-off-by: Prasad J Pandit +Cc: qemu-stable@nongnu.org +Message-Id: <1464000485-27041-1-git-send-email-ppandit@redhat.com> +Reviewed-by: Shmulik Ladkani +Reviewed-by: Dmitry Fleytman +Signed-off-by: Paolo Bonzini +--- + hw/scsi/vmw_pvscsi.c | 24 ++++++++++++++++++++---- + 1 files changed, 20 insertions(+), 4 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/scsi/vmw_pvscsi.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/scsi/vmw_pvscsi.c 2016-08-03 13:50:41.005715197 -0400 ++++ qemu-2.0.0+dfsg/hw/scsi/vmw_pvscsi.c 2016-08-03 13:50:41.001715158 -0400 +@@ -126,7 +126,7 @@ + return log; + } + +-static void ++static int + pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri) + { + int i; +@@ -134,6 +134,10 @@ + uint32_t req_ring_size, cmp_ring_size; + m->rs_pa = ri->ringsStatePPN << VMW_PAGE_SHIFT; + ++ if ((ri->reqRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES) ++ || (ri->cmpRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES)) { ++ return -1; ++ } + req_ring_size = ri->reqRingNumPages * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE; + cmp_ring_size = ri->cmpRingNumPages * PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE; + txr_len_log2 = pvscsi_log2(req_ring_size - 1); +@@ -165,15 +169,20 @@ + + /* Flush ring state page changes */ + smp_wmb(); ++ ++ return 0; + } + +-static void ++static int + pvscsi_ring_init_msg(PVSCSIRingInfo *m, PVSCSICmdDescSetupMsgRing *ri) + { + int i; + uint32_t len_log2; + uint32_t ring_size; + ++ if (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); + +@@ -193,6 +202,8 @@ + + /* Flush ring state page changes */ + smp_wmb(); ++ ++ return 0; + } + + static void +@@ -740,7 +751,10 @@ + trace_pvscsi_on_cmd_arrived("PVSCSI_CMD_SETUP_RINGS"); + + pvscsi_dbg_dump_tx_rings_config(rc); +- pvscsi_ring_init_data(&s->rings, rc); ++ if (pvscsi_ring_init_data(&s->rings, rc) < 0) { ++ return PVSCSI_COMMAND_PROCESSING_FAILED; ++ } ++ + s->rings_info_valid = TRUE; + return PVSCSI_COMMAND_PROCESSING_SUCCEEDED; + } +@@ -820,7 +834,9 @@ + } + + if (s->rings_info_valid) { +- pvscsi_ring_init_msg(&s->rings, rc); ++ if (pvscsi_ring_init_msg(&s->rings, rc) < 0) { ++ return PVSCSI_COMMAND_PROCESSING_FAILED; ++ } + s->msg_ring_info_valid = TRUE; + } + return sizeof(PVSCSICmdDescSetupMsgRing) / sizeof(uint32_t); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5105.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-5105.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5105.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-5105.patch 2016-08-03 17:50:55.000000000 +0000 @@ -0,0 +1,31 @@ +From d37af740730dbbb93960cd318e040372d04d6dcf Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Wed, 25 May 2016 17:41:44 +0530 +Subject: [PATCH] scsi: megasas: initialise local configuration data buffer + +When reading MegaRAID SAS controller configuration via MegaRAID +Firmware Interface(MFI) commands, routine megasas_dcmd_cfg_read +uses an uninitialised local data buffer. Initialise this buffer +to avoid stack information leakage. + +Reported-by: Li Qiang +Signed-off-by: Prasad J Pandit +Message-Id: <1464178304-12831-1-git-send-email-ppandit@redhat.com> +Signed-off-by: Paolo Bonzini +--- + hw/scsi/megasas.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/scsi/megasas.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/scsi/megasas.c 2016-08-03 13:50:53.493834125 -0400 ++++ qemu-2.0.0+dfsg/hw/scsi/megasas.c 2016-08-03 13:50:53.489834088 -0400 +@@ -1195,7 +1195,7 @@ + + static int megasas_dcmd_cfg_read(MegasasState *s, MegasasCmd *cmd) + { +- uint8_t data[4096]; ++ uint8_t data[4096] = { 0 }; + struct mfi_config_data *info; + int num_pd_disks = 0, array_offset, ld_offset; + BusChild *kid; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5106.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-5106.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5106.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-5106.patch 2016-08-03 17:51:03.000000000 +0000 @@ -0,0 +1,31 @@ +From 1b85898025c4cd95dce673d15e67e60e98e91731 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Wed, 25 May 2016 16:01:29 +0530 +Subject: [PATCH] scsi: megasas: use appropriate property buffer size + +When setting MegaRAID SAS controller properties via MegaRAID +Firmware Interface(MFI) commands, a user supplied size parameter +is used to set property value. Use appropriate size value to avoid +OOB access issues. + +Reported-by: Li Qiang +Signed-off-by: Prasad J Pandit +Message-Id: <1464172291-2856-2-git-send-email-ppandit@redhat.com> +Signed-off-by: Paolo Bonzini +--- + hw/scsi/megasas.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/scsi/megasas.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/scsi/megasas.c 2016-08-03 13:51:00.773903462 -0400 ++++ qemu-2.0.0+dfsg/hw/scsi/megasas.c 2016-08-03 13:51:00.769903425 -0400 +@@ -1335,7 +1335,7 @@ + dcmd_size); + return MFI_STAT_INVALID_PARAMETER; + } +- dma_buf_write((uint8_t *)&info, cmd->iov_size, &cmd->qsg); ++ dma_buf_write((uint8_t *)&info, dcmd_size, &cmd->qsg); + trace_megasas_dcmd_unsupported(cmd->index, cmd->iov_size); + return MFI_STAT_OK; + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5107.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-5107.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5107.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-5107.patch 2016-08-03 17:55:44.000000000 +0000 @@ -0,0 +1,35 @@ +Backport of: + +From b60bdd1f1ee1616b7a9aeeffb4088e1ce2710fb2 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Wed, 25 May 2016 17:55:10 +0530 +Subject: [PATCH] scsi: megasas: check 'read_queue_head' index value + +While doing MegaRAID SAS controller command frame lookup, routine +'megasas_lookup_frame' uses 'read_queue_head' value as an index +into 'frames[MEGASAS_MAX_FRAMES=2048]' array. Limit its value +within array bounds to avoid any OOB access. + +Reported-by: Li Qiang +Signed-off-by: Prasad J Pandit +Message-Id: <1464179110-18593-1-git-send-email-ppandit@redhat.com> +Reviewed-by: Alexander Graf +Signed-off-by: Paolo Bonzini +--- + hw/scsi/megasas.c | 2 ++ + 1 files changed, 2 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/scsi/megasas.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/scsi/megasas.c 2016-08-03 13:51:10.685997874 -0400 ++++ qemu-2.0.0+dfsg/hw/scsi/megasas.c 2016-08-03 13:55:18.024356313 -0400 +@@ -608,7 +608,9 @@ + pa_hi = le32_to_cpu(initq->pi_addr_hi); + s->producer_pa = ((uint64_t) pa_hi << 32) | pa_lo; + s->reply_queue_head = ldl_le_phys(&address_space_memory, s->producer_pa); ++ s->reply_queue_head %= MEGASAS_MAX_FRAMES; + s->reply_queue_tail = ldl_le_phys(&address_space_memory, s->consumer_pa); ++ s->reply_queue_tail %= MEGASAS_MAX_FRAMES; + flags = le32_to_cpu(initq->flags); + if (flags & MFI_QUEUE_FLAG_CONTEXT64) { + s->flags |= MEGASAS_MASK_USE_QUEUE64; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5126.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-5126.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5126.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-5126.patch 2016-08-03 17:56:05.000000000 +0000 @@ -0,0 +1,34 @@ +From a6b3167fa0e825aebb5a7cd8b437b6d41584a196 Mon Sep 17 00:00:00 2001 +From: Peter Lieven +Date: Tue, 24 May 2016 10:59:28 +0200 +Subject: [PATCH] block/iscsi: avoid potential overflow of acb->task->cdb + +at least in the path via virtio-blk the maximum size is not +restricted. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Peter Lieven +Message-Id: <1464080368-29584-1-git-send-email-pl@kamp.de> +Signed-off-by: Paolo Bonzini +--- + block/iscsi.c | 7 +++++++ + 1 files changed, 7 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/block/iscsi.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/block/iscsi.c 2016-08-03 13:56:02.756783364 -0400 ++++ qemu-2.0.0+dfsg/block/iscsi.c 2016-08-03 13:56:02.752783325 -0400 +@@ -512,6 +512,13 @@ + acb->buf = NULL; + acb->ioh = buf; + ++ if (acb->ioh->cmd_len > SCSI_CDB_MAX_SIZE) { ++ error_report("iSCSI: ioctl error CDB exceeds max size (%d > %d)", ++ acb->ioh->cmd_len, SCSI_CDB_MAX_SIZE); ++ qemu_aio_unref(acb); ++ return NULL; ++ } ++ + acb->task = malloc(sizeof(struct scsi_task)); + if (acb->task == NULL) { + error_report("iSCSI: Failed to allocate task for scsi command. %s", diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5238.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-5238.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5238.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-5238.patch 2016-08-03 17:58:42.000000000 +0000 @@ -0,0 +1,33 @@ +From d3cdc49138c30be1d3c2f83d18f85d9fdee95f1a Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Tue, 31 May 2016 23:23:27 +0530 +Subject: [PATCH] scsi: esp: check buffer length before reading scsi command + +The 53C9X Fast SCSI Controller(FSC) comes with an internal 16-byte +FIFO buffer. It is used to handle command and data transfer. +Routine get_cmd() in non-DMA mode, uses 'ti_size' to read scsi +command into a buffer. Add check to validate command length against +buffer size to avoid any overrun. + +Reported-by: Li Qiang +Signed-off-by: Prasad J Pandit +Message-Id: <1464717207-7549-1-git-send-email-ppandit@redhat.com> +Signed-off-by: Paolo Bonzini +--- + hw/scsi/esp.c | 3 +++ + 1 files changed, 3 insertions(+), 0 deletions(-) + +Index: qemu-2.5+dfsg/hw/scsi/esp.c +=================================================================== +--- qemu-2.5+dfsg.orig/hw/scsi/esp.c 2016-08-03 12:39:25.826092428 -0400 ++++ qemu-2.5+dfsg/hw/scsi/esp.c 2016-08-03 12:39:25.822092391 -0400 +@@ -96,6 +96,9 @@ + s->dma_memory_read(s->dma_opaque, buf, dmalen); + } else { + dmalen = s->ti_size; ++ if (dmalen > TI_BUFSZ) { ++ return 0; ++ } + memcpy(buf, s->ti_buf, dmalen); + buf[0] = buf[2] >> 5; + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5337.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-5337.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5337.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-5337.patch 2016-08-03 17:58:53.000000000 +0000 @@ -0,0 +1,29 @@ +From 844864fbae66935951529408831c2f22367a57b6 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Tue, 7 Jun 2016 16:44:03 +0530 +Subject: [PATCH] scsi: megasas: null terminate bios version buffer + +While reading information via 'megasas_ctrl_get_info' routine, +a local bios version buffer isn't null terminated. Add the +terminating null byte to avoid any OOB access. + +Reported-by: Li Qiang +Reviewed-by: Peter Maydell +Signed-off-by: Prasad J Pandit +Signed-off-by: Paolo Bonzini +--- + hw/scsi/megasas.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/scsi/megasas.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/scsi/megasas.c 2016-08-03 13:58:50.990390810 -0400 ++++ qemu-2.0.0+dfsg/hw/scsi/megasas.c 2016-08-03 13:58:50.982390733 -0400 +@@ -728,6 +728,7 @@ + + ptr = memory_region_get_ram_ptr(&pci_dev->rom); + memcpy(biosver, ptr + 0x41, 31); ++ biosver[31] = 0; + memcpy(info.image_component[1].name, "BIOS", 4); + memcpy(info.image_component[1].version, biosver, + strlen((const char *)biosver)); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5338.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-5338.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5338.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-5338.patch 2016-08-03 17:59:00.000000000 +0000 @@ -0,0 +1,68 @@ +From ff589551c8e8e9e95e211b9d8daafb4ed39f1aec Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Mon, 6 Jun 2016 22:04:43 +0530 +Subject: [PATCH] scsi: esp: check TI buffer index before read/write + +The 53C9X Fast SCSI Controller(FSC) comes with internal 16-byte +FIFO buffers. One is used to handle commands and other is for +information transfer. Three control variables 'ti_rptr', +'ti_wptr' and 'ti_size' are used to control r/w access to the +information transfer buffer ti_buf[TI_BUFSZ=16]. In that, + +'ti_rptr' is used as read index, where read occurs. +'ti_wptr' is a write index, where write would occur. +'ti_size' indicates total bytes to be read from the buffer. + +While reading/writing to this buffer, index could exceed its +size. Add check to avoid OOB r/w access. + +Reported-by: Huawei PSIRT +Reported-by: Li Qiang +Signed-off-by: Prasad J Pandit +Message-Id: <1465230883-22303-1-git-send-email-ppandit@redhat.com> +Signed-off-by: Paolo Bonzini +--- + hw/scsi/esp.c | 20 +++++++++----------- + 1 files changed, 9 insertions(+), 11 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/scsi/esp.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/scsi/esp.c 2016-08-03 13:58:59.166468985 -0400 ++++ qemu-2.0.0+dfsg/hw/scsi/esp.c 2016-08-03 13:58:59.154468870 -0400 +@@ -401,19 +401,17 @@ + trace_esp_mem_readb(saddr, s->rregs[saddr]); + switch (saddr) { + case ESP_FIFO: +- if (s->ti_size > 0) { ++ if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) { ++ /* Data out. */ ++ qemu_log_mask(LOG_UNIMP, "esp: PIO data read not implemented\n"); ++ s->rregs[ESP_FIFO] = 0; ++ esp_raise_irq(s); ++ } else if (s->ti_rptr < s->ti_wptr) { + s->ti_size--; +- if ((s->rregs[ESP_RSTAT] & STAT_PIO_MASK) == 0) { +- /* Data out. */ +- qemu_log_mask(LOG_UNIMP, +- "esp: PIO data read not implemented\n"); +- s->rregs[ESP_FIFO] = 0; +- } else { +- s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++]; +- } ++ s->rregs[ESP_FIFO] = s->ti_buf[s->ti_rptr++]; + esp_raise_irq(s); + } +- if (s->ti_size == 0) { ++ if (s->ti_rptr == s->ti_wptr) { + s->ti_rptr = 0; + s->ti_wptr = 0; + } +@@ -450,7 +448,7 @@ + } else { + trace_esp_error_fifo_overrun(); + } +- } else if (s->ti_size == TI_BUFSZ - 1) { ++ } else if (s->ti_wptr == TI_BUFSZ - 1) { + trace_esp_error_fifo_overrun(); + } else { + s->ti_size++; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5403-2.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-5403-2.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5403-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-5403-2.patch 2016-11-07 20:29:11.000000000 +0000 @@ -0,0 +1,51 @@ +Backport of: + +From bccdef6b1a204db0f41ffb6e24ce373e4d7890d4 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Mon, 15 Aug 2016 13:54:15 +0100 +Subject: [PATCH] virtio: recalculate vq->inuse after migration + +The vq->inuse field is not migrated. Many devices don't hold +VirtQueueElements across migration so it doesn't matter that vq->inuse +starts at 0 on the destination QEMU. + +At least virtio-serial, virtio-blk, and virtio-balloon migrate while +holding VirtQueueElements. For these devices we need to recalculate +vq->inuse upon load so the value is correct. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Michael S. Tsirkin +Reviewed-by: Cornelia Huck +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +--- + hw/virtio/virtio.c | 15 +++++++++++++++ + 1 files changed, 15 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/virtio/virtio.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/virtio/virtio.c 2016-11-07 15:26:43.831060734 -0500 ++++ qemu-2.0.0+dfsg/hw/virtio/virtio.c 2016-11-07 15:28:57.756561214 -0500 +@@ -987,6 +987,21 @@ + vdev->vq[i].last_avail_idx, nheads); + return -1; + } ++ ++ /* ++ * Some devices migrate VirtQueueElements that have been popped ++ * from the avail ring but not yet returned to the used ring. ++ */ ++ vdev->vq[i].inuse = vdev->vq[i].last_avail_idx - ++ vring_used_idx(&vdev->vq[i]); ++ if (vdev->vq[i].inuse > vdev->vq[i].vring.num) { ++ error_report("VQ %d size 0x%x < last_avail_idx 0x%x - " ++ "used_idx 0x%x", ++ i, vdev->vq[i].vring.num, ++ vdev->vq[i].last_avail_idx, ++ vring_used_idx(&vdev->vq[i])); ++ return -1; ++ } + } else if (vdev->vq[i].last_avail_idx) { + error_report("VQ %d address 0x0 " + "inconsistent with Host index 0x%x", diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5403-3.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-5403-3.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5403-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-5403-3.patch 2016-11-07 20:29:30.000000000 +0000 @@ -0,0 +1,31 @@ +From 58a83c61496eeb0d31571a07a51bc1947e3379ac Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Mon, 15 Aug 2016 13:54:16 +0100 +Subject: [PATCH] virtio: decrement vq->inuse in virtqueue_discard() + +virtqueue_discard() moves vq->last_avail_idx back so the element can be +popped again. It's necessary to decrement vq->inuse to avoid "leaking" +the element count. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Stefan Hajnoczi +Reviewed-by: Michael S. Tsirkin +Reviewed-by: Cornelia Huck +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +--- + hw/virtio/virtio.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/virtio/virtio.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/virtio/virtio.c 2016-11-07 15:29:28.012900200 -0500 ++++ qemu-2.0.0+dfsg/hw/virtio/virtio.c 2016-11-07 15:29:28.008900155 -0500 +@@ -262,6 +262,7 @@ + unsigned int len) + { + vq->last_avail_idx--; ++ vq->inuse--; + virtqueue_unmap_sg(vq, elem, len); + } + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5403-4.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-5403-4.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5403-4.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-5403-4.patch 2016-11-07 20:31:08.000000000 +0000 @@ -0,0 +1,48 @@ +Backport of: + +From 4b7f91ed0270a371e1933efa21ba600b6da23ab9 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Wed, 7 Sep 2016 11:51:25 -0400 +Subject: [PATCH] virtio: zero vq->inuse in virtio_reset() + +vq->inuse must be zeroed upon device reset like most other virtqueue +fields. + +In theory, virtio_reset() just needs assert(vq->inuse == 0) since +devices must clean up in-flight requests during reset (requests cannot +not be leaked!). + +In practice, it is difficult to achieve vq->inuse == 0 across reset +because balloon, blk, 9p, etc implement various different strategies for +cleaning up requests. Most devices call g_free(elem) directly without +telling virtio.c that the VirtQueueElement is cleaned up. Therefore +vq->inuse is not decremented during reset. + +This patch zeroes vq->inuse and trusts that devices are not leaking +VirtQueueElements across reset. + +I will send a follow-up series that refactors request life-cycle across +all devices and converts vq->inuse = 0 into assert(vq->inuse == 0) but +this more invasive approach is not appropriate for stable trees. + +Signed-off-by: Stefan Hajnoczi +Cc: qemu-stable +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Ladi Prosek +--- + hw/virtio/virtio.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/virtio/virtio.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/virtio/virtio.c 2016-11-07 15:29:39.329026985 -0500 ++++ qemu-2.0.0+dfsg/hw/virtio/virtio.c 2016-11-07 15:30:36.501667538 -0500 +@@ -592,6 +592,7 @@ + vdev->vq[i].signalled_used = 0; + vdev->vq[i].signalled_used_valid = false; + vdev->vq[i].notification = true; ++ vdev->vq[i].inuse = 0; + } + } + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5403-5.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-5403-5.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5403-5.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-5403-5.patch 2017-04-06 14:03:03.000000000 +0000 @@ -0,0 +1,52 @@ +Backport of: + +From e66bcc408146730958d1a840bda85d7ad51e0cd7 Mon Sep 17 00:00:00 2001 +From: Halil Pasic +Date: Mon, 19 Dec 2016 16:44:44 +0100 +Subject: [PATCH] virtio: fix vq->inuse recalc after migr + +Correct recalculation of vq->inuse after migration for the corner case +where the avail_idx has already wrapped but used_idx not yet. + +Also change the type of the VirtQueue.inuse to unsigned int. This is +done to be consistent with other members representing sizes (VRing.num), +and because C99 guarantees max ring size < UINT_MAX but does not +guarantee max ring size < INT_MAX. + +Signed-off-by: Halil Pasic +Fixes: bccdef6b ("virtio: recalculate vq->inuse after migration") +CC: qemu-stable@nongnu.org +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Michael S. Tsirkin +Reviewed-by: Stefan Hajnoczi +--- + hw/virtio/virtio.c | 8 +++++--- + 1 file changed, 5 insertions(+), 3 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/virtio/virtio.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/virtio/virtio.c 2017-04-06 10:02:58.186463739 -0400 ++++ qemu-2.0.0+dfsg/hw/virtio/virtio.c 2017-04-06 10:02:58.186463739 -0400 +@@ -80,7 +80,7 @@ + + uint16_t queue_index; + +- int inuse; ++ unsigned int inuse; + + uint16_t vector; + void (*handle_output)(VirtIODevice *vdev, VirtQueue *vq); +@@ -993,9 +993,11 @@ + /* + * Some devices migrate VirtQueueElements that have been popped + * from the avail ring but not yet returned to the used ring. ++ * Since max ring size < UINT16_MAX it's safe to use modulo ++ * UINT16_MAX + 1 subtraction. + */ +- vdev->vq[i].inuse = vdev->vq[i].last_avail_idx - +- vring_used_idx(&vdev->vq[i]); ++ vdev->vq[i].inuse = (uint16_t)(vdev->vq[i].last_avail_idx - ++ vring_used_idx(&vdev->vq[i])); + if (vdev->vq[i].inuse > vdev->vq[i].vring.num) { + error_report("VQ %d size 0x%x < last_avail_idx 0x%x - " + "used_idx 0x%x", diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5403-6.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-5403-6.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5403-6.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-5403-6.patch 2017-04-06 14:03:46.000000000 +0000 @@ -0,0 +1,38 @@ +Description: make sure vdev->vq[i].inuse never goes below 0 + This is a work-around to fix live migrations after the patches for + CVE-2016-5403 were applied. The true root cause still needs to be + determined. +Origin: based on a patch by Len +Bug-Ubuntu: https://bugs.launchpad.net/ubuntu/+source/qemu/+bug/1647389 + +Index: qemu-2.0.0+dfsg/hw/virtio/virtio.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/virtio/virtio.c 2017-04-06 10:03:09.850609649 -0400 ++++ qemu-2.0.0+dfsg/hw/virtio/virtio.c 2017-04-06 10:03:38.234964641 -0400 +@@ -978,6 +978,7 @@ + + if (vdev->vq[i].pa) { + uint16_t nheads; ++ int inuse_tmp; + virtqueue_init(&vdev->vq[i]); + nheads = vring_avail_idx(&vdev->vq[i]) - vdev->vq[i].last_avail_idx; + /* Check it isn't doing very strange things with descriptor numbers. */ +@@ -996,12 +997,15 @@ + * Since max ring size < UINT16_MAX it's safe to use modulo + * UINT16_MAX + 1 subtraction. + */ +- vdev->vq[i].inuse = (uint16_t)(vdev->vq[i].last_avail_idx - ++ inuse_tmp = (int)(vdev->vq[i].last_avail_idx - + vring_used_idx(&vdev->vq[i])); ++ ++ vdev->vq[i].inuse = (inuse_tmp < 0 ? 0 : inuse_tmp); ++ + if (vdev->vq[i].inuse > vdev->vq[i].vring.num) { +- error_report("VQ %d size 0x%x < last_avail_idx 0x%x - " ++ error_report("VQ %d inuse %u size 0x%x < last_avail_idx 0x%x - " + "used_idx 0x%x", +- i, vdev->vq[i].vring.num, ++ i, vdev->vq[i].inuse, vdev->vq[i].vring.num, + vdev->vq[i].last_avail_idx, + vring_used_idx(&vdev->vq[i])); + return -1; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5403.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-5403.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-5403.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-5403.patch 2016-08-03 17:59:54.000000000 +0000 @@ -0,0 +1,64 @@ +Backport of: + +From afd9096eb1882f23929f5b5c177898ed231bac66 Mon Sep 17 00:00:00 2001 +From: Stefan Hajnoczi +Date: Tue, 19 Jul 2016 13:07:13 +0100 +Subject: [PATCH] virtio: error out if guest exceeds virtqueue size + +A broken or malicious guest can submit more requests than the virtqueue +size permits, causing unbounded memory allocation in QEMU. + +The guest can submit requests without bothering to wait for completion +and is therefore not bound by virtqueue size. This requires reusing +vring descriptors in more than one request, which is not allowed by the +VIRTIO 1.0 specification. + +In "3.2.1 Supplying Buffers to The Device", the VIRTIO 1.0 specification +says: + + 1. The driver places the buffer into free descriptor(s) in the + descriptor table, chaining as necessary + +and + + Note that the above code does not take precautions against the + available ring buffer wrapping around: this is not possible since the + ring buffer is the same size as the descriptor table, so step (1) will + prevent such a condition. + +This implies that placing more buffers into the virtqueue than the +descriptor table size is not allowed. + +QEMU is missing the check to prevent this case. Processing a request +allocates a VirtQueueElement leading to unbounded memory allocation +controlled by the guest. + +Exit with an error if the guest provides more requests than the +virtqueue size permits. This bounds memory allocation and makes the +buggy guest visible to the user. + +This patch fixes CVE-2016-5403 and was reported by Zhenhao Hong from 360 +Marvel Team, China. + +Reported-by: Zhenhao Hong +Signed-off-by: Stefan Hajnoczi +--- + hw/virtio/virtio.c | 5 +++++ + 1 files changed, 5 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/virtio/virtio.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/virtio/virtio.c 2016-08-03 13:59:06.426538406 -0400 ++++ qemu-2.0.0+dfsg/hw/virtio/virtio.c 2016-08-03 13:59:06.422538367 -0400 +@@ -472,6 +472,11 @@ + + max = vq->vring.num; + ++ if (vq->inuse >= vq->vring.num) { ++ error_report("Virtqueue size exceeded"); ++ exit(1); ++ } ++ + i = head = virtqueue_get_head(vq, vq->last_avail_idx++); + if (vq->vdev->guest_features & (1 << VIRTIO_RING_F_EVENT_IDX)) { + vring_avail_event(vq, vring_avail_idx(vq)); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-6351.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-6351.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-6351.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-6351.patch 2016-08-03 18:01:00.000000000 +0000 @@ -0,0 +1,93 @@ +Description: fix oob write access while reading ESP command +Origin: backport, http://git.qemu.org/?p=qemu.git;a=commit;h=926cde5f3e4d2504ed161ed0cb771ac7cad6fd11 +Origin: backport, http://git.qemu.org/?p=qemu.git;a=commit;h=cc96677469388bad3d66479379735cf75db069e3 +Bug-Debian: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=832621 + +Index: qemu-2.0.0+dfsg/hw/scsi/esp.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/scsi/esp.c 2016-08-03 14:00:03.783086983 -0400 ++++ qemu-2.0.0+dfsg/hw/scsi/esp.c 2016-08-03 14:00:03.779086945 -0400 +@@ -247,6 +247,8 @@ + len = s->dma_left; + if (s->do_cmd) { + trace_esp_do_dma(s->cmdlen, len); ++ assert (s->cmdlen <= sizeof(s->cmdbuf) && ++ len <= sizeof(s->cmdbuf) - s->cmdlen); + s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len); + s->ti_size = 0; + s->cmdlen = 0; +@@ -346,7 +348,7 @@ + s->dma_counter = dmalen; + + if (s->do_cmd) +- minlen = (dmalen < 32) ? dmalen : 32; ++ minlen = (dmalen < ESP_CMDBUF_SZ) ? dmalen : ESP_CMDBUF_SZ; + else if (s->ti_size < 0) + minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size; + else +@@ -443,7 +445,7 @@ + break; + case ESP_FIFO: + if (s->do_cmd) { +- if (s->cmdlen < TI_BUFSZ) { ++ if (s->cmdlen < ESP_CMDBUF_SZ) { + s->cmdbuf[s->cmdlen++] = val & 0xff; + } else { + trace_esp_error_fifo_overrun(); +@@ -566,7 +568,7 @@ + + const VMStateDescription vmstate_esp = { + .name ="esp", +- .version_id = 3, ++ .version_id = 4, + .minimum_version_id = 3, + .minimum_version_id_old = 3, + .fields = (VMStateField []) { +@@ -578,7 +580,8 @@ + VMSTATE_BUFFER(ti_buf, ESPState), + VMSTATE_UINT32(status, ESPState), + VMSTATE_UINT32(dma, ESPState), +- VMSTATE_BUFFER(cmdbuf, ESPState), ++ VMSTATE_PARTIAL_BUFFER(cmdbuf, ESPState, 16), ++ VMSTATE_BUFFER_START_MIDDLE_V(cmdbuf, ESPState, 16, 4), + VMSTATE_UINT32(cmdlen, ESPState), + VMSTATE_UINT32(do_cmd, ESPState), + VMSTATE_UINT32(dma_left, ESPState), +Index: qemu-2.0.0+dfsg/include/hw/scsi/esp.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/include/hw/scsi/esp.h 2016-08-03 14:00:03.783086983 -0400 ++++ qemu-2.0.0+dfsg/include/hw/scsi/esp.h 2016-08-03 14:00:03.779086945 -0400 +@@ -14,6 +14,7 @@ + + #define ESP_REGS 16 + #define TI_BUFSZ 16 ++#define ESP_CMDBUF_SZ 32 + + typedef struct ESPState ESPState; + +@@ -30,7 +31,7 @@ + SCSIBus bus; + SCSIDevice *current_dev; + SCSIRequest *current_req; +- uint8_t cmdbuf[TI_BUFSZ]; ++ uint8_t cmdbuf[ESP_CMDBUF_SZ]; + uint32_t cmdlen; + uint32_t do_cmd; + +Index: qemu-2.0.0+dfsg/include/migration/vmstate.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/include/migration/vmstate.h 2016-08-03 14:00:03.783086983 -0400 ++++ qemu-2.0.0+dfsg/include/migration/vmstate.h 2016-08-03 14:00:03.779086945 -0400 +@@ -722,8 +722,11 @@ + #define VMSTATE_PARTIAL_BUFFER(_f, _s, _size) \ + VMSTATE_STATIC_BUFFER(_f, _s, 0, NULL, 0, _size) + ++#define VMSTATE_BUFFER_START_MIDDLE_V(_f, _s, _start, _v) \ ++ VMSTATE_STATIC_BUFFER(_f, _s, _v, NULL, _start, sizeof(typeof_field(_s, _f))) ++ + #define VMSTATE_BUFFER_START_MIDDLE(_f, _s, _start) \ +- VMSTATE_STATIC_BUFFER(_f, _s, 0, NULL, _start, sizeof(typeof_field(_s, _f))) ++ VMSTATE_BUFFER_START_MIDDLE_V(_f, _s, _start, 0) + + #define VMSTATE_PARTIAL_VBUFFER(_f, _s, _size) \ + VMSTATE_VBUFFER(_f, _s, 0, NULL, 0, _size) diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-6833.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-6833.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-6833.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-6833.patch 2016-11-07 20:31:30.000000000 +0000 @@ -0,0 +1,33 @@ +From 6c352ca9b4ee3e1e286ea9e8434bd8e69ac7d0d8 Mon Sep 17 00:00:00 2001 +From: Li Qiang +Date: Mon, 8 Aug 2016 18:08:31 +0530 +Subject: [PATCH] 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 +Signed-off-by: Prasad J Pandit +Acked-by: Dmitry Fleytman +Signed-off-by: Jason Wang +--- + hw/net/vmxnet3.c | 4 ++++ + 1 files changed, 4 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/vmxnet3.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/vmxnet3.c 2016-11-07 15:31:28.802253504 -0500 ++++ qemu-2.0.0+dfsg/hw/net/vmxnet3.c 2016-11-07 15:31:28.798253460 -0500 +@@ -1070,6 +1070,10 @@ + { + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-6834.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-6834.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-6834.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-6834.patch 2016-11-07 20:31:35.000000000 +0000 @@ -0,0 +1,35 @@ +From 3b9717a62bf5882abaf6602c077cdbe63dffc35e Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Thu, 4 Aug 2016 13:00:14 +0530 +Subject: [PATCH] net: check fragment length during fragmentation + +Network transport abstraction layer supports packet fragmentation. +While fragmenting a packet, it checks for more fragments from +packet length and current fragment length. It is susceptible +to an infinite loop, if the current fragment length is zero. +Add check to avoid it. + +Reported-by: Li Qiang +Signed-off-by: Prasad J Pandit +Reviewed-by: Dmitry Fleytman +CC: qemu-stable@nongnu.org +Signed-off-by: Jason Wang +(cherry picked from commit ead315e43ea0c2ca3491209c6c8db8ce3f2bbe05) +Signed-off-by: Michael Roth +--- + hw/net/vmxnet_tx_pkt.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +Index: qemu-2.5+dfsg/hw/net/vmxnet_tx_pkt.c +=================================================================== +--- qemu-2.5+dfsg.orig/hw/net/vmxnet_tx_pkt.c 2016-11-07 10:54:23.347984625 -0500 ++++ qemu-2.5+dfsg/hw/net/vmxnet_tx_pkt.c 2016-11-07 10:54:23.347984625 -0500 +@@ -543,7 +543,7 @@ + + fragment_offset += fragment_len; + +- } while (more_frags); ++ } while (fragment_len && more_frags); + + return true; + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-6835.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-6835.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-6835.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-6835.patch 2016-11-07 20:31:42.000000000 +0000 @@ -0,0 +1,33 @@ +From 93060258ae748573ca7197204125a2670047896d Mon Sep 17 00:00:00 2001 +From: Li Qiang +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 +Signed-off-by: Prasad J Pandit +Reviewed-by: Dmitry Fleytman +Signed-off-by: Michael Roth +--- + hw/net/vmxnet_tx_pkt.c | 5 +++++ + 1 files changed, 5 insertions(+), 0 deletions(-) + +Index: qemu-2.5+dfsg/hw/net/vmxnet_tx_pkt.c +=================================================================== +--- qemu-2.5+dfsg.orig/hw/net/vmxnet_tx_pkt.c 2016-11-07 10:54:30.316062695 -0500 ++++ qemu-2.5+dfsg/hw/net/vmxnet_tx_pkt.c 2016-11-07 10:54:30.316062695 -0500 +@@ -177,6 +177,11 @@ + } + + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-6836.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-6836.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-6836.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-6836.patch 2016-11-07 20:31:51.000000000 +0000 @@ -0,0 +1,30 @@ +From fdda170e50b8af062cf5741e12c4fb5e57a2eacf Mon Sep 17 00:00:00 2001 +From: Li Qiang +Date: Thu, 11 Aug 2016 00:42:20 +0530 +Subject: [PATCH] net: vmxnet: initialise local tx descriptor + +In Vmxnet3 device emulator while processing transmit(tx) queue, +when it reaches end of packet, it calls vmxnet3_complete_packet. +In that local 'txcq_descr' object is not initialised, which could +leak host memory bytes a guest. + +Reported-by: Li Qiang +Signed-off-by: Prasad J Pandit +Reviewed-by: Dmitry Fleytman +Signed-off-by: Jason Wang +--- + hw/net/vmxnet3.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/vmxnet3.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/vmxnet3.c 2016-11-07 15:31:48.826477853 -0500 ++++ qemu-2.0.0+dfsg/hw/net/vmxnet3.c 2016-11-07 15:31:48.822477808 -0500 +@@ -498,6 +498,7 @@ + + VMXNET3_RING_DUMP(VMW_RIPRN, "TXC", qidx, &s->txq_descr[qidx].comp_ring); + ++ memset(&txcq_descr, 0, sizeof(txcq_descr)); + txcq_descr.txdIdx = tx_ridx; + txcq_descr.gen = vmxnet3_ring_curr_gen(&s->txq_descr[qidx].comp_ring); + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-6888.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-6888.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-6888.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-6888.patch 2016-11-07 20:31:56.000000000 +0000 @@ -0,0 +1,36 @@ +From cb3677cd50dcb07e74d0113337e40e9e3e14d728 Mon Sep 17 00:00:00 2001 +From: Li Qiang +Date: Mon, 22 Aug 2016 13:11:57 +0530 +Subject: [PATCH] net: vmxnet: use g_new for pkt initialisation + +When vmxnet transport abstraction layer initialises pkt, +the maximum fragmentation count is not checked. This could lead +to an integer overflow causing a NULL pointer dereference. +Replace g_malloc() with g_new() to catch the multiplication +overflow. + +Reported-by: Li Qiang +Signed-off-by: Prasad J Pandit +Acked-by: Dmitry Fleytman +Signed-off-by: Michael Roth +--- + hw/net/vmxnet_tx_pkt.c | 5 ++--- + 1 files changed, 2 insertions(+), 3 deletions(-) + +Index: qemu-2.5+dfsg/hw/net/vmxnet_tx_pkt.c +=================================================================== +--- qemu-2.5+dfsg.orig/hw/net/vmxnet_tx_pkt.c 2016-11-07 10:54:43.924215158 -0500 ++++ qemu-2.5+dfsg/hw/net/vmxnet_tx_pkt.c 2016-11-07 10:54:43.916215068 -0500 +@@ -59,10 +59,9 @@ + { + struct VmxnetTxPkt *p = g_malloc0(sizeof *p); + +- p->vec = g_malloc((sizeof *p->vec) * +- (max_frags + VMXNET_TX_PKT_PL_START_FRAG)); ++ p->vec = g_new(struct iovec, max_frags + VMXNET_TX_PKT_PL_START_FRAG); + +- p->raw = g_malloc((sizeof *p->raw) * max_frags); ++ p->raw = g_new(struct iovec, max_frags); + + p->max_payload_frags = max_frags; + p->max_raw_frags = max_frags; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7116-1.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-7116-1.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7116-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-7116-1.patch 2016-11-07 20:32:06.000000000 +0000 @@ -0,0 +1,181 @@ +Backport of: + +From 917e9a9816f34787391059c89ba5fb770fe22028 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +Date: Tue, 30 Aug 2016 19:11:05 +0200 +Subject: [PATCH] 9pfs: forbid illegal path names + +Empty path components don't make sense for most commands and may cause +undefined behavior, depending on the backend. + +Also, the walk request described in the 9P spec [1] clearly shows that +the client is supposed to send individual path components: the official +linux client never sends portions of path containing the / character for +example. + +Moreover, the 9P spec [2] also states that a system can decide to restrict +the set of supported characters used in path components, with an explicit +mention "to remove slashes from name components". + +This patch introduces a new name_is_illegal() helper that checks the +names sent by the client are not empty and don't contain unwanted chars. +Since 9pfs is only supported on linux hosts, only the / character is +checked at the moment. When support for other hosts (AKA. win32) is added, +other chars may need to be blacklisted as well. + +If a client sends an illegal path component, the request will fail and +ENOENT is returned to the client. + +[1] http://man.cat-v.org/plan_9/5/walk +[2] http://man.cat-v.org/plan_9/5/intro + +Suggested-by: Peter Maydell +Backport of: + +Signed-off-by: Greg Kurz +Reviewed-by: Eric Blake +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Peter Maydell +(cherry picked from commit fff39a7ad09da07ef490de05c92c91f22f8002f2) +Signed-off-by: Michael Roth +--- + hw/9pfs/9p.c | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 files changed, 56 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p.c 2016-11-07 15:32:03.374640848 -0500 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c 2016-11-07 15:32:03.370640804 -0500 +@@ -1226,6 +1226,11 @@ + return offset; + } + ++static bool name_is_illegal(const char *name) ++{ ++ return !*name || strchr(name, '/') != NULL; ++} ++ + static void v9fs_walk(void *opaque) + { + int name_idx; +@@ -1259,6 +1264,10 @@ + if (err < 0) { + goto out_nofid; + } ++ if (name_is_illegal(wnames[i].data)) { ++ err = -ENOENT; ++ goto out_nofid; ++ } + offset += err; + } + } else if (nwnames > P9_MAXWELEM) { +@@ -1453,6 +1462,11 @@ + } + trace_v9fs_lcreate(pdu->tag, pdu->id, dfid, flags, mode, gid); + ++ if (name_is_illegal(name.data)) { ++ err = -ENOENT; ++ goto out_nofid; ++ } ++ + fidp = get_fid(pdu, dfid); + if (fidp == NULL) { + err = -ENOENT; +@@ -2042,6 +2056,11 @@ + } + trace_v9fs_create(pdu->tag, pdu->id, fid, name.data, perm, mode); + ++ if (name_is_illegal(name.data)) { ++ err = -ENOENT; ++ goto out_nofid; ++ } ++ + fidp = get_fid(pdu, fid); + if (fidp == NULL) { + err = -EINVAL; +@@ -2207,6 +2226,11 @@ + } + trace_v9fs_symlink(pdu->tag, pdu->id, dfid, name.data, symname.data, gid); + ++ if (name_is_illegal(name.data)) { ++ err = -ENOENT; ++ goto out_nofid; ++ } ++ + dfidp = get_fid(pdu, dfid); + if (dfidp == NULL) { + err = -EINVAL; +@@ -2282,6 +2306,11 @@ + } + trace_v9fs_link(pdu->tag, pdu->id, dfid, oldfid, name.data); + ++ if (name_is_illegal(name.data)) { ++ err = -ENOENT; ++ goto out_nofid; ++ } ++ + dfidp = get_fid(pdu, dfid); + if (dfidp == NULL) { + err = -ENOENT; +@@ -2364,6 +2393,12 @@ + if (err < 0) { + goto out_nofid; + } ++ ++ if (name_is_illegal(name.data)) { ++ err = -ENOENT; ++ goto out_nofid; ++ } ++ + dfidp = get_fid(pdu, dfid); + if (dfidp == NULL) { + err = -EINVAL; +@@ -2470,6 +2505,12 @@ + if (err < 0) { + goto out_nofid; + } ++ ++ if (name_is_illegal(name.data)) { ++ err = -ENOENT; ++ goto out_nofid; ++ } ++ + fidp = get_fid(pdu, fid); + if (fidp == NULL) { + err = -ENOENT; +@@ -2582,6 +2623,11 @@ + goto out_err; + } + ++ if (name_is_illegal(old_name.data) || name_is_illegal(new_name.data)) { ++ err = -ENOENT; ++ goto out_err; ++ } ++ + v9fs_path_write_lock(s); + err = v9fs_complete_renameat(pdu, olddirfid, + &old_name, newdirfid, &new_name); +@@ -2794,6 +2840,11 @@ + } + trace_v9fs_mknod(pdu->tag, pdu->id, fid, mode, major, minor); + ++ if (name_is_illegal(name.data)) { ++ err = -ENOENT; ++ goto out_nofid; ++ } ++ + fidp = get_fid(pdu, fid); + if (fidp == NULL) { + err = -ENOENT; +@@ -2947,6 +2998,11 @@ + } + trace_v9fs_mkdir(pdu->tag, pdu->id, fid, name.data, mode, gid); + ++ if (name_is_illegal(name.data)) { ++ err = -ENOENT; ++ goto out_nofid; ++ } ++ + fidp = get_fid(pdu, fid); + if (fidp == NULL) { + err = -ENOENT; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7116-2.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-7116-2.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7116-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-7116-2.patch 2016-11-07 20:32:12.000000000 +0000 @@ -0,0 +1,160 @@ +Backport of: + +From b5191b2df7dc92a7a4f7fb4d18c37cf8aae38894 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +Date: Tue, 30 Aug 2016 19:13:11 +0200 +Subject: [PATCH] 9pfs: forbid . and .. in file names + +According to the 9P spec http://man.cat-v.org/plan_9/5/open about the +create request: + +The names . and .. are special; it is illegal to create files with these +names. + +This patch causes the create and lcreate requests to fail with EINVAL if +the file name is either "." or "..". + +Even if it isn't explicitly written in the spec, this patch extends the +checking to all requests that may cause a directory entry to be created: + + - mknod + - rename + - renameat + - mkdir + - link + - symlink + +The unlinkat request also gets patched for consistency (even if +rmdir("foo/..") is expected to fail according to POSIX.1-2001). + +The various error values come from the linux manual pages. + +Suggested-by: Peter Maydell +Signed-off-by: Greg Kurz +Reviewed-by: Eric Blake +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Peter Maydell +(cherry picked from commit 805b5d98c649d26fc44d2d7755a97f18e62b438a) +Signed-off-by: Michael Roth +--- + hw/9pfs/9p.c | 51 +++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 files changed, 51 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p.c 2016-11-07 15:32:10.194717259 -0500 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c 2016-11-07 15:32:10.190717214 -0500 +@@ -1467,6 +1467,11 @@ + goto out_nofid; + } + ++ if (!strcmp(".", name.data) || !strcmp("..", name.data)) { ++ err = -EEXIST; ++ goto out_nofid; ++ } ++ + fidp = get_fid(pdu, dfid); + if (fidp == NULL) { + err = -ENOENT; +@@ -2061,6 +2066,11 @@ + goto out_nofid; + } + ++ if (!strcmp(".", name.data) || !strcmp("..", name.data)) { ++ err = -EEXIST; ++ goto out_nofid; ++ } ++ + fidp = get_fid(pdu, fid); + if (fidp == NULL) { + err = -EINVAL; +@@ -2231,6 +2241,11 @@ + goto out_nofid; + } + ++ if (!strcmp(".", name.data) || !strcmp("..", name.data)) { ++ err = -EEXIST; ++ goto out_nofid; ++ } ++ + dfidp = get_fid(pdu, dfid); + if (dfidp == NULL) { + err = -EINVAL; +@@ -2311,6 +2326,11 @@ + goto out_nofid; + } + ++ if (!strcmp(".", name.data) || !strcmp("..", name.data)) { ++ err = -EEXIST; ++ goto out_nofid; ++ } ++ + dfidp = get_fid(pdu, dfid); + if (dfidp == NULL) { + err = -ENOENT; +@@ -2399,6 +2419,16 @@ + goto out_nofid; + } + ++ if (!strcmp(".", name.data)) { ++ err = -EINVAL; ++ goto out_nofid; ++ } ++ ++ if (!strcmp("..", name.data)) { ++ err = -ENOTEMPTY; ++ goto out_nofid; ++ } ++ + dfidp = get_fid(pdu, dfid); + if (dfidp == NULL) { + err = -EINVAL; +@@ -2511,6 +2541,11 @@ + goto out_nofid; + } + ++ if (!strcmp(".", name.data) || !strcmp("..", name.data)) { ++ err = -EISDIR; ++ goto out_nofid; ++ } ++ + fidp = get_fid(pdu, fid); + if (fidp == NULL) { + err = -ENOENT; +@@ -2628,6 +2663,12 @@ + goto out_err; + } + ++ if (!strcmp(".", old_name.data) || !strcmp("..", old_name.data) || ++ !strcmp(".", new_name.data) || !strcmp("..", new_name.data)) { ++ err = -EISDIR; ++ goto out_err; ++ } ++ + v9fs_path_write_lock(s); + err = v9fs_complete_renameat(pdu, olddirfid, + &old_name, newdirfid, &new_name); +@@ -2845,6 +2886,11 @@ + goto out_nofid; + } + ++ if (!strcmp(".", name.data) || !strcmp("..", name.data)) { ++ err = -EEXIST; ++ goto out_nofid; ++ } ++ + fidp = get_fid(pdu, fid); + if (fidp == NULL) { + err = -ENOENT; +@@ -3003,6 +3049,11 @@ + goto out_nofid; + } + ++ if (!strcmp(".", name.data) || !strcmp("..", name.data)) { ++ err = -EEXIST; ++ goto out_nofid; ++ } ++ + fidp = get_fid(pdu, fid); + if (fidp == NULL) { + err = -ENOENT; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7116-3.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-7116-3.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7116-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-7116-3.patch 2016-11-07 20:32:18.000000000 +0000 @@ -0,0 +1,127 @@ +Backport of: + +From 85d0a53c583656e5e37a8317f9119933c796847f Mon Sep 17 00:00:00 2001 +From: Greg Kurz +Date: Tue, 30 Aug 2016 17:02:27 +0200 +Subject: [PATCH] 9pfs: handle walk of ".." in the root directory + +The 9P spec at http://man.cat-v.org/plan_9/5/intro says: + +All directories must support walks to the directory .. (dot-dot) meaning +parent directory, although by convention directories contain no explicit +entry for .. or . (dot). The parent of the root directory of a server's +tree is itself. + +This means that a client cannot walk further than the root directory +exported by the server. In other words, if the client wants to walk +"/.." or "/foo/../..", the server should answer like the request was +to walk "/". + +This patch just does that: +- we cache the QID of the root directory at attach time +- during the walk we compare the QID of each path component with the root + QID to detect if we're in a "/.." situation +- if so, we skip the current component and go to the next one + +Signed-off-by: Greg Kurz +Reviewed-by: Eric Blake +Signed-off-by: Peter Maydell +(cherry picked from commit 56f101ecce0eafd09e2daf1c4eeb1377d6959261) +Signed-off-by: Michael Roth +--- + hw/9pfs/9p.c | 40 +++++++++++++++++++++++++++++++--------- + hw/9pfs/9p.h | 1 + + 2 files changed, 32 insertions(+), 9 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p.c 2016-11-07 15:32:16.510788024 -0500 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c 2016-11-07 15:32:16.502787934 -0500 +@@ -979,6 +979,7 @@ + goto out; + } + err += offset; ++ memcpy(&s->root_qid, &qid, sizeof(qid)); + trace_v9fs_attach_return(pdu->tag, pdu->id, + qid.type, qid.version, qid.path); + /* +@@ -1231,6 +1232,14 @@ + return !*name || strchr(name, '/') != NULL; + } + ++static bool not_same_qid(const V9fsQID *qid1, const V9fsQID *qid2) ++{ ++ return ++ qid1->type != qid2->type || ++ qid1->version != qid2->version || ++ qid1->path != qid2->path; ++} ++ + static void v9fs_walk(void *opaque) + { + int name_idx; +@@ -1246,6 +1255,7 @@ + V9fsFidState *newfidp = NULL; + V9fsPDU *pdu = opaque; + V9fsState *s = pdu->s; ++ V9fsQID qid; + + err = pdu_unmarshal(pdu, offset, "ddw", &fid, &newfid, &nwnames); + if (err < 0) { +@@ -1279,6 +1289,12 @@ + err = -ENOENT; + goto out_nofid; + } ++ ++ err = fid_to_qid(pdu, fidp, &qid); ++ if (err < 0) { ++ goto out; ++ } ++ + v9fs_path_init(&dpath); + v9fs_path_init(&path); + /* +@@ -1288,16 +1304,22 @@ + v9fs_path_copy(&dpath, &fidp->path); + v9fs_path_copy(&path, &fidp->path); + for (name_idx = 0; name_idx < nwnames; name_idx++) { +- err = v9fs_co_name_to_path(pdu, &dpath, wnames[name_idx].data, &path); +- if (err < 0) { +- goto out; +- } +- err = v9fs_co_lstat(pdu, &path, &stbuf); +- if (err < 0) { +- goto out; ++ if (not_same_qid(&pdu->s->root_qid, &qid) || ++ strcmp("..", wnames[name_idx].data)) { ++ err = v9fs_co_name_to_path(pdu, &dpath, wnames[name_idx].data, ++ &path); ++ if (err < 0) { ++ goto out; ++ } ++ ++ err = v9fs_co_lstat(pdu, &path, &stbuf); ++ if (err < 0) { ++ goto out; ++ } ++ stat_to_qid(&stbuf, &qid); ++ v9fs_path_copy(&dpath, &path); + } +- stat_to_qid(&stbuf, &qids[name_idx]); +- v9fs_path_copy(&dpath, &path); ++ memcpy(&qids[name_idx], &qid, sizeof(qid)); + } + if (fid == newfid) { + BUG_ON(fidp->fid_type != P9_FID_NONE); +Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p.h 2016-11-07 15:32:16.510788024 -0500 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.h 2016-11-07 15:32:16.506787979 -0500 +@@ -225,6 +225,7 @@ + int32_t root_fid; + Error *migration_blocker; + V9fsConf fsconf; ++ V9fsQID root_qid; + } V9fsState; + + typedef struct V9fsStatState { diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7116-4.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-7116-4.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7116-4.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-7116-4.patch 2016-11-07 20:32:24.000000000 +0000 @@ -0,0 +1,52 @@ +Backport of: + +From 5e2c6fe7cc5314c13d96069328b603c40dc12b41 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +Date: Fri, 16 Sep 2016 11:44:49 +0200 +Subject: [PATCH] 9pfs: fix potential segfault during walk +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf8 +Content-Transfer-Encoding: 8bit + +If the call to fid_to_qid() returns an error, we will call v9fs_path_free() +on uninitialized paths. + +It is a regression introduced by the following commit: + +56f101ecce0e 9pfs: handle walk of ".." in the root directory + +Let's fix this by initializing dpath and path before calling fid_to_qid(). + +Signed-off-by: Greg Kurz +Reviewed-by: Cédric Le Goater +[groug: updated the changelog to indicate this is regression and to provide + the offending commit SHA1] +Signed-off-by: Greg Kurz + +(cherry picked from commit 13fd08e631ec0c3ff5ad1bdcb6a4474c7d9a024f) +Signed-off-by: Michael Roth +--- + hw/9pfs/9p.c | 5 +++-- + 1 files changed, 3 insertions(+), 2 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p.c 2016-11-07 15:32:22.422854261 -0500 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c 2016-11-07 15:32:22.418854216 -0500 +@@ -1290,13 +1290,14 @@ + goto out_nofid; + } + ++ v9fs_path_init(&dpath); ++ v9fs_path_init(&path); ++ + err = fid_to_qid(pdu, fidp, &qid); + if (err < 0) { + goto out; + } + +- v9fs_path_init(&dpath); +- v9fs_path_init(&path); + /* + * Both dpath and path initially poin to fidp. + * Needed to handle request with nwnames == 0 diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7155.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-7155.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7155.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-7155.patch 2016-11-07 20:32:34.000000000 +0000 @@ -0,0 +1,83 @@ +From da99530e410349d672e792e820b355a648d430fa Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Wed, 31 Aug 2016 12:19:29 +0530 +Subject: [PATCH] vmw_pvscsi: check page count while initialising descriptor rings + +Vmware Paravirtual SCSI emulation uses command descriptors to +process SCSI commands. These descriptors come with their ring +buffers. A guest could set the page count for these rings to +an arbitrary value, leading to infinite loop or OOB access. +Add check to avoid it. + +Reported-by: Tom Victor +Signed-off-by: Prasad J Pandit +Message-Id: <1472626169-12989-1-git-send-email-ppandit@redhat.com> +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +(cherry picked from commit 7f61f4690dd153be98900a2a508b88989e692753) +Signed-off-by: Michael Roth +--- + hw/scsi/vmw_pvscsi.c | 19 +++++++++---------- + 1 files changed, 9 insertions(+), 10 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/scsi/vmw_pvscsi.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/scsi/vmw_pvscsi.c 2016-11-07 15:32:32.430966391 -0500 ++++ qemu-2.0.0+dfsg/hw/scsi/vmw_pvscsi.c 2016-11-07 15:32:32.426966346 -0500 +@@ -126,7 +126,7 @@ + return log; + } + +-static int ++static void + pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri) + { + int i; +@@ -134,10 +134,6 @@ + uint32_t req_ring_size, cmp_ring_size; + m->rs_pa = ri->ringsStatePPN << VMW_PAGE_SHIFT; + +- if ((ri->reqRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES) +- || (ri->cmpRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES)) { +- return -1; +- } + req_ring_size = ri->reqRingNumPages * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE; + cmp_ring_size = ri->cmpRingNumPages * PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE; + txr_len_log2 = pvscsi_log2(req_ring_size - 1); +@@ -169,8 +165,6 @@ + + /* Flush ring state page changes */ + smp_wmb(); +- +- return 0; + } + + static int +@@ -717,7 +711,7 @@ + + trace_pvscsi_tx_rings_num_pages("Confirm Ring", rc->cmpRingNumPages); + for (i = 0; i < rc->cmpRingNumPages; i++) { +- trace_pvscsi_tx_rings_ppn("Confirm Ring", rc->reqRingPPNs[i]); ++ trace_pvscsi_tx_rings_ppn("Confirm Ring", rc->cmpRingPPNs[i]); + } + } + +@@ -750,11 +744,16 @@ + + trace_pvscsi_on_cmd_arrived("PVSCSI_CMD_SETUP_RINGS"); + +- pvscsi_dbg_dump_tx_rings_config(rc); +- if (pvscsi_ring_init_data(&s->rings, rc) < 0) { ++ if (!rc->reqRingNumPages ++ || rc->reqRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES ++ || !rc->cmpRingNumPages ++ || rc->cmpRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES) { + return PVSCSI_COMMAND_PROCESSING_FAILED; + } + ++ pvscsi_dbg_dump_tx_rings_config(rc); ++ pvscsi_ring_init_data(&s->rings, rc); ++ + s->rings_info_valid = TRUE; + return PVSCSI_COMMAND_PROCESSING_SUCCEEDED; + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7156.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-7156.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7156.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-7156.patch 2016-11-07 20:32:41.000000000 +0000 @@ -0,0 +1,61 @@ +From 49adc5d3f8c6bb75e55ebfeab109c5c37dea65e8 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Tue, 6 Sep 2016 02:20:43 +0530 +Subject: [PATCH] scsi: pvscsi: limit loop to fetch SG list + +In PVSCSI paravirtual SCSI bus, pvscsi_convert_sglist can take a very +long time or go into an infinite loop due to two different bugs: + +1) the request descriptor data length is defined to be 64 bit. While +building SG list from a request descriptor, it gets truncated to 32bit +in routine 'pvscsi_convert_sglist'. This could lead to an infinite loop +situation large 'dataLen' values when data_length is cast to uint32_t and +chunk_size becomes always zero. Fix this by removing the incorrect cast. + +2) pvscsi_get_next_sg_elem can be called arbitrarily many times if the +element has a zero length. Get out of the loop early when this happens, +by introducing an upper limit on the number of SG list elements. + +Reported-by: Li Qiang +Signed-off-by: Prasad J Pandit +Message-Id: <1473108643-12983-1-git-send-email-ppandit@redhat.com> +Signed-off-by: Paolo Bonzini +--- + hw/scsi/vmw_pvscsi.c | 11 ++++++----- + 1 files changed, 6 insertions(+), 5 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/scsi/vmw_pvscsi.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/scsi/vmw_pvscsi.c 2016-11-07 15:32:39.587046567 -0500 ++++ qemu-2.0.0+dfsg/hw/scsi/vmw_pvscsi.c 2016-11-07 15:32:39.583046521 -0500 +@@ -39,6 +39,8 @@ + #define PVSCSI_MAX_DEVS (64) + #define PVSCSI_MSIX_NUM_VECTORS (1) + ++#define PVSCSI_MAX_SG_ELEM 2048 ++ + #define PVSCSI_MAX_CMD_DATA_WORDS \ + (sizeof(PVSCSICmdDescSetupRings)/sizeof(uint32_t)) + +@@ -599,17 +601,16 @@ + static void + pvscsi_convert_sglist(PVSCSIRequest *r) + { +- int chunk_size; ++ uint32_t chunk_size, elmcnt = 0; + uint64_t data_length = r->req.dataLen; + PVSCSISGState sg = r->sg; +- while (data_length) { +- while (!sg.resid) { ++ while (data_length && elmcnt < PVSCSI_MAX_SG_ELEM) { ++ while (!sg.resid && elmcnt++ < PVSCSI_MAX_SG_ELEM) { + pvscsi_get_next_sg_elem(&sg); + trace_pvscsi_convert_sglist(r->req.context, r->sg.dataAddr, + r->sg.resid); + } +- assert(data_length > 0); +- chunk_size = MIN((unsigned) data_length, sg.resid); ++ chunk_size = MIN(data_length, sg.resid); + if (chunk_size) { + qemu_sglist_add(&r->sgl, sg.dataAddr, chunk_size); + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7161.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-7161.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7161.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-7161.patch 2016-11-07 20:32:48.000000000 +0000 @@ -0,0 +1,32 @@ +From a0d1cbdacff5df4ded16b753b38fdd9da6092968 Mon Sep 17 00:00:00 2001 +From: chaojianhu +Date: Tue, 9 Aug 2016 11:52:54 +0800 +Subject: [PATCH] hw/net: Fix a heap overflow in xlnx.xps-ethernetlite + +The .receive callback of xlnx.xps-ethernetlite doesn't check the length +of data before calling memcpy. As a result, the NetClientState object in +heap will be overflowed. All versions of qemu with xlnx.xps-ethernetlite +will be affected. + +Reported-by: chaojianhu +Signed-off-by: chaojianhu +Signed-off-by: Jason Wang +--- + hw/net/xilinx_ethlite.c | 4 ++++ + 1 files changed, 4 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/xilinx_ethlite.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/xilinx_ethlite.c 2016-11-07 15:32:47.023129879 -0500 ++++ qemu-2.0.0+dfsg/hw/net/xilinx_ethlite.c 2016-11-07 15:32:47.019129834 -0500 +@@ -193,6 +193,10 @@ + } + + D(qemu_log("%s %zd rxbase=%x\n", __func__, size, rxbase)); ++ if (size > (R_MAX - R_RX_BUF0 - rxbase) * 4) { ++ D(qemu_log("ethlite packet is too big, size=%x\n", size)); ++ return -1; ++ } + memcpy(&s->regs[rxbase + R_RX_BUF0], buf, size); + + s->regs[rxbase + R_RX_CTRL0] |= CTRL_S; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7170.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-7170.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7170.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-7170.patch 2016-11-07 20:36:54.000000000 +0000 @@ -0,0 +1,55 @@ +Backport of: + +From 167d97a3def77ee2dbf6e908b0ecbfe2103977db Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Thu, 8 Sep 2016 18:15:54 +0530 +Subject: [PATCH] vmsvga: correct bitmap and pixmap size checks + +When processing svga command DEFINE_CURSOR in vmsvga_fifo_run, +the computed BITMAP and PIXMAP size are checked against the +'cursor.mask[]' and 'cursor.image[]' array sizes in bytes. +Correct these checks to avoid OOB memory access. + +Reported-by: Qinghao Tang +Reported-by: Li Qiang +Signed-off-by: Prasad J Pandit +Message-id: 1473338754-15430-1-git-send-email-ppandit@redhat.com +Signed-off-by: Gerd Hoffmann +--- + hw/display/vmware_vga.c | 12 +++++++----- + 1 files changed, 7 insertions(+), 5 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/display/vmware_vga.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/display/vmware_vga.c 2016-11-07 15:33:01.259289378 -0500 ++++ qemu-2.0.0+dfsg/hw/display/vmware_vga.c 2016-11-07 15:36:48.537835770 -0500 +@@ -482,10 +482,10 @@ + #endif + + struct vmsvga_cursor_definition_s { +- int width; +- int height; ++ uint32_t width; ++ uint32_t height; + int id; +- int bpp; ++ uint32_t bpp; + int hot_x; + int hot_y; + uint32_t mask[1024]; +@@ -674,8 +674,13 @@ + cursor.bpp = vmsvga_fifo_read(s); + + args = SVGA_BITMAP_SIZE(x, y) + SVGA_PIXMAP_SIZE(x, y, cursor.bpp); +- if (SVGA_BITMAP_SIZE(x, y) > sizeof cursor.mask || +- SVGA_PIXMAP_SIZE(x, y, cursor.bpp) > sizeof cursor.image) { ++ if (cursor.width > 256 ++ || cursor.height > 256 ++ || cursor.bpp > 32 ++ || SVGA_BITMAP_SIZE(x, y) ++ > sizeof(cursor.mask) / sizeof(cursor.mask[0]) ++ || SVGA_PIXMAP_SIZE(x, y, cursor.bpp) ++ > sizeof(cursor.image) / sizeof(cursor.image[0])) { + goto badcmd; + } + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7421.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-7421.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7421.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-7421.patch 2016-11-07 20:39:30.000000000 +0000 @@ -0,0 +1,37 @@ +Backport of: + +From d251157ac1928191af851d199a9ff255d330bec9 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Wed, 14 Sep 2016 15:09:12 +0530 +Subject: [PATCH] scsi: pvscsi: limit process IO loop to ring size + +Vmware Paravirtual SCSI emulator while processing IO requests +could run into an infinite loop if 'pvscsi_ring_pop_req_descr' +always returned positive value. Limit IO loop to the ring size. + +Cc: qemu-stable@nongnu.org +Reported-by: Li Qiang +Signed-off-by: Prasad J Pandit +Message-Id: <1473845952-30785-1-git-send-email-ppandit@redhat.com> +Signed-off-by: Paolo Bonzini +--- + hw/scsi/vmw_pvscsi.c | 5 ++++- + 1 files changed, 4 insertions(+), 1 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/scsi/vmw_pvscsi.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/scsi/vmw_pvscsi.c 2016-11-07 15:37:32.782331478 -0500 ++++ qemu-2.0.0+dfsg/hw/scsi/vmw_pvscsi.c 2016-11-07 15:38:11.522765520 -0500 +@@ -221,8 +221,11 @@ + pvscsi_ring_pop_req_descr(PVSCSIRingInfo *mgr) + { + uint32_t ready_ptr = RS_GET_FIELD(mgr->rs_pa, reqProdIdx); ++ uint32_t ring_size = PVSCSI_MAX_NUM_PAGES_REQ_RING ++ * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE; + +- if (ready_ptr != mgr->consumed_ptr) { ++ if (ready_ptr != mgr->consumed_ptr ++ && ready_ptr - mgr->consumed_ptr < ring_size) { + uint32_t next_ready_ptr = + mgr->consumed_ptr++ & mgr->txr_len_mask; + uint32_t next_ready_page = diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7908.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-7908.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7908.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-7908.patch 2016-11-07 20:42:31.000000000 +0000 @@ -0,0 +1,49 @@ +From 070c4b92b8cd5390889716677a0b92444d6e087a Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Thu, 22 Sep 2016 16:02:37 +0530 +Subject: [PATCH] net: mcf: limit buffer descriptor count + +ColdFire Fast Ethernet Controller uses buffer descriptors to manage +data flow to/fro receive & transmit queues. While transmitting +packets, it could continue to read buffer descriptors if a buffer +descriptor has length of zero and has crafted values in bd.flags. +Set upper limit to number of buffer descriptors. + +Reported-by: Li Qiang +Signed-off-by: Prasad J Pandit +Reviewed-by: Paolo Bonzini +Signed-off-by: Jason Wang +--- + hw/net/mcf_fec.c | 5 +++-- + 1 files changed, 3 insertions(+), 2 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/mcf_fec.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/mcf_fec.c 2016-11-07 15:42:29.345654125 -0500 ++++ qemu-2.0.0+dfsg/hw/net/mcf_fec.c 2016-11-07 15:42:29.341654080 -0500 +@@ -21,6 +21,7 @@ + #define DPRINTF(fmt, ...) do {} while(0) + #endif + ++#define FEC_MAX_DESC 1024 + #define FEC_MAX_FRAME_SIZE 2032 + + typedef struct { +@@ -147,7 +148,7 @@ + uint32_t addr; + mcf_fec_bd bd; + int frame_size; +- int len; ++ int len, descnt = 0; + uint8_t frame[FEC_MAX_FRAME_SIZE]; + uint8_t *ptr; + +@@ -155,7 +156,7 @@ + ptr = frame; + frame_size = 0; + addr = s->tx_descriptor; +- while (1) { ++ while (descnt++ < FEC_MAX_DESC) { + mcf_fec_read_bd(&bd, addr); + DPRINTF("tx_bd %x flags %04x len %d data %08x\n", + addr, bd.flags, bd.length, bd.data); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7909.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-7909.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-7909.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-7909.patch 2016-11-07 20:42:39.000000000 +0000 @@ -0,0 +1,34 @@ +From 34e29ce754c02bb6b3bdd244fbb85033460feaff Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Fri, 30 Sep 2016 00:27:33 +0530 +Subject: [PATCH] net: pcnet: check rx/tx descriptor ring length + +The AMD PC-Net II emulator has set of control and status(CSR) +registers. Of these, CSR76 and CSR78 hold receive and transmit +descriptor ring length respectively. This ring length could range +from 1 to 65535. Setting ring length to zero leads to an infinite +loop in pcnet_rdra_addr() or pcnet_transmit(). Add check to avoid it. + +Reported-by: Li Qiang +Signed-off-by: Prasad J Pandit +Signed-off-by: Jason Wang +--- + hw/net/pcnet.c | 3 +++ + 1 files changed, 3 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/pcnet.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/pcnet.c 2016-11-07 15:42:37.653747208 -0500 ++++ qemu-2.0.0+dfsg/hw/net/pcnet.c 2016-11-07 15:42:37.653747208 -0500 +@@ -1451,8 +1451,11 @@ + case 47: /* POLLINT */ + case 72: + case 74: ++ break; + case 76: /* RCVRL */ + case 78: /* XMTRL */ ++ val = (val > 0) ? val : 512; ++ break; + case 112: + if (CSR_STOP(s) || CSR_SPND(s)) + break; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-8576.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-8576.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-8576.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-8576.patch 2016-11-07 20:44:15.000000000 +0000 @@ -0,0 +1,65 @@ +From 05f43d44e4bc26611ce25fd7d726e483f73363ce Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Mon, 10 Oct 2016 12:46:22 +0200 +Subject: [PATCH] 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. + +Reported-by: Li Qiang +Tested-by: P J P +Signed-off-by: Gerd Hoffmann +Message-id: 1476096382-7981-1-git-send-email-kraxel@redhat.com +--- + hw/usb/hcd-xhci.c | 10 ++++++++++ + 1 files changed, 10 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/usb/hcd-xhci.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/usb/hcd-xhci.c 2016-11-07 15:44:13.102816603 -0500 ++++ qemu-2.0.0+dfsg/hw/usb/hcd-xhci.c 2016-11-07 15:44:13.098816560 -0500 +@@ -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) +@@ -979,6 +981,7 @@ + dma_addr_t *addr) + { + PCIDevice *pci_dev = PCI_DEVICE(xhci); ++ uint32_t link_cnt = 0; + + while (1) { + TRBType type; +@@ -1005,6 +1008,9 @@ + 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; +@@ -1022,6 +1028,7 @@ + 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; +@@ -1037,6 +1044,9 @@ + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-8577.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-8577.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-8577.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-8577.patch 2016-11-07 20:44:23.000000000 +0000 @@ -0,0 +1,38 @@ +Backport of: + +From e95c9a493a5a8d6f969e86c9f19f80ffe6587e19 Mon Sep 17 00:00:00 2001 +From: Li Qiang +Date: Mon, 17 Oct 2016 14:13:58 +0200 +Subject: [PATCH] 9pfs: fix potential host memory leak in v9fs_read + +In 9pfs read dispatch function, it doesn't free two QEMUIOVector +object thus causing potential memory leak. This patch avoid this. + +Signed-off-by: Li Qiang +Signed-off-by: Greg Kurz +--- + hw/9pfs/9p.c | 5 +++-- + 1 files changed, 3 insertions(+), 2 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p.c 2016-11-07 15:44:20.886903815 -0500 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c 2016-11-07 15:44:20.882903770 -0500 +@@ -1783,14 +1783,15 @@ + if (len < 0) { + /* IO error return the error */ + err = len; +- goto out; ++ goto out_free_iovec; + } + } while (count < max_count && len > 0); + err = pdu_marshal(pdu, offset, "d", count); + if (err < 0) { +- goto out; ++ goto out_free_iovec; + } + err += offset + count; ++out_free_iovec: + qemu_iovec_destroy(&qiov); + qemu_iovec_destroy(&qiov_full); + } else if (fidp->fid_type == P9_FID_XATTR) { diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-8578.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-8578.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-8578.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-8578.patch 2016-11-07 20:44:29.000000000 +0000 @@ -0,0 +1,57 @@ +Backport of: + +From ba42ebb863ab7d40adc79298422ed9596df8f73a Mon Sep 17 00:00:00 2001 +From: Li Qiang +Date: Mon, 17 Oct 2016 14:13:58 +0200 +Subject: [PATCH] 9pfs: allocate space for guest originated empty strings + +If a guest sends an empty string paramater to any 9P operation, the current +code unmarshals it into a V9fsString equal to { .size = 0, .data = NULL }. + +This is unfortunate because it can cause NULL pointer dereference to happen +at various locations in the 9pfs code. And we don't want to check str->data +everywhere we pass it to strcmp() or any other function which expects a +dereferenceable pointer. + +This patch enforces the allocation of genuine C empty strings instead, so +callers don't have to bother. + +Out of all v9fs_iov_vunmarshal() users, only v9fs_xattrwalk() checks if +the returned string is empty. It now uses v9fs_string_size() since +name.data cannot be NULL anymore. + +Signed-off-by: Li Qiang +[groug, rewritten title and changelog, + fix empty string check in v9fs_xattrwalk()] +Signed-off-by: Greg Kurz +--- + fsdev/9p-iov-marshal.c | 2 +- + hw/9pfs/9p.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +Index: qemu-2.0.0+dfsg/fsdev/virtio-9p-marshal.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/fsdev/virtio-9p-marshal.c 2016-11-07 15:44:27.842981751 -0500 ++++ qemu-2.0.0+dfsg/fsdev/virtio-9p-marshal.c 2016-11-07 15:44:27.838981705 -0500 +@@ -166,7 +166,7 @@ + str->data = g_malloc(str->size + 1); + copied = v9fs_unpack(str->data, out_sg, out_num, offset, + str->size); +- if (copied > 0) { ++ if (copied >= 0) { + str->data[str->size] = 0; + } else { + v9fs_string_free(str); +Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p.c 2016-11-07 15:44:27.842981751 -0500 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c 2016-11-07 15:44:27.838981705 -0500 +@@ -3132,7 +3132,7 @@ + goto out; + } + v9fs_path_copy(&xattr_fidp->path, &file_fidp->path); +- if (name.data == NULL) { ++ if (!v9fs_string_size(&name)) { + /* + * listxattr request. Get the size first + */ diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-8667.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-8667.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-8667.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-8667.patch 2017-04-05 15:22:54.000000000 +0000 @@ -0,0 +1,35 @@ +From c0a3172fa6bbddcc73192f2a2c48d0bf3a7ba61c Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +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 +Signed-off-by: Prasad J Pandit +Tested-by: Hervé Poussineau +Signed-off-by: Yongbok Kim +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-8669.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-8669.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-8669.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-8669.patch 2017-04-05 15:22:57.000000000 +0000 @@ -0,0 +1,34 @@ +From 3592fe0c919cf27a81d8e9f9b4f269553418bb01 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +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 +Signed-off-by: Prasad J Pandit +Message-Id: <1476251888-20238-1-git-send-email-ppandit@redhat.com> +Signed-off-by: Paolo Bonzini +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-8909.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-8909.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-8909.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-8909.patch 2016-11-07 20:45:44.000000000 +0000 @@ -0,0 +1,35 @@ +From 0c0fc2b5fd534786051889459848764edd798050 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Thu, 20 Oct 2016 13:10:24 +0530 +Subject: [PATCH] audio: intel-hda: check stream entry count during transfer + +Intel HDA emulator uses stream of buffers during DMA data +transfers. Each entry has buffer length and buffer pointer +position, which are used to derive bytes to 'copy'. If this +length and buffer pointer were to be same, 'copy' could be +set to zero(0), leading to an infinite loop. Add check to +avoid it. + +Reported-by: Huawei PSIRT +Signed-off-by: Prasad J Pandit +Reviewed-by: Stefan Hajnoczi +Message-id: 1476949224-6865-1-git-send-email-ppandit@redhat.com +Signed-off-by: Gerd Hoffmann +--- + hw/audio/intel-hda.c | 3 ++- + 1 files changed, 2 insertions(+), 1 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/audio/intel-hda.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/audio/intel-hda.c 2016-11-07 15:45:42.767821196 -0500 ++++ qemu-2.0.0+dfsg/hw/audio/intel-hda.c 2016-11-07 15:45:42.763821151 -0500 +@@ -413,7 +413,8 @@ + } + + left = len; +- while (left > 0) { ++ s = st->bentries; ++ while (left > 0 && s-- > 0) { + copy = left; + if (copy > st->bsize - st->lpib) + copy = st->bsize - st->lpib; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-8910.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-8910.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-8910.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-8910.patch 2016-11-07 20:45:53.000000000 +0000 @@ -0,0 +1,31 @@ +From c7c35916692fe010fef25ac338443d3fe40be225 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Fri, 21 Oct 2016 17:39:29 +0530 +Subject: [PATCH] net: rtl8139: limit processing of ring descriptors + +RTL8139 ethernet controller in C+ mode supports multiple +descriptor rings, each with maximum of 64 descriptors. While +processing transmit descriptor ring in 'rtl8139_cplus_transmit', +it does not limit the descriptor count and runs forever. Add +check to avoid it. + +Reported-by: Andrew Henderson +Signed-off-by: Prasad J Pandit +Signed-off-by: Jason Wang +--- + hw/net/rtl8139.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/rtl8139.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/rtl8139.c 2016-11-07 15:45:51.123914816 -0500 ++++ qemu-2.0.0+dfsg/hw/net/rtl8139.c 2016-11-07 15:45:51.119914771 -0500 +@@ -2432,7 +2432,7 @@ + { + int txcount = 0; + +- while (rtl8139_cplus_transmit_one(s)) ++ while (txcount < 64 && rtl8139_cplus_transmit_one(s)) + { + ++txcount; + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9101.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9101.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9101.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9101.patch 2016-11-07 20:46:02.000000000 +0000 @@ -0,0 +1,27 @@ +From 2634ab7fe29b3f75d0865b719caf8f310d634aae Mon Sep 17 00:00:00 2001 +From: Li Qiang +Date: Sat, 8 Oct 2016 05:07:25 -0700 +Subject: [PATCH] net: eepro100: fix memory leak in device uninit + +The exit dispatch of eepro100 network card device doesn't free +the 's->vmstate' field which was allocated in device realize thus +leading a host memory leak. This patch avoid this. + +Signed-off-by: Li Qiang +Signed-off-by: Jason Wang +--- + hw/net/eepro100.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/eepro100.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/eepro100.c 2016-11-07 15:46:00.460019417 -0500 ++++ qemu-2.0.0+dfsg/hw/net/eepro100.c 2016-11-07 15:46:00.460019417 -0500 +@@ -1864,6 +1864,7 @@ + memory_region_destroy(&s->io_bar); + memory_region_destroy(&s->flash_bar); + vmstate_unregister(&pci_dev->qdev, s->vmstate, s); ++ g_free(s->vmstate); + eeprom93xx_free(&pci_dev->qdev, s->eeprom); + qemu_del_nic(s->nic); + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9102.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9102.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9102.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9102.patch 2016-11-07 20:47:10.000000000 +0000 @@ -0,0 +1,33 @@ +Backport of: + +From ff55e94d23ae94c8628b0115320157c763eb3e06 Mon Sep 17 00:00:00 2001 +From: Li Qiang +Date: Mon, 17 Oct 2016 14:13:58 +0200 +Subject: [PATCH] 9pfs: fix memory leak in v9fs_xattrcreate + +The 'fs.xattr.value' field in V9fsFidState object doesn't consider the +situation that this field has been allocated previously. Every time, it +will be allocated directly. This leads to a host memory leak issue if +the client sends another Txattrcreate message with the same fid number +before the fid from the previous time got clunked. + +Signed-off-by: Li Qiang +Reviewed-by: Greg Kurz +[groug, updated the changelog to indicate how the leak can occur] +Signed-off-by: Greg Kurz +--- + hw/9pfs/9p.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p.c 2016-11-07 15:47:08.404780658 -0500 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c 2016-11-07 15:47:08.400780614 -0500 +@@ -3241,6 +3241,7 @@ + xattr_fidp->fs.xattr.flags = flags; + v9fs_string_init(&xattr_fidp->fs.xattr.name); + v9fs_string_copy(&xattr_fidp->fs.xattr.name, &name); ++ g_free(xattr_fidp->fs.xattr.value); + xattr_fidp->fs.xattr.value = g_malloc0(size); + err = offset; + put_fid(pdu, file_fidp); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9103.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9103.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9103.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9103.patch 2016-11-07 20:47:04.000000000 +0000 @@ -0,0 +1,31 @@ +Backport of: + +From eb687602853b4ae656e9236ee4222609f3a6887d Mon Sep 17 00:00:00 2001 +From: Li Qiang +Date: Mon, 17 Oct 2016 14:13:58 +0200 +Subject: [PATCH] 9pfs: fix information leak in xattr read + +9pfs uses g_malloc() to allocate the xattr memory space, if the guest +reads this memory before writing to it, this will leak host heap memory +to the guest. This patch avoid this. + +Signed-off-by: Li Qiang +Reviewed-by: Greg Kurz +Signed-off-by: Greg Kurz +--- + hw/9pfs/9p.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p.c 2016-11-07 15:47:02.604715675 -0500 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c 2016-11-07 15:47:02.600715630 -0500 +@@ -3241,7 +3241,7 @@ + xattr_fidp->fs.xattr.flags = flags; + v9fs_string_init(&xattr_fidp->fs.xattr.name); + v9fs_string_copy(&xattr_fidp->fs.xattr.name, &name); +- xattr_fidp->fs.xattr.value = g_malloc(size); ++ xattr_fidp->fs.xattr.value = g_malloc0(size); + err = offset; + put_fid(pdu, file_fidp); + out_nofid: diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9104.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9104.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9104.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9104.patch 2016-11-07 20:47:16.000000000 +0000 @@ -0,0 +1,89 @@ +Backport of: + +From 7e55d65c56a03dcd2c5d7c49d37c5a74b55d4bd6 Mon Sep 17 00:00:00 2001 +From: Li Qiang +Date: Tue, 1 Nov 2016 12:00:40 +0100 +Subject: [PATCH] 9pfs: fix integer overflow issue in xattr read/write +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf8 +Content-Transfer-Encoding: 8bit + +The v9fs_xattr_read() and v9fs_xattr_write() are passed a guest +originated offset: they must ensure this offset does not go beyond +the size of the extended attribute that was set in v9fs_xattrcreate(). +Unfortunately, the current code implement these checks with unsafe +calculations on 32 and 64 bit values, which may allow a malicious +guest to cause OOB access anyway. + +Fix this by comparing the offset and the xattr size, which are +both uint64_t, before trying to compute the effective number of bytes +to read or write. + +Suggested-by: Greg Kurz +Signed-off-by: Li Qiang +Reviewed-by: Greg Kurz +Reviewed-By: Guido Günther +Signed-off-by: Greg Kurz +--- + hw/9pfs/9p.c | 32 ++++++++++++-------------------- + 1 files changed, 12 insertions(+), 20 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p.c 2016-11-07 15:47:14.452848420 -0500 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c 2016-11-07 15:47:14.448848375 -0500 +@@ -1600,18 +1600,15 @@ + { + ssize_t err; + size_t offset = 7; +- int read_count; +- int64_t xattr_len; ++ uint64_t read_count; + +- xattr_len = fidp->fs.xattr.len; +- read_count = xattr_len - off; ++ if (fidp->fs.xattr.len < off) { ++ read_count = 0; ++ } else { ++ read_count = fidp->fs.xattr.len - off; ++ } + if (read_count > max_count) { + read_count = max_count; +- } else if (read_count < 0) { +- /* +- * read beyond XATTR value +- */ +- read_count = 0; + } + err = pdu_marshal(pdu, offset, "d", read_count); + if (err < 0) { +@@ -1936,23 +1933,18 @@ + { + int i, to_copy; + ssize_t err = 0; +- int write_count; +- int64_t xattr_len; ++ uint64_t write_count; + size_t offset = 7; + + +- xattr_len = fidp->fs.xattr.len; +- write_count = xattr_len - off; +- if (write_count > count) { +- write_count = count; +- } else if (write_count < 0) { +- /* +- * write beyond XATTR value len specified in +- * xattrcreate +- */ ++ if (fidp->fs.xattr.len < off) { + err = -ENOSPC; + goto out; + } ++ write_count = fidp->fs.xattr.len - off; ++ if (write_count > count) { ++ write_count = count; ++ } + err = pdu_marshal(pdu, offset, "d", write_count); + if (err < 0) { + return err; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9105.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9105.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9105.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9105.patch 2016-11-07 20:47:24.000000000 +0000 @@ -0,0 +1,31 @@ +Backport of: + +From 4c1586787ff43c9acd18a56c12d720e3e6be9f7c Mon Sep 17 00:00:00 2001 +From: Li Qiang +Date: Mon, 17 Oct 2016 14:13:58 +0200 +Subject: [PATCH] 9pfs: fix memory leak in v9fs_link + +The v9fs_link() function keeps a reference on the source fid object. This +causes a memory leak since the reference never goes down to 0. This patch +fixes the issue. + +Signed-off-by: Li Qiang +Reviewed-by: Greg Kurz +[groug, rephrased the changelog] +Signed-off-by: Greg Kurz +--- + hw/9pfs/9p.c | 1 + + 1 files changed, 1 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p.c 2016-11-07 15:47:22.132934466 -0500 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c 2016-11-07 15:47:22.128934421 -0500 +@@ -2362,6 +2362,7 @@ + if (!err) { + err = offset; + } ++ put_fid(pdu, oldfidp); + out: + put_fid(pdu, dfidp); + out_nofid: diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9106.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9106.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9106.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9106.patch 2016-11-07 20:47:30.000000000 +0000 @@ -0,0 +1,32 @@ +Backport of: + +From fdfcc9aeea1492f4b819a24c94dfb678145b1bf9 Mon Sep 17 00:00:00 2001 +From: Li Qiang +Date: Mon, 17 Oct 2016 14:13:58 +0200 +Subject: [PATCH] 9pfs: fix memory leak in v9fs_write + +If an error occurs when marshalling the transfer length to the guest, the +v9fs_write() function doesn't free an IO vector, thus leading to a memory +leak. This patch fixes the issue. + +Signed-off-by: Li Qiang +Reviewed-by: Greg Kurz +[groug, rephrased the changelog] +Signed-off-by: Greg Kurz +--- + hw/9pfs/9p.c | 2 +- + 1 files changed, 1 insertions(+), 1 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p.c 2016-11-07 15:47:28.281003348 -0500 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c 2016-11-07 15:47:28.277003304 -0500 +@@ -2038,7 +2038,7 @@ + offset = 7; + err = pdu_marshal(pdu, offset, "d", total); + if (err < 0) { +- goto out; ++ goto out_qiov; + } + err += offset; + trace_v9fs_write_return(pdu->tag, pdu->id, total, err); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9381.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9381.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9381.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9381.patch 2017-04-05 15:28:18.000000000 +0000 @@ -0,0 +1,73 @@ +Backport of: + +From b85f9dfdb156ae2a2a52f39a36e9f1f270614cd2 Mon Sep 17 00:00:00 2001 +From: Jan Beulich +Date: Tue, 22 Nov 2016 05:56:51 -0700 +Subject: [PATCH] xen: fix ioreq handling + +Avoid double fetches and bounds check size to avoid overflowing +internal variables. + +This is CVE-2016-9381 / XSA-197. + +Reported-by: yanghongke +Signed-off-by: Jan Beulich +Reviewed-by: Stefano Stabellini +Signed-off-by: Stefano Stabellini +--- + xen-hvm.c | 16 +++++++++++++++- + 1 file changed, 15 insertions(+), 1 deletion(-) + +Index: qemu-2.0.0+dfsg/xen-all.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/xen-all.c 2017-04-05 11:25:29.074952651 -0400 ++++ qemu-2.0.0+dfsg/xen-all.c 2017-04-05 11:27:36.972595932 -0400 +@@ -705,6 +705,10 @@ + { + uint32_t i; + ++ if (req->size > sizeof(uint32_t)) { ++ hw_error("PIO: bad size (%u)", req->size); ++ } ++ + if (req->dir == IOREQ_READ) { + if (!req->data_is_ptr) { + req->data = do_inp(req->addr, req->size); +@@ -734,6 +738,10 @@ + { + uint32_t i; + ++ if (req->size > sizeof(req->data)) { ++ hw_error("MMIO: bad size (%u)", req->size); ++ } ++ + if (!req->data_is_ptr) { + if (req->dir == IOREQ_READ) { + for (i = 0; i < req->count; i++) { +@@ -809,11 +817,13 @@ + req.df = 1; + req.type = buf_req->type; + req.data_is_ptr = 0; ++ xen_rmb(); + qw = (req.size == 8); + if (qw) { + buf_req = &state->buffered_io_page->buf_ioreq[ + (state->buffered_io_page->read_pointer + 1) % IOREQ_BUFFER_SLOT_NUM]; + req.data |= ((uint64_t)buf_req->data) << 32; ++ xen_rmb(); + } + + handle_ioreq(&req); +@@ -845,7 +855,11 @@ + + handle_buffered_iopage(state); + if (req) { +- handle_ioreq(req); ++ ioreq_t copy = *req; ++ ++ xen_rmb(); ++ handle_ioreq(©); ++ req->data = copy.data; + + if (req->state != STATE_IOREQ_INPROCESS) { + fprintf(stderr, "Badness in I/O request ... not in service?!: " diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-10.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-10.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-10.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-10.patch 2017-04-05 15:32:26.000000000 +0000 @@ -0,0 +1,164 @@ +Backport of: + +From 72f0d0bf51362011c4d841a89fb8f5cfb16e0bf3 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-11.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-11.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-11.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-11.patch 2017-04-05 15:32:35.000000000 +0000 @@ -0,0 +1,147 @@ +Backport of: + +From df4938a6651b1f980018f9eaf86af43e6b9d7fed Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-12.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-12.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-12.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-12.patch 2017-04-05 15:32:47.000000000 +0000 @@ -0,0 +1,106 @@ +Backport of: + +From a0e640a87210b1e986bcd4e7f7de03beb3db0a4a Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-13.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-13.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-13.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-13.patch 2017-04-05 15:32:56.000000000 +0000 @@ -0,0 +1,56 @@ +Backport of: + +From a33eda0dd99e00faa3bacae43d19490bb9500e07 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-14.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-14.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-14.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-14.patch 2017-04-05 15:33:02.000000000 +0000 @@ -0,0 +1,43 @@ +Backport of: + +From 31e51d1c15b35dc98b88a301812914b70a2b55dc Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-15.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-15.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-15.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-15.patch 2017-04-05 15:33:09.000000000 +0000 @@ -0,0 +1,46 @@ +Backport of: + +From ac125d993b461d4dee4d6df4d93ac3f2eb959d1d Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-16.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-16.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-16.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-16.patch 2017-04-05 15:34:35.000000000 +0000 @@ -0,0 +1,76 @@ +Backport of: + +From bec1e9546e03b9e7f5152cf3e8c95cf8acff5e12 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-17.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-17.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-17.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-17.patch 2017-04-05 15:36:27.000000000 +0000 @@ -0,0 +1,156 @@ +Backport of: + +From f9aef99b3e6df88036436b0d3dc3d504b9346c8c Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + hw/9pfs/9p-local.c | 78 ++++++++++++++++++++++++++++++++++++++++++------------ + 1 file changed, 61 insertions(+), 17 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:34:43.522076416 -0400 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c 2017-04-05 11:36:16.979277193 -0400 +@@ -110,17 +110,49 @@ + 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; + +- attr_path = local_mapped_attr_path(ctx, path); +- fp = local_fopen(attr_path, "r"); +- g_free(attr_path); ++ map_dirfd = openat(dirfd, VIRTFS_META_DIR, ++ O_RDONLY | O_DIRECTORY | O_NOFOLLOW); ++ if (map_dirfd == -1) { ++ return; ++ } ++ ++ fp = local_fopenat(map_dirfd, name, "r"); ++ close_preserve_errno(map_dirfd); + if (!fp) { + return; + } +@@ -142,12 +174,17 @@ + + 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; + } +@@ -157,25 +194,32 @@ + 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 = 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 = 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 = 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 = 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-18.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-18.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-18.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-18.patch 2017-04-05 15:37:12.000000000 +0000 @@ -0,0 +1,123 @@ +Backport of: + +From 99f2cf4b2dad7b37c69759deb0d0b19d3ec1a24a Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-19.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-19.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-19.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-19.patch 2017-04-05 15:37:19.000000000 +0000 @@ -0,0 +1,97 @@ +Backport of: + +From d2767edec582558f1e6c52e1dd9370d62e2b30fc Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-1.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-1.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-1.patch 2017-04-05 15:28:58.000000000 +0000 @@ -0,0 +1,181 @@ +Backport of: + +From 56fc494bdcba35d74da27e1d34dbb6db6fa7bd67 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-20.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-20.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-20.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-20.patch 2017-04-05 15:37:25.000000000 +0000 @@ -0,0 +1,91 @@ +Backport of: + +From 6dd4b1f1d026e478d9177b28169b377e212400f3 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-21.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-21.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-21.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-21.patch 2017-04-05 15:38:36.000000000 +0000 @@ -0,0 +1,144 @@ +Backport of: + +From ad0b46e6ac769b187cb4dcf0065675ef8a198a5e Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-22.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-22.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-22.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-22.patch 2017-04-05 15:38:41.000000000 +0000 @@ -0,0 +1,242 @@ +Backport of: + +From e3187a45dd02a7490f9191c16527dc28a4ba45b9 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-23.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-23.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-23.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-23.patch 2017-04-05 15:38:47.000000000 +0000 @@ -0,0 +1,75 @@ +Backport of: + +From d369f20763a857eac544a5289a046d0285a91df8 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-24.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-24.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-24.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-24.patch 2017-04-05 15:43:52.000000000 +0000 @@ -0,0 +1,169 @@ +Backport of: + +From 38771613ea6759f499645afd709aa422161eb27e Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-25.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-25.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-25.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-25.patch 2017-04-05 15:47:09.000000000 +0000 @@ -0,0 +1,152 @@ +Backport of: + +From d815e7219036d6911fce12efe3e59906264c8536 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-26.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-26.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-26.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-26.patch 2017-04-05 15:50:03.000000000 +0000 @@ -0,0 +1,127 @@ +Backport of: + +From 3f3a16990b09e62d787bd2eb2dd51aafbe90019a Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-27.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-27.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-27.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-27.patch 2017-04-05 15:53:09.000000000 +0000 @@ -0,0 +1,141 @@ +Backport of: + +From a565fea56546e254b7610305b07711f0a3bda0c7 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-28.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-28.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-28.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-28.patch 2017-04-05 16:08:39.000000000 +0000 @@ -0,0 +1,241 @@ +Backport of: + +From c23d5f1d5bc0e23aeb845b1af8f996f16783ce98 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + hw/9pfs/9p-local.c | 198 ----------------------------------------------------- + 1 file changed, 198 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 12:07:53.495644420 -0400 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c 2017-04-05 12:08:34.456170700 -0400 +@@ -81,50 +81,6 @@ + + #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; +@@ -237,135 +193,6 @@ + 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) { +- err = setxattr(path, "user.virtfs.uid", &credp->fc_uid, sizeof(uid_t), +- 0); +- if (err) { +- return err; +- } +- } +- if (credp->fc_gid != -1) { +- err = setxattr(path, "user.virtfs.gid", &credp->fc_gid, sizeof(gid_t), +- 0); +- if (err) { +- return err; +- } +- } +- if (credp->fc_mode != -1) { +- err = setxattr(path, "user.virtfs.mode", &credp->fc_mode, +- sizeof(mode_t), 0); +- if (err) { +- return err; +- } +- } +- if (credp->fc_rdev != -1) { +- err = setxattr(path, "user.virtfs.rdev", &credp->fc_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) + { +@@ -515,33 +342,6 @@ + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-29.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-29.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-29.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-29.patch 2017-04-05 15:54:57.000000000 +0000 @@ -0,0 +1,50 @@ +Backport of: + +From b003fc0d8aa5e7060dbf7e5862b8013c73857c7f Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Daniel P. Berrange +Reviewed-by: Eric Blake +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-2.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-2.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-2.patch 2017-04-05 15:29:10.000000000 +0000 @@ -0,0 +1,72 @@ +Backport of: + +From 00c90bd1c2ff6aabb9ca948a254ba044a403e399 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-3.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-3.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-3.patch 2017-04-05 15:31:21.000000000 +0000 @@ -0,0 +1,55 @@ +Backport of: + +From 21328e1e57f526e3f0c2fcd00f10c8aa6e7bc07f Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-4.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-4.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-4.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-4.patch 2017-04-06 12:58:42.000000000 +0000 @@ -0,0 +1,188 @@ +Backport of: + +From 6482a961636d66cc10928dde5d4d908206e5f65a Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Signed-off-by: Greg Kurz +Reviewed-by: Stefan Hajnoczi +(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 +--- + 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 ++ * ++ * 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 ++ * ++ * 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-5.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-5.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-5.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-5.patch 2017-04-05 15:32:00.000000000 +0000 @@ -0,0 +1,91 @@ +Backport of: + +From 0e35a3782948c6154d7fafe9a02a86bc130199c7 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + hw/9pfs/9p-local.c | 30 ++++++++++++++++++++++++++++-- + 1 file changed, 28 insertions(+), 2 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:32.719624908 -0400 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c 2017-04-05 11:31:50.151848884 -0400 +@@ -14,6 +14,7 @@ + #include "hw/virtio/virtio.h" + #include "virtio-9p.h" + #include "virtio-9p-xattr.h" ++#include "virtio-9p-util.h" + #include + #include + #include +@@ -40,6 +41,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) +@@ -1191,13 +1196,20 @@ + 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: +@@ -1224,7 +1236,20 @@ + } + 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) +@@ -1267,6 +1292,7 @@ + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-6.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-6.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-6.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-6.patch 2017-04-05 15:32:08.000000000 +0000 @@ -0,0 +1,126 @@ +Backport of: + +From 996a0d76d7e756e4023ef79bc37bfe629b9eaca7 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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-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:06.268055952 -0400 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c 2017-04-05 11:32:06.260055849 -0400 +@@ -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 +@@ -45,6 +46,24 @@ + 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) +@@ -359,13 +378,9 @@ + 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; + } +@@ -376,13 +391,15 @@ + 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-2.0.0+dfsg/hw/9pfs/virtio-9p-local.h +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.h 2017-04-05 11:32:06.260055849 -0400 +@@ -0,0 +1,20 @@ ++/* ++ * 9p local backend utilities ++ * ++ * Copyright IBM, Corp. 2017 ++ * ++ * Authors: ++ * Greg Kurz ++ * ++ * 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-7.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-7.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-7.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-7.patch 2017-04-06 12:59:12.000000000 +0000 @@ -0,0 +1,194 @@ +Backport of: + +From 56ad3e54dad6cdcee8668d170df161d89581846f Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-8.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-8.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-8.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-8.patch 2017-04-05 15:32:16.000000000 +0000 @@ -0,0 +1,93 @@ +Backport of: + +From 5507904e362df252f6065cb27d1ff98372db6abc Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-9.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-9.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-9.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-9.patch 2017-04-05 15:32:21.000000000 +0000 @@ -0,0 +1,173 @@ +Backport of: + +From 3e36aba757f76673007a80b3cd56a4062c2e3462 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Stefan Hajnoczi +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-pre.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-pre.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9602-pre.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9602-pre.patch 2017-04-05 15:56:37.000000000 +0000 @@ -0,0 +1,44 @@ +Backport of: + +From 529490e5d664a20d5c4223070dd7c03a0e02b6bd Mon Sep 17 00:00:00 2001 +From: Peter Maydell +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 +Signed-off-by: Michael Tokarev +--- + 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 + #include + #include +-#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 ++#include "glib-compat.h" + + #if defined(CONFIG_SOLARIS) && CONFIG_SOLARIS_VERSION < 10 + /* [u]int_fast*_t not in */ diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9603.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9603.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9603.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9603.patch 2017-04-06 13:43:03.000000000 +0000 @@ -0,0 +1,263 @@ +Backport of: + +From 50628d3479e4f9aa97e323506856e394fe7ad7a6 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +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 +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-2.0.0+dfsg/hw/display/cirrus_vga.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/display/cirrus_vga.c 2017-04-06 09:41:20.386188897 -0400 ++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga.c 2017-04-06 09:41:20.378188796 -0400 +@@ -753,11 +753,6 @@ + } + } + +- /* 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 @@ + 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-2.0.0+dfsg/include/ui/console.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/include/ui/console.h 2017-04-06 09:41:20.386188897 -0400 ++++ qemu-2.0.0+dfsg/include/ui/console.h 2017-04-06 09:41:48.846547543 -0400 +@@ -158,9 +158,6 @@ + int x, int y, int w, int h); + void (*dpy_gfx_switch)(DisplayChangeListener *dcl, + struct DisplaySurface *new_surface); +- void (*dpy_gfx_copy)(DisplayChangeListener *dcl, +- int src_x, int src_y, +- int dst_x, int dst_y, int w, int h); + + void (*dpy_text_cursor)(DisplayChangeListener *dcl, + int x, int y); +@@ -217,8 +214,6 @@ + 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); +@@ -302,8 +297,6 @@ + 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); + +Index: qemu-2.0.0+dfsg/ui/console.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/ui/console.c 2017-04-06 09:41:20.386188897 -0400 ++++ qemu-2.0.0+dfsg/ui/console.c 2017-04-06 09:41:20.378188796 -0400 +@@ -1418,27 +1418,6 @@ + } + } + +-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; +@@ -1857,13 +1836,6 @@ + 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-2.0.0+dfsg/ui/vnc.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/ui/vnc.c 2017-04-06 09:41:16.158135604 -0400 ++++ qemu-2.0.0+dfsg/ui/vnc.c 2017-04-06 09:42:50.447323308 -0400 +@@ -730,96 +730,6 @@ + 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) + { +@@ -2925,7 +2835,6 @@ + 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, diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9776.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9776.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9776.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9776.patch 2017-04-06 13:43:21.000000000 +0000 @@ -0,0 +1,31 @@ +From 77d54985b85a0cb760330ec2bd92505e0a2a97a9 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +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 +Signed-off-by: Prasad J Pandit +Signed-off-by: Jason Wang +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9907.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9907.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9907.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9907.patch 2017-04-06 13:47:42.000000000 +0000 @@ -0,0 +1,53 @@ +Backport of: + +From 07b026fd82d6cf11baf7d7c603c4f5f6070b35bf Mon Sep 17 00:00:00 2001 +From: Li Qiang +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 +Reviewed-by: Marc-André Lureau +Message-id: 58216976.d0236b0a.77b99.bcd6@mx.google.com +Signed-off-by: Gerd Hoffmann +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9911.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9911.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9911.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9911.patch 2017-04-06 14:02:41.000000000 +0000 @@ -0,0 +1,28 @@ +From 791f97758e223de3290592d169f8e6339c281714 Mon Sep 17 00:00:00 2001 +From: Li Qiang +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 +Message-id: 5821c0f4.091c6b0a.e0c92.e811@mx.google.com +Signed-off-by: Gerd Hoffmann +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9913.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9913.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9913.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9913.patch 2017-04-05 15:57:46.000000000 +0000 @@ -0,0 +1,32 @@ +Backport of: + +From 4774718e5c194026ba5ee7a28d9be49be3080e42 Mon Sep 17 00:00:00 2001 +From: Li Qiang +Date: Wed, 23 Nov 2016 13:53:34 +0100 +Subject: [PATCH] 9pfs: adjust the order of resource cleanup in device + unrealize + +Unrealize should undo things that were set during realize in +reverse order. So should do in the error path in realize. + +Signed-off-by: Li Qiang +Reviewed-by: Greg Kurz +Signed-off-by: Greg Kurz +--- + hw/9pfs/9p.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-device.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-device.c 2017-04-05 11:56:50.159121597 -0400 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-device.c 2017-04-05 11:56:50.155121546 -0400 +@@ -130,8 +130,8 @@ + + return; + out: +- g_free(s->ctx.fs_root); + g_free(s->tag); ++ g_free(s->ctx.fs_root); + virtio_cleanup(vdev); + v9fs_path_free(&path); + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9914-1.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9914-1.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9914-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9914-1.patch 2017-04-05 15:58:32.000000000 +0000 @@ -0,0 +1,45 @@ +Backport of: + +From 702dbcc274e2ca43be20ba64c758c0ca57dab91d Mon Sep 17 00:00:00 2001 +From: Li Qiang +Date: Wed, 23 Nov 2016 13:53:34 +0100 +Subject: [PATCH] 9pfs: add cleanup operation in FileOperations + +Currently, the backend of VirtFS doesn't have a cleanup +function. This will lead resource leak issues if the backed +driver allocates resources. This patch addresses this issue. + +Signed-off-by: Li Qiang +Reviewed-by: Greg Kurz +Signed-off-by: Greg Kurz +--- + fsdev/file-op-9p.h | 1 + + hw/9pfs/9p.c | 6 ++++++ + 2 files changed, 7 insertions(+) + +Index: qemu-2.0.0+dfsg/fsdev/file-op-9p.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/fsdev/file-op-9p.h 2017-04-05 11:58:03.732066893 -0400 ++++ qemu-2.0.0+dfsg/fsdev/file-op-9p.h 2017-04-05 11:58:03.728066842 -0400 +@@ -102,6 +102,7 @@ + { + 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-2.0.0+dfsg/hw/9pfs/virtio-9p-device.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-device.c 2017-04-05 11:58:03.732066893 -0400 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-device.c 2017-04-05 11:58:03.728066842 -0400 +@@ -130,6 +130,9 @@ + + return; + out: ++ if (s->ops->cleanup && s->ctx.private) { ++ s->ops->cleanup(&s->ctx); ++ } + g_free(s->tag); + g_free(s->ctx.fs_root); + virtio_cleanup(vdev); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9914-2.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9914-2.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9914-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9914-2.patch 2017-04-05 15:58:46.000000000 +0000 @@ -0,0 +1,31 @@ +Backport of: + +From f2b58c43758efc61e2a49b899f5e58848489d0dc Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Reviewed-by: Li Qiang +--- + hw/9pfs/9p.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-device.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p-device.c 2017-04-05 11:58:43.468577445 -0400 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-device.c 2017-04-05 11:58:43.464577393 -0400 +@@ -130,7 +130,7 @@ + + 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->tag); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9915.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9915.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9915.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9915.patch 2017-04-05 15:58:52.000000000 +0000 @@ -0,0 +1,46 @@ +Backport of: + +From 971f406b77a6eb84e0ad27dcc416b663765aee30 Mon Sep 17 00:00:00 2001 +From: Li Qiang +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 +Reviewed-by: Greg Kurz +Signed-off-by: Greg Kurz +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9916.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9916.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9916.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9916.patch 2017-04-05 15:59:00.000000000 +0000 @@ -0,0 +1,46 @@ +Backport of: + +From 898ae90a44551d25b8e956fd87372d303c82fe68 Mon Sep 17 00:00:00 2001 +From: Li Qiang +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 +Reviewed-by: Greg Kurz +Signed-off-by: Greg Kurz +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2016-9921-9922.patch qemu-2.0.0+dfsg/debian/patches/CVE-2016-9921-9922.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2016-9921-9922.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2016-9921-9922.patch 2017-04-06 13:49:12.000000000 +0000 @@ -0,0 +1,73 @@ +From 4299b90e9ba9ce5ca9024572804ba751aa1a7e70 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +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 +Signed-off-by: Prasad J Pandit +Message-id: 1476776717-24807-1-git-send-email-ppandit@redhat.com +Signed-off-by: Gerd Hoffmann +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-10664.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-10664.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-10664.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-10664.patch 2017-08-22 16:34:38.000000000 +0000 @@ -0,0 +1,47 @@ +Backport of: + +From 041e32b8d9d076980b4e35317c0339e57ab888f1 Mon Sep 17 00:00:00 2001 +From: Max Reitz +Date: Sun, 11 Jun 2017 14:37:14 +0200 +Subject: [PATCH] qemu-nbd: 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). + +Signed-off-by: Max Reitz +Message-Id: <20170611123714.31292-1-mreitz@redhat.com> +Signed-off-by: Paolo Bonzini +--- + qemu-nbd.c | 4 ++++ + 1 file changed, 4 insertions(+) + +Index: qemu-2.0.0+dfsg/qemu-nbd.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/qemu-nbd.c 2017-08-22 12:34:35.916840570 -0400 ++++ qemu-2.0.0+dfsg/qemu-nbd.c 2017-08-22 12:34:35.912840570 -0400 +@@ -437,6 +437,11 @@ int main(int argc, char **argv) + memset(&sa_sigterm, 0, sizeof(sa_sigterm)); + sa_sigterm.sa_handler = termsig_handler; + sigaction(SIGTERM, &sa_sigterm, NULL); ++ ++#ifdef CONFIG_POSIX ++ signal(SIGPIPE, SIG_IGN); ++#endif ++ + qemu_init_exec_dir(argv[0]); + + while ((ch = getopt_long(argc, argv, sopt, lopt, &opt_ind)) != -1) { diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-10806.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-10806.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-10806.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-10806.patch 2017-08-22 16:34:45.000000000 +0000 @@ -0,0 +1,47 @@ +From bd4a683505b27adc1ac809f71e918e58573d851d Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +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: 李强 +Signed-off-by: Gerd Hoffmann +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.0.0~rc1+dfsg/debian/patches/CVE-2017-10911.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-10911.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-10911.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-10911.patch 2017-08-22 16:36:58.000000000 +0000 @@ -0,0 +1,70 @@ +Backport of: + +From b0ac694fdb9113b973048ebe5619927e74965f61 Mon Sep 17 00:00:00 2001 +From: Stefano Stabellini +Date: Tue, 27 Jun 2017 14:45:34 -0700 +Subject: [PATCH] xen/disk: don't leak stack data via response ring + +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 +Signed-off-by: Jan Beulich +Signed-off-by: Stefano Stabellini +Acked-by: Anthony PERARD +--- + hw/block/xen_disk.c | 25 ++++++++++++------------- + 1 file changed, 12 insertions(+), 13 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/block/xen_disk.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/block/xen_disk.c 2017-08-22 12:34:51.960841318 -0400 ++++ qemu-2.0.0+dfsg/hw/block/xen_disk.c 2017-08-22 12:36:40.160846364 -0400 +@@ -596,30 +596,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); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-11434.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-11434.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-11434.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-11434.patch 2017-08-22 16:37:10.000000000 +0000 @@ -0,0 +1,32 @@ +From 413d463f43fbc4dd3a601e80a5724aa384a265a0 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Mon, 17 Jul 2017 17:33:26 +0530 +Subject: [PATCH] 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 +Signed-off-by: Prasad J Pandit +Signed-off-by: Samuel Thibault +--- + slirp/bootp.c | 3 +++ + 1 file changed, 3 insertions(+) + +Index: qemu-2.0.0+dfsg/slirp/bootp.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/slirp/bootp.c 2017-08-22 12:37:08.352847678 -0400 ++++ qemu-2.0.0+dfsg/slirp/bootp.c 2017-08-22 12:37:08.340847678 -0400 +@@ -116,6 +116,9 @@ static void dhcp_decode(const struct boo + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-14167.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-14167.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-14167.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-14167.patch 2018-02-15 18:17:19.000000000 +0000 @@ -0,0 +1,60 @@ +From ed4f86e8b6eff8e600c69adee68c7cd34dd2cccb Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Thu, 7 Sep 2017 12:02:56 +0530 +Subject: [PATCH] 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. + +This is CVE-2017-14167. + +Reported-by: Thomas Garnier +Signed-off-by: Prasad J Pandit +Message-Id: <20170907063256.7418-1-ppandit@redhat.com> +Signed-off-by: Paolo Bonzini +--- + hw/i386/multiboot.c | 19 +++++++++++++++++++ + 1 file changed, 19 insertions(+) + +Index: qemu-2.0.0+dfsg/hw/i386/multiboot.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/i386/multiboot.c 2018-02-15 13:17:17.194812224 -0500 ++++ qemu-2.0.0+dfsg/hw/i386/multiboot.c 2018-02-15 13:17:17.194812224 -0500 +@@ -200,15 +200,34 @@ int load_multiboot(FWCfgState *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.0.0~rc1+dfsg/debian/patches/CVE-2017-15038.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-15038.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-15038.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-15038.patch 2018-02-15 18:17:30.000000000 +0000 @@ -0,0 +1,42 @@ +Backport of: + +From 7bd92756303f2158a68d5166264dc30139b813b6 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Mon, 16 Oct 2017 14:21:59 +0200 +Subject: [PATCH] 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. + +Reported-by: Tuomas Tynkkynen +Signed-off-by: Prasad J Pandit +Signed-off-by: Greg Kurz +--- + hw/9pfs/9p.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p.c 2018-02-15 13:17:28.822822323 -0500 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c 2018-02-15 13:17:28.822822323 -0500 +@@ -3150,7 +3150,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); +@@ -3183,7 +3183,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.0.0~rc1+dfsg/debian/patches/CVE-2017-15289.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-15289.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-15289.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-15289.patch 2018-02-15 18:20:29.000000000 +0000 @@ -0,0 +1,55 @@ +From eb38e1bc3740725ca29a535351de94107ec58d51 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +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 +Reported-by: Niu Guoxiang +Signed-off-by: Gerd Hoffmann +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.0.0~rc1+dfsg/debian/patches/CVE-2017-18043.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-18043.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-18043.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-18043.patch 2018-02-15 18:33:01.000000000 +0000 @@ -0,0 +1,55 @@ +Backport of: + +From 2098b073f398cd628c09c5a78537a6854e85830d Mon Sep 17 00:00:00 2001 +From: Eric Blake +Date: Thu, 14 Sep 2017 08:49:23 -0500 +Subject: [PATCH] osdep: Fix ROUND_UP(64-bit, 32-bit) + +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 +Reviewed-by: Laszlo Ersek +Reviewed-by: Richard Henderson +Signed-off-by: Michael Tokarev +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-2615.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-2615.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-2615.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-2615.patch 2017-04-06 14:02:49.000000000 +0000 @@ -0,0 +1,47 @@ +Backport of: + +From 62d4c6bd5263bb8413a06c80144fc678df6dfb64 Mon Sep 17 00:00:00 2001 +From: Li Qiang +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 + +{ 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 +Cc: Laszlo Ersek +Cc: Paolo Bonzini +Cc: Wolfgang Bumiller +Fixes: d3532a0db02296e687711b8cdc7791924efccea0 (CVE-2014-8106) +Signed-off-by: Gerd Hoffmann +Message-id: 1485938101-26602-1-git-send-email-kraxel@redhat.com +Reviewed-by: Laszlo Ersek +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-2620.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-2620.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-2620.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-2620.patch 2017-04-06 13:53:52.000000000 +0000 @@ -0,0 +1,46 @@ +From 92f2b88cea48c6aeba8de568a45f2ed958f3c298 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Wed, 8 Feb 2017 11:18:36 +0100 +Subject: [PATCH] cirrus: add blit_is_unsafe call to cirrus_bitblt_cputovideo + (CVE-2017-2620) + +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. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Gerd Hoffmann +--- + hw/display/cirrus_vga.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +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:50.435596471 -0400 ++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga.c 2017-04-06 09:53:50.431596421 -0400 +@@ -863,6 +863,10 @@ + { + 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]; +@@ -888,6 +892,10 @@ + } + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-2620-pre.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-2620-pre.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-2620-pre.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-2620-pre.patch 2017-04-06 13:53:45.000000000 +0000 @@ -0,0 +1,69 @@ +From 913a87885f589d263e682c2eb6637c6e14538061 Mon Sep 17 00:00:00 2001 +From: Bruce Rogers +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 +Message-id: 20170109203520.5619-1-brogers@suse.com +Signed-off-by: Gerd Hoffmann +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-2633.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-2633.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-2633.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-2633.patch 2017-04-06 14:09:45.000000000 +0000 @@ -0,0 +1,385 @@ +From bea60dd7679364493a0d7f5b54316c767cf894ef Mon Sep 17 00:00:00 2001 +From: Peter Lieven +Date: Mon, 30 Jun 2014 10:57:51 +0200 +Subject: [PATCH] ui/vnc: fix potential memory corruption issues + +this patch makes the VNC server work correctly if the +server surface and the guest surface have different sizes. + +Basically the server surface is adjusted to not exceed VNC_MAX_WIDTH +x VNC_MAX_HEIGHT and additionally the width is rounded up to multiple of +VNC_DIRTY_PIXELS_PER_BIT. + +If we have a resolution whose width is not dividable by VNC_DIRTY_PIXELS_PER_BIT +we now get a small black bar on the right of the screen. + +If the surface is too big to fit the limits only the upper left area is shown. + +On top of that this fixes 2 memory corruption issues: + +The first was actually discovered during playing +around with a Windows 7 vServer. During resolution +change in Windows 7 it happens sometimes that Windows +changes to an intermediate resolution where +server_stride % cmp_bytes != 0 (in vnc_refresh_server_surface). +This happens only if width % VNC_DIRTY_PIXELS_PER_BIT != 0. + +The second is a theoretical issue, but is maybe exploitable +by the guest. If for some reason the guest surface size is bigger +than VNC_MAX_WIDTH x VNC_MAX_HEIGHT we end up in severe corruption since +this limit is nowhere enforced. + +Signed-off-by: Peter Lieven +Signed-off-by: Gerd Hoffmann +--- + ui/vnc.c | 149 +++++++++++++++++++++++++++++---------------------------------- + ui/vnc.h | 14 +++--- + 2 files changed, 77 insertions(+), 86 deletions(-) + +Index: qemu-2.0.0+dfsg/ui/vnc.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/ui/vnc.c 2017-04-06 10:09:39.575475045 -0400 ++++ qemu-2.0.0+dfsg/ui/vnc.c 2017-04-06 10:09:39.571474995 -0400 +@@ -427,14 +427,10 @@ + static void vnc_refresh(DisplayChangeListener *dcl); + static int vnc_refresh_server_surface(VncDisplay *vd); + +-static void vnc_dpy_update(DisplayChangeListener *dcl, +- int x, int y, int w, int h) +-{ +- VncDisplay *vd = container_of(dcl, VncDisplay, dcl); +- struct VncSurface *s = &vd->guest; +- int width = surface_width(vd->ds); +- int height = surface_height(vd->ds); +- ++static void vnc_set_area_dirty(DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], ++ VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT), ++ int width, int height, ++ int x, int y, int w, int h) { + /* this is needed this to ensure we updated all affected + * blocks if x % VNC_DIRTY_PIXELS_PER_BIT != 0 */ + w += (x % VNC_DIRTY_PIXELS_PER_BIT); +@@ -446,11 +442,22 @@ + h = MIN(y + h, height); + + for (; y < h; y++) { +- bitmap_set(s->dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT, ++ bitmap_set(dirty[y], x / VNC_DIRTY_PIXELS_PER_BIT, + DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT)); + } + } + ++static void vnc_dpy_update(DisplayChangeListener *dcl, ++ int x, int y, int w, int h) ++{ ++ VncDisplay *vd = container_of(dcl, VncDisplay, dcl); ++ struct VncSurface *s = &vd->guest; ++ int width = pixman_image_get_width(vd->server); ++ int height = pixman_image_get_height(vd->server); ++ ++ vnc_set_area_dirty(s->dirty, width, height, x, y, w, h); ++} ++ + void vnc_framebuffer_update(VncState *vs, int x, int y, int w, int h, + int32_t encoding) + { +@@ -512,17 +519,15 @@ + + static void vnc_desktop_resize(VncState *vs) + { +- DisplaySurface *ds = vs->vd->ds; +- + if (vs->csock == -1 || !vnc_has_feature(vs, VNC_FEATURE_RESIZE)) { + return; + } +- if (vs->client_width == surface_width(ds) && +- vs->client_height == surface_height(ds)) { ++ if (vs->client_width == pixman_image_get_width(vs->vd->server) && ++ vs->client_height == pixman_image_get_height(vs->vd->server)) { + return; + } +- vs->client_width = surface_width(ds); +- vs->client_height = surface_height(ds); ++ vs->client_width = pixman_image_get_width(vs->vd->server); ++ vs->client_height = pixman_image_get_height(vs->vd->server); + vnc_lock_output(vs); + vnc_write_u8(vs, VNC_MSG_SERVER_FRAMEBUFFER_UPDATE); + vnc_write_u8(vs, 0); +@@ -566,31 +571,24 @@ + ptr += x * VNC_SERVER_FB_BYTES; + return ptr; + } +-/* this sets only the visible pixels of a dirty bitmap */ +-#define VNC_SET_VISIBLE_PIXELS_DIRTY(bitmap, w, h) {\ +- int y;\ +- memset(bitmap, 0x00, sizeof(bitmap));\ +- for (y = 0; y < h; y++) {\ +- bitmap_set(bitmap[y], 0,\ +- DIV_ROUND_UP(w, VNC_DIRTY_PIXELS_PER_BIT));\ +- } \ +- } + + static void vnc_dpy_switch(DisplayChangeListener *dcl, + DisplaySurface *surface) + { + VncDisplay *vd = container_of(dcl, VncDisplay, dcl); + VncState *vs; ++ int width, height; + + vnc_abort_display_jobs(vd); + + /* server surface */ + qemu_pixman_image_unref(vd->server); + vd->ds = surface; ++ width = MIN(VNC_MAX_WIDTH, ROUND_UP(surface_width(vd->ds), ++ VNC_DIRTY_PIXELS_PER_BIT)); ++ height = MIN(VNC_MAX_HEIGHT, surface_height(vd->ds)); + vd->server = pixman_image_create_bits(VNC_SERVER_FB_FORMAT, +- surface_width(vd->ds), +- surface_height(vd->ds), +- NULL, 0); ++ width, height, NULL, 0); + + /* guest surface */ + #if 0 /* FIXME */ +@@ -600,9 +598,9 @@ + qemu_pixman_image_unref(vd->guest.fb); + vd->guest.fb = pixman_image_ref(surface->image); + vd->guest.format = surface->format; +- VNC_SET_VISIBLE_PIXELS_DIRTY(vd->guest.dirty, +- surface_width(vd->ds), +- surface_height(vd->ds)); ++ memset(vd->guest.dirty, 0x00, sizeof(vd->guest.dirty)); ++ vnc_set_area_dirty(vd->guest.dirty, width, height, 0, 0, ++ width, height); + + QTAILQ_FOREACH(vs, &vd->clients, next) { + vnc_colordepth(vs); +@@ -610,9 +608,9 @@ + if (vs->vd->cursor) { + vnc_cursor_define(vs); + } +- VNC_SET_VISIBLE_PIXELS_DIRTY(vs->dirty, +- surface_width(vd->ds), +- surface_height(vd->ds)); ++ memset(vs->dirty, 0x00, sizeof(vs->dirty)); ++ vnc_set_area_dirty(vs->dirty, width, height, 0, 0, ++ width, height); + } + } + +@@ -816,8 +814,8 @@ + */ + job = vnc_job_new(vs); + +- height = MIN(pixman_image_get_height(vd->server), vs->client_height); +- width = MIN(pixman_image_get_width(vd->server), vs->client_width); ++ height = pixman_image_get_height(vd->server); ++ width = pixman_image_get_width(vd->server); + + y = 0; + for (;;) { +@@ -1403,8 +1401,8 @@ + vnc_write_u8(vs, 0); + vnc_write_u16(vs, 1); + vnc_framebuffer_update(vs, absolute, 0, +- surface_width(vs->vd->ds), +- surface_height(vs->vd->ds), ++ pixman_image_get_width(vs->vd->server), ++ pixman_image_get_height(vs->vd->server), + VNC_ENCODING_POINTER_TYPE_CHANGE); + vnc_unlock_output(vs); + vnc_flush(vs); +@@ -1422,8 +1420,8 @@ + [INPUT_BUTTON_WHEEL_DOWN] = 0x10, + }; + QemuConsole *con = vs->vd->dcl.con; +- int width = surface_width(vs->vd->ds); +- int height = surface_height(vs->vd->ds); ++ int width = pixman_image_get_width(vs->vd->server); ++ int height = pixman_image_get_height(vs->vd->server); + + if (vs->last_bmask != button_mask) { + qemu_input_update_buttons(con, bmap, vs->last_bmask, button_mask); +@@ -1753,29 +1751,18 @@ + } + + static void framebuffer_update_request(VncState *vs, int incremental, +- int x_position, int y_position, +- int w, int h) ++ int x, int y, int w, int h) + { +- int i; +- const size_t width = surface_width(vs->vd->ds) / VNC_DIRTY_PIXELS_PER_BIT; +- const size_t height = surface_height(vs->vd->ds); +- +- if (y_position > height) { +- y_position = height; +- } +- if (y_position + h >= height) { +- h = height - y_position; +- } ++ int width = pixman_image_get_width(vs->vd->server); ++ int height = pixman_image_get_height(vs->vd->server); + + vs->need_update = 1; +- if (!incremental) { +- vs->force_update = 1; +- for (i = 0; i < h; i++) { +- bitmap_set(vs->dirty[y_position + i], 0, width); +- bitmap_clear(vs->dirty[y_position + i], width, +- VNC_DIRTY_BITS - width); +- } ++ ++ if (incremental) { ++ return; + } ++ ++ vnc_set_area_dirty(vs->dirty, width, height, x, y, w, h); + } + + static void send_ext_key_event_ack(VncState *vs) +@@ -1785,8 +1772,8 @@ + vnc_write_u8(vs, 0); + vnc_write_u16(vs, 1); + vnc_framebuffer_update(vs, 0, 0, +- surface_width(vs->vd->ds), +- surface_height(vs->vd->ds), ++ pixman_image_get_width(vs->vd->server), ++ pixman_image_get_height(vs->vd->server), + VNC_ENCODING_EXT_KEY_EVENT); + vnc_unlock_output(vs); + vnc_flush(vs); +@@ -1799,8 +1786,8 @@ + vnc_write_u8(vs, 0); + vnc_write_u16(vs, 1); + vnc_framebuffer_update(vs, 0, 0, +- surface_width(vs->vd->ds), +- surface_height(vs->vd->ds), ++ pixman_image_get_width(vs->vd->server), ++ pixman_image_get_height(vs->vd->server), + VNC_ENCODING_AUDIO); + vnc_unlock_output(vs); + vnc_flush(vs); +@@ -1988,8 +1975,8 @@ + vnc_write_u8(vs, 0); + vnc_write_u16(vs, 1); /* number of rects */ + vnc_framebuffer_update(vs, 0, 0, +- surface_width(vs->vd->ds), +- surface_height(vs->vd->ds), ++ pixman_image_get_width(vs->vd->server), ++ pixman_image_get_height(vs->vd->server), + VNC_ENCODING_WMVi); + pixel_format_message(vs); + vnc_unlock_output(vs); +@@ -2211,8 +2198,8 @@ + } + vnc_set_share_mode(vs, mode); + +- vs->client_width = surface_width(vs->vd->ds); +- vs->client_height = surface_height(vs->vd->ds); ++ vs->client_width = pixman_image_get_width(vs->vd->server); ++ vs->client_height = pixman_image_get_height(vs->vd->server); + vnc_write_u16(vs, vs->client_width); + vnc_write_u16(vs, vs->client_height); + +@@ -2579,12 +2566,12 @@ + + static int vnc_refresh_server_surface(VncDisplay *vd) + { +- int width = pixman_image_get_width(vd->guest.fb); +- int height = pixman_image_get_height(vd->guest.fb); +- int y; ++ int width = MIN(pixman_image_get_width(vd->guest.fb), ++ pixman_image_get_width(vd->server)); ++ int height = MIN(pixman_image_get_height(vd->guest.fb), ++ pixman_image_get_height(vd->server)); ++ int cmp_bytes, server_stride, min_stride, guest_stride, y = 0; + uint8_t *guest_row0 = NULL, *server_row0; +- int guest_stride = 0, server_stride; +- int cmp_bytes; + VncState *vs; + int has_dirty = 0; + pixman_image_t *tmpbuf = NULL; +@@ -2601,10 +2588,10 @@ + * Check and copy modified bits from guest to server surface. + * Update server dirty map. + */ +- cmp_bytes = VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES; +- if (cmp_bytes > vnc_server_fb_stride(vd)) { +- cmp_bytes = vnc_server_fb_stride(vd); +- } ++ server_row0 = (uint8_t *)pixman_image_get_data(vd->server); ++ server_stride = guest_stride = pixman_image_get_stride(vd->server); ++ cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES, ++ server_stride); + if (vd->guest.format != VNC_SERVER_FB_FORMAT) { + int width = pixman_image_get_width(vd->server); + tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width); +@@ -2612,10 +2599,8 @@ + guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb); + guest_stride = pixman_image_get_stride(vd->guest.fb); + } +- server_row0 = (uint8_t *)pixman_image_get_data(vd->server); +- server_stride = pixman_image_get_stride(vd->server); ++ min_stride = MIN(server_stride, guest_stride); + +- y = 0; + for (;;) { + int x; + uint8_t *guest_ptr, *server_ptr; +@@ -2641,13 +2626,17 @@ + + for (; x < DIV_ROUND_UP(width, VNC_DIRTY_PIXELS_PER_BIT); + x++, guest_ptr += cmp_bytes, server_ptr += cmp_bytes) { ++ int _cmp_bytes = cmp_bytes; + if (!test_and_clear_bit(x, vd->guest.dirty[y])) { + continue; + } +- if (memcmp(server_ptr, guest_ptr, cmp_bytes) == 0) { ++ if ((x + 1) * cmp_bytes > min_stride) { ++ _cmp_bytes = min_stride - x * cmp_bytes; ++ } ++ if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) { + continue; + } +- memcpy(server_ptr, guest_ptr, cmp_bytes); ++ memcpy(server_ptr, guest_ptr, _cmp_bytes); + if (!vd->non_adaptive) { + vnc_rect_updated(vd, x * VNC_DIRTY_PIXELS_PER_BIT, + y, &tv); +Index: qemu-2.0.0+dfsg/ui/vnc.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/ui/vnc.h 2017-04-06 10:09:39.575475045 -0400 ++++ qemu-2.0.0+dfsg/ui/vnc.h 2017-04-06 10:09:39.571474995 -0400 +@@ -77,14 +77,15 @@ + void *last_fg, + int *has_bg, int *has_fg); + +-/* VNC_MAX_WIDTH must be a multiple of 16. */ +-#define VNC_MAX_WIDTH 2560 +-#define VNC_MAX_HEIGHT 2048 +- + /* VNC_DIRTY_PIXELS_PER_BIT is the number of dirty pixels represented +- * by one bit in the dirty bitmap */ ++ * by one bit in the dirty bitmap, should be a power of 2 */ + #define VNC_DIRTY_PIXELS_PER_BIT 16 + ++/* VNC_MAX_WIDTH must be a multiple of VNC_DIRTY_PIXELS_PER_BIT. */ ++ ++#define VNC_MAX_WIDTH ROUND_UP(2560, VNC_DIRTY_PIXELS_PER_BIT) ++#define VNC_MAX_HEIGHT 2048 ++ + /* VNC_DIRTY_BITS is the number of bits in the dirty bitmap. */ + #define VNC_DIRTY_BITS (VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT) + +@@ -126,7 +127,8 @@ + struct VncSurface + { + struct timeval last_freq_check; +- DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], VNC_MAX_WIDTH / 16); ++ DECLARE_BITMAP(dirty[VNC_MAX_HEIGHT], ++ VNC_MAX_WIDTH / VNC_DIRTY_PIXELS_PER_BIT); + VncRectStat stats[VNC_STAT_ROWS][VNC_STAT_COLS]; + pixman_image_t *fb; + pixman_format_code_t format; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5525.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-5525.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5525.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-5525.patch 2017-04-06 13:55:03.000000000 +0000 @@ -0,0 +1,38 @@ +Backport of: + +From 12351a91da97b414eec8cdb09f1d9f41e535a401 Mon Sep 17 00:00:00 2001 +From: Li Qiang +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 +Reviewed-by: Marc-André Lureau +Message-id: 58520052.4825ed0a.27a71.6cae@mx.google.com +Signed-off-by: Gerd Hoffmann +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-5526.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-5526.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5526.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-5526.patch 2017-04-06 13:56:09.000000000 +0000 @@ -0,0 +1,41 @@ +Backport of: + +From 069eb7b2b8fc47c7cb52e5a4af23ea98d939e3da Mon Sep 17 00:00:00 2001 +From: Li Qiang +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 +Reviewed-by: Marc-André Lureau +Message-id: 585200c9.a968ca0a.1ab80.4c98@mx.google.com +Signed-off-by: Gerd Hoffmann +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-5579.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-5579.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5579.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-5579.patch 2017-04-06 13:58:02.000000000 +0000 @@ -0,0 +1,39 @@ +Backport of: + +From 8409dc884a201bf74b30a9d232b6bbdd00cb7e2b Mon Sep 17 00:00:00 2001 +From: Li Qiang +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 +Message-Id: <586cb5ab.f31d9d0a.38ac3.acf2@mx.google.com> +Signed-off-by: Paolo Bonzini +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-5667.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-5667.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5667.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-5667.patch 2017-04-06 13:58:16.000000000 +0000 @@ -0,0 +1,34 @@ +From 42922105beb14c2fc58185ea022b9f72fb5465e9 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +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 +Signed-off-by: Prasad J Pandit +Reviewed-by: Peter Maydell +Message-id: 20170130064736.9236-1-ppandit@redhat.com +Signed-off-by: Peter Maydell +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-5715-1.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-5715-1.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5715-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-5715-1.patch 2018-01-23 16:42:51.000000000 +0000 @@ -0,0 +1,44 @@ +Backport of: + +From 807e9869b8c4119b81df902625af818519e01759 Mon Sep 17 00:00:00 2001 +From: Eduardo Habkost +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" +Signed-off-by: Eduardo Habkost +Message-Id: <20180109154519.25634-2-ehabkost@redhat.com> +Signed-off-by: Eduardo Habkost +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-5715-2.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-5715-2.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5715-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-5715-2.patch 2018-01-23 14:16:12.000000000 +0000 @@ -0,0 +1,136 @@ +Backport of: + +From a33a2cfe2f771b360b3422f6cdf566a560860bfc Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Tue, 9 Jan 2018 13:45:14 -0200 +Subject: [PATCH] i386: Add support for SPEC_CTRL MSR + +Signed-off-by: Eduardo Habkost +Message-Id: <20180109154519.25634-3-ehabkost@redhat.com> +Signed-off-by: Eduardo Habkost +--- + target/i386/cpu.h | 3 +++ + target/i386/kvm.c | 14 ++++++++++++++ + target/i386/machine.c | 20 ++++++++++++++++++++ + 3 files changed, 37 insertions(+) + +Index: qemu-2.0.0+dfsg/target-i386/cpu.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/target-i386/cpu.h 2018-01-23 09:07:57.151079991 -0500 ++++ qemu-2.0.0+dfsg/target-i386/cpu.h 2018-01-23 09:10:15.730765134 -0500 +@@ -305,6 +305,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 +@@ -879,6 +880,7 @@ typedef struct CPUX86State { + struct CPUWatchpoint *cpu_watchpoint[4]; + }; /* break/watchpoints for dr[0..3] */ + uint32_t smbase; ++ uint64_t spec_ctrl; + int old_exception; /* exception in flight */ + + /* KVM states, automatically cleared on reset */ +Index: qemu-2.0.0+dfsg/target-i386/kvm.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/target-i386/kvm.c 2018-01-23 09:07:57.151079991 -0500 ++++ qemu-2.0.0+dfsg/target-i386/kvm.c 2018-01-23 09:16:00.754342811 -0500 +@@ -75,6 +75,7 @@ static int lm_capable_kernel; + static bool has_msr_hv_hypercall; + static bool has_msr_hv_vapic; + static bool has_msr_hv_tsc; ++static bool has_msr_spec_ctrl; + + static bool has_msr_architectural_pmu; + static uint32_t num_architectural_pmu_counters; +@@ -782,6 +783,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; +@@ -1181,6 +1186,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); +@@ -1189,6 +1197,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. +@@ -1488,6 +1497,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; +@@ -1665,6 +1677,9 @@ static int kvm_get_msrs(X86CPU *cpu) + case HV_X64_MSR_REFERENCE_TSC: + env->msr_hv_tsc = msrs[i].data; + break; ++ case MSR_IA32_SPEC_CTRL: ++ env->spec_ctrl = msrs[i].data; ++ break; + } + } + +Index: qemu-2.0.0+dfsg/target-i386/machine.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/target-i386/machine.c 2018-01-23 09:07:57.151079991 -0500 ++++ qemu-2.0.0+dfsg/target-i386/machine.c 2018-01-23 09:13:28.734478157 -0500 +@@ -613,6 +613,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() ++ } ++}; ++ + const VMStateDescription vmstate_x86_cpu = { + .name = "cpu", + .version_id = 12, +@@ -757,6 +775,9 @@ const 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.0.0~rc1+dfsg/debian/patches/CVE-2017-5715-3.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-5715-3.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5715-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-5715-3.patch 2018-01-23 14:22:47.000000000 +0000 @@ -0,0 +1,42 @@ +Backport of: + +From a2381f0934432ef2cd47a335348ba8839632164c Mon Sep 17 00:00:00 2001 +From: Eduardo Habkost +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 +Message-Id: <20180109154519.25634-4-ehabkost@redhat.com> +Signed-off-by: Eduardo Habkost +--- + target/i386/cpu.c | 2 +- + target/i386/cpu.h | 1 + + 2 files changed, 2 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:22:10.650225666 -0500 ++++ qemu-2.0.0+dfsg/target-i386/cpu.c 2018-01-23 09:22:10.630225666 -0500 +@@ -273,7 +273,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, + }; + + typedef struct FeatureWordInfo { +Index: qemu-2.0.0+dfsg/target-i386/cpu.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/target-i386/cpu.h 2018-01-23 09:22:10.650225666 -0500 ++++ qemu-2.0.0+dfsg/target-i386/cpu.h 2018-01-23 09:22:37.058225299 -0500 +@@ -559,6 +559,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 */ + + #define CPUID_VENDOR_SZ 12 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5715-3pre1.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-5715-3pre1.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5715-3pre1.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-5715-3pre1.patch 2018-01-29 19:53:07.000000000 +0000 @@ -0,0 +1,98 @@ +Description: add FEAT_7_0_ECX and FEAT_7_0_EDX for backporting reasons +Author: Marc Deslaurers + +Index: qemu-2.0.0+dfsg/target-i386/cpu.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/target-i386/cpu.c 2018-01-29 14:51:24.809826035 -0500 ++++ qemu-2.0.0+dfsg/target-i386/cpu.c 2018-01-29 14:52:52.517956322 -0500 +@@ -262,6 +262,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, ++}; ++ + typedef struct FeatureWordInfo { + const char **feat_names; + uint32_t cpuid_eax; /* Input EAX for CPUID */ +@@ -299,6 +313,18 @@ static FeatureWordInfo feature_word_info + .feat_names = svm_feature_name, + .cpuid_eax = 0x8000000A, .cpuid_reg = R_EDX, + }, ++ [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, ++ }, ++ [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, ++ }, + [FEAT_7_0_EBX] = { + .feat_names = cpuid_7_0_ebx_feature_name, + .cpuid_eax = 7, +@@ -1745,6 +1771,8 @@ static void x86_cpu_parse_featurestr(CPU + env->features[FEAT_KVM] |= plus_features[FEAT_KVM]; + env->features[FEAT_SVM] |= plus_features[FEAT_SVM]; + env->features[FEAT_7_0_EBX] |= plus_features[FEAT_7_0_EBX]; ++ env->features[FEAT_7_0_ECX] |= plus_features[FEAT_7_0_ECX]; ++ env->features[FEAT_7_0_EDX] |= plus_features[FEAT_7_0_EDX]; + env->features[FEAT_1_EDX] &= ~minus_features[FEAT_1_EDX]; + env->features[FEAT_1_ECX] &= ~minus_features[FEAT_1_ECX]; + env->features[FEAT_8000_0001_EDX] &= ~minus_features[FEAT_8000_0001_EDX]; +@@ -1753,6 +1781,8 @@ static void x86_cpu_parse_featurestr(CPU + env->features[FEAT_KVM] &= ~minus_features[FEAT_KVM]; + env->features[FEAT_SVM] &= ~minus_features[FEAT_SVM]; + env->features[FEAT_7_0_EBX] &= ~minus_features[FEAT_7_0_EBX]; ++ env->features[FEAT_7_0_ECX] &= ~minus_features[FEAT_7_0_ECX]; ++ env->features[FEAT_7_0_EDX] &= ~minus_features[FEAT_7_0_EDX]; + + out: + return; +@@ -1876,6 +1906,8 @@ static void x86_cpu_load_def(X86CPU *cpu + env->features[FEAT_SVM] = def->features[FEAT_SVM]; + env->features[FEAT_C000_0001_EDX] = def->features[FEAT_C000_0001_EDX]; + env->features[FEAT_7_0_EBX] = def->features[FEAT_7_0_EBX]; ++ env->features[FEAT_7_0_ECX] = def->features[FEAT_7_0_ECX]; ++ env->features[FEAT_7_0_EDX] = def->features[FEAT_7_0_EDX]; + env->cpuid_xlevel2 = def->xlevel2; + cpu->cache_info_passthrough = def->cache_info_passthrough; + +@@ -2187,8 +2219,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-2.0.0+dfsg/target-i386/cpu.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/target-i386/cpu.h 2018-01-29 14:51:24.809826035 -0500 ++++ qemu-2.0.0+dfsg/target-i386/cpu.h 2018-01-29 14:51:24.809826035 -0500 +@@ -397,6 +397,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_C000_0001_EDX, /* CPUID[C000_0001].EDX */ diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5715-4.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-5715-4.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5715-4.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-5715-4.patch 2018-01-29 19:55:22.000000000 +0000 @@ -0,0 +1,107 @@ +Backport of: + +From 1b3420e1c4d523c49866cca4e7544753201cd43d Mon Sep 17 00:00:00 2001 +From: Eduardo Habkost +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 +Message-Id: <20180109154519.25634-5-ehabkost@redhat.com> +Signed-off-by: Eduardo Habkost +--- + target/i386/cpu.c | 19 ++++++++++++++++++- + target/i386/cpu.h | 3 +++ + 2 files changed, 21 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-29 14:53:17.329992568 -0500 ++++ qemu-2.0.0+dfsg/target-i386/cpu.c 2018-01-29 14:55:18.770166635 -0500 +@@ -276,6 +276,17 @@ static const char *cpuid_7_0_edx_feature + NULL, NULL, "spec-ctrl", NULL, NULL, NULL, NULL, NULL, + }; + ++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 */ +@@ -331,6 +342,11 @@ static FeatureWordInfo feature_word_info + .cpuid_needs_ecx = true, .cpuid_ecx = 0, + .cpuid_reg = R_EBX, + }, ++ [FEAT_8000_0008_EBX] = { ++ .feat_names = cpuid_8000_0008_ebx_feature_name, ++ .cpuid_eax = 0x80000008, ++ .cpuid_reg = R_EBX, ++ }, + }; + + typedef struct X86RegisterInfo32 { +@@ -1767,6 +1783,7 @@ static void x86_cpu_parse_featurestr(CPU + env->features[FEAT_1_ECX] |= plus_features[FEAT_1_ECX]; + env->features[FEAT_8000_0001_EDX] |= plus_features[FEAT_8000_0001_EDX]; + env->features[FEAT_8000_0001_ECX] |= plus_features[FEAT_8000_0001_ECX]; ++ env->features[FEAT_8000_0008_EBX] |= plus_features[FEAT_8000_0008_EBX]; + env->features[FEAT_C000_0001_EDX] |= plus_features[FEAT_C000_0001_EDX]; + env->features[FEAT_KVM] |= plus_features[FEAT_KVM]; + env->features[FEAT_SVM] |= plus_features[FEAT_SVM]; +@@ -1777,6 +1794,7 @@ static void x86_cpu_parse_featurestr(CPU + env->features[FEAT_1_ECX] &= ~minus_features[FEAT_1_ECX]; + env->features[FEAT_8000_0001_EDX] &= ~minus_features[FEAT_8000_0001_EDX]; + env->features[FEAT_8000_0001_ECX] &= ~minus_features[FEAT_8000_0001_ECX]; ++ env->features[FEAT_8000_0008_EBX] &= ~minus_features[FEAT_8000_0008_EBX]; + env->features[FEAT_C000_0001_EDX] &= ~minus_features[FEAT_C000_0001_EDX]; + env->features[FEAT_KVM] &= ~minus_features[FEAT_KVM]; + env->features[FEAT_SVM] &= ~minus_features[FEAT_SVM]; +@@ -1901,6 +1919,7 @@ static void x86_cpu_load_def(X86CPU *cpu + env->features[FEAT_1_ECX] = def->features[FEAT_1_ECX]; + env->features[FEAT_8000_0001_EDX] = def->features[FEAT_8000_0001_EDX]; + env->features[FEAT_8000_0001_ECX] = def->features[FEAT_8000_0001_ECX]; ++ env->features[FEAT_8000_0008_EBX] = def->features[FEAT_8000_0008_EBX]; + object_property_set_int(OBJECT(cpu), def->xlevel, "xlevel", errp); + env->features[FEAT_KVM] = def->features[FEAT_KVM]; + env->features[FEAT_SVM] = def->features[FEAT_SVM]; +@@ -2380,7 +2399,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-2.0.0+dfsg/target-i386/cpu.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/target-i386/cpu.h 2018-01-29 14:53:17.329992568 -0500 ++++ qemu-2.0.0+dfsg/target-i386/cpu.h 2018-01-29 14:53:17.329992568 -0500 +@@ -401,6 +401,7 @@ typedef enum FeatureWord { + 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_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 */ +@@ -561,6 +562,8 @@ typedef uint32_t FeatureWordArray[FEATUR + #define CPUID_7_0_EBX_SMAP (1U << 20) + #define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) /* Speculation Control */ + ++#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.0.0~rc1+dfsg/debian/patches/CVE-2017-5715-5.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-5715-5.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5715-5.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-5715-5.patch 2018-01-23 16:43:27.000000000 +0000 @@ -0,0 +1,172 @@ +Backport of: + +From ac96c41354b7e4c70b756342d9b686e31ab87458 Mon Sep 17 00:00:00 2001 +From: Eduardo Habkost +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 +Signed-off-by: Eduardo Habkost +Message-Id: <20180109154519.25634-6-ehabkost@redhat.com> +Signed-off-by: Eduardo Habkost +--- + target/i386/cpu.c | 379 +++++++++++++++++++++++++++++++++++++++++++++++++++++- + 1 file changed, 378 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 11:43:26.096347615 -0500 ++++ qemu-2.0.0+dfsg/target-i386/cpu.c 2018-01-23 11:43:26.092347610 -0500 +@@ -932,6 +932,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, +@@ -956,6 +981,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, +@@ -983,6 +1034,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, +@@ -1016,6 +1096,41 @@ static X86CPUDefinition builtin_x86_defs + .model_id = "Intel Core Processor (Haswell)", + }, + { ++ .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.0.0~rc1+dfsg/debian/patches/CVE-2017-5856.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-5856.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5856.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-5856.patch 2017-04-06 13:58:30.000000000 +0000 @@ -0,0 +1,61 @@ +From 765a707000e838c30b18d712fe6cb3dd8e0435f3 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +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 +Signed-off-by: Paolo Bonzini +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-5898.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-5898.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5898.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-5898.patch 2017-04-06 13:59:35.000000000 +0000 @@ -0,0 +1,32 @@ +From c7dfbf322595ded4e70b626bf83158a9f3807c6a Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Fri, 3 Feb 2017 00:52:28 +0530 +Subject: [PATCH] usb: ccid: check ccid apdu length + +CCID device emulator uses Application Protocol Data Units(APDU) +to exchange command and responses to and from the host. +The length in these units couldn't be greater than 65536. Add +check to ensure the same. It'd also avoid potential integer +overflow in emulated_apdu_from_guest. + +Reported-by: Li Qiang +Signed-off-by: Prasad J Pandit +Message-id: 20170202192228.10847-1-ppandit@redhat.com +Signed-off-by: Gerd Hoffmann +--- + hw/usb/dev-smartcard-reader.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: qemu-2.0.0+dfsg/hw/usb/dev-smartcard-reader.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/usb/dev-smartcard-reader.c 2017-04-06 09:59:33.191896354 -0400 ++++ qemu-2.0.0+dfsg/hw/usb/dev-smartcard-reader.c 2017-04-06 09:59:33.191896354 -0400 +@@ -962,7 +962,7 @@ + DPRINTF(s, 1, "%s: seq %d, len %d\n", __func__, + recv->hdr.bSeq, len); + ccid_add_pending_answer(s, (CCID_Header *)recv); +- if (s->card) { ++ if (s->card && len <= BULK_OUT_DATA_SIZE) { + ccid_card_apdu_from_guest(s->card, recv->abData, len); + } else { + DPRINTF(s, D_WARN, "warning: discarded apdu\n"); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5973.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-5973.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5973.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-5973.patch 2017-04-06 13:59:44.000000000 +0000 @@ -0,0 +1,95 @@ +Backport of: + +From f89b60f6e5fee3923bedf80e82b4e5efc1bb156b Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +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: 李强 +Signed-off-by: Gerd Hoffmann +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-2.0.0+dfsg/hw/usb/hcd-xhci.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/usb/hcd-xhci.c 2017-04-06 09:59:42.540013562 -0400 ++++ qemu-2.0.0+dfsg/hw/usb/hcd-xhci.c 2017-04-06 09:59:42.536013512 -0400 +@@ -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) +@@ -1009,6 +1011,7 @@ + return type; + } else { + if (++link_cnt > TRB_LINK_LIMIT) { ++ trace_usb_xhci_enforced_limit("trb-link"); + return 0; + } + ring->dequeue = xhci_mask64(trb->parameter); +@@ -2078,6 +2081,7 @@ + XHCIRing *ring; + USBEndpoint *ep = NULL; + uint64_t mfindex; ++ unsigned int count = 0; + int length; + int i; + +@@ -2216,6 +2220,10 @@ + epctx->retry = xfer; + break; + } ++ if (count++ > TRANSFER_LIMIT) { ++ trace_usb_xhci_enforced_limit("transfers"); ++ break; ++ } + } + + ep = xhci_epid_to_usbep(xhci, slotid, epid); +@@ -2683,7 +2691,7 @@ + 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)) { +@@ -2797,6 +2805,11 @@ + } + event.slotid = slotid; + xhci_event(xhci, &event, 0); ++ ++ if (count++ > COMMAND_LIMIT) { ++ trace_usb_xhci_enforced_limit("commands"); ++ return; ++ } + } + } + +Index: qemu-2.0.0+dfsg/trace-events +=================================================================== +--- qemu-2.0.0+dfsg.orig/trace-events 2017-04-06 09:59:42.540013562 -0400 ++++ qemu-2.0.0+dfsg/trace-events 2017-04-06 09:59:42.540013562 -0400 +@@ -394,6 +394,7 @@ + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-5987-1.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-5987-1.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5987-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-5987-1.patch 2017-04-06 14:00:05.000000000 +0000 @@ -0,0 +1,38 @@ +From 8b20aefac4ee8874bb9c8826e4b30e1dc8cd7511 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +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 +Reviewed-by: Alistair Francis +Message-id: 20170214185225.7994-2-ppandit@redhat.com +Signed-off-by: Peter Maydell +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-5987-2.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-5987-2.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5987-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-5987-2.patch 2017-04-06 14:00:10.000000000 +0000 @@ -0,0 +1,51 @@ +From 6e86d90352adf6cb08295255220295cf23c4286e Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +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 +Reported-by: Jiang Xin +Signed-off-by: Prasad J Pandit +Message-id: 20170214185225.7994-3-ppandit@redhat.com +Reviewed-by: Alistair Francis +Signed-off-by: Peter Maydell +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-5987-3.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-5987-3.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5987-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-5987-3.patch 2017-04-06 14:02:08.000000000 +0000 @@ -0,0 +1,35 @@ +Backport of: + +From 45ba9f761bde329cc5ef276b571bd4f3c41a044e Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +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 +Message-id: 20170214185225.7994-4-ppandit@redhat.com +Reviewed-by: Alistair Francis +Signed-off-by: Peter Maydell +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-5987-4.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-5987-4.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-5987-4.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-5987-4.patch 2017-04-06 14:02:21.000000000 +0000 @@ -0,0 +1,42 @@ +From 241999bf4c0dd75d300ceee46f7ad28b3a39fe97 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +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 +Message-id: 20170214185225.7994-5-ppandit@redhat.com +Reviewed-by: Alistair Francis +Signed-off-by: Peter Maydell +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-6505.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-6505.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-6505.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-6505.patch 2017-04-06 14:02:29.000000000 +0000 @@ -0,0 +1,49 @@ +From 95ed56939eb2eaa4e2f349fe6dcd13ca4edfd8fb Mon Sep 17 00:00:00 2001 +From: Li Qiang +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 +Message-id: 5899a02e.45ca240a.6c373.93c1@mx.google.com +Signed-off-by: Gerd Hoffmann +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-7377.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-7377.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-7377.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-7377.patch 2017-05-10 19:35:11.000000000 +0000 @@ -0,0 +1,48 @@ +Backport of: + +From d63fb193e71644a073b77ff5ac6f1216f2f6cf6e Mon Sep 17 00:00:00 2001 +From: Li Qiang +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 +(reworded the changelog, Greg Kurz) +Signed-off-by: Greg Kurz +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-7493.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-7493.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-7493.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-7493.patch 2017-08-22 14:15:51.000000000 +0000 @@ -0,0 +1,173 @@ +Backport of: + +From 7a95434e0ca8a037fd8aa1a2e2461f92585eb77b Mon Sep 17 00:00:00 2001 +From: Greg Kurz +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 +Signed-off-by: Greg Kurz +Reviewed-by: Eric Blake +--- + hw/9pfs/9p-local.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++++++-- + 1 file changed, 56 insertions(+), 2 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-08-22 10:15:48.712452262 -0400 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p-local.c 2017-08-22 10:15:48.700452261 -0400 +@@ -449,6 +449,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) +@@ -459,8 +464,8 @@ again: + ret = readdir_r(fs->dir, entry, result); + 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; + } + } +@@ -552,6 +557,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; +@@ -597,6 +608,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; +@@ -690,6 +707,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 + */ +@@ -748,6 +771,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; +@@ -822,6 +851,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; +@@ -1089,6 +1124,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); +@@ -1107,6 +1148,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; +@@ -1197,6 +1245,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.0.0~rc1+dfsg/debian/patches/CVE-2017-7718.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-7718.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-7718.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-7718.patch 2017-05-10 19:35:21.000000000 +0000 @@ -0,0 +1,48 @@ +From 215902d7b6fb50c6fc216fc74f770858278ed904 Mon Sep 17 00:00:00 2001 +From: hangaohuai +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 +Signed-off-by: hangaohuai +Message-id: 20170314063919.16200-1-hangaohuai@huawei.com +Signed-off-by: Gerd Hoffmann +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-1.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-1.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-1.patch 2017-05-10 19:47:51.000000000 +0000 @@ -0,0 +1,47 @@ +From f153b563f8cf121aebf5a2fff5f0110faf58ccb3 Mon Sep 17 00:00:00 2001 +From: Wolfgang Bumiller +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 +Message-id: 1485352137-29367-1-git-send-email-w.bumiller@proxmox.com + +[ kraxel: codestyle fixes ] + +Signed-off-by: Gerd Hoffmann +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-2.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-2.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-2.patch 2017-05-10 19:47:57.000000000 +0000 @@ -0,0 +1,99 @@ +From 5858dd1801883309bdd208d72ddb81c4e9fee30c Mon Sep 17 00:00:00 2001 +From: Wolfgang Bumiller +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 +Message-id: 1485272138-23249-1-git-send-email-w.bumiller@proxmox.com +Signed-off-by: Gerd Hoffmann +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-3.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-3.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-3.patch 2017-05-10 19:48:02.000000000 +0000 @@ -0,0 +1,101 @@ +From 60cd23e85151525ab26591394c4e7e06fa07d216 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +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 +Signed-off-by: Gerd Hoffmann +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.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-4.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-4.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-4.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-4.patch 2017-05-10 19:48:10.000000000 +0000 @@ -0,0 +1,101 @@ +From 95280c31cda79bb1d0968afc7b19a220b3a9d986 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +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 +Cc: Dr. David Alan Gilbert +Signed-off-by: Gerd Hoffmann +Reviewed-by: Dr. David Alan Gilbert +Reviewed-by: Wolfgang Bumiller +Reviewed-by: Laurent Vivier +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.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-5.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-5.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-5.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-5.patch 2017-05-10 19:48:16.000000000 +0000 @@ -0,0 +1,100 @@ +From 12e97ec39931e5321645fd483ab761319d48bf16 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +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 +Cc: Dr. David Alan Gilbert +Signed-off-by: Gerd Hoffmann +Reviewed-by: Dr. David Alan Gilbert +Reviewed-by: Laurent Vivier +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.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-6.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-6.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-6.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-6.patch 2017-05-10 19:48:22.000000000 +0000 @@ -0,0 +1,616 @@ +From 026aeffcb4752054830ba203020ed6eb05bcaba8 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +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 +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.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-7.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-7.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-7.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-7.patch 2017-05-10 19:48:27.000000000 +0000 @@ -0,0 +1,441 @@ +From ffaf857778286ca54e3804432a2369a279e73aa7 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +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 +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.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-8.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-8.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-8.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-8.patch 2017-05-10 19:48:32.000000000 +0000 @@ -0,0 +1,34 @@ +From f019722cbbb45aea153294fc8921fcc96a4d3fa2 Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 17 Mar 2017 08:21:36 +0100 +Subject: [PATCH] cirrus: fix off-by-one in cirrus_bitblt_rop_bkwd_transp_*_16 +MIME-Version: 1.0 +Content-Type: text/plain; charset=utf8 +Content-Transfer-Encoding: 8bit + +The switch from pointers to addresses (commit +026aeffcb4752054830ba203020ed6eb05bcaba8 and +ffaf857778286ca54e3804432a2369a279e73aa7) added +a off-by-one bug to 16bit backward blits. Fix. + +Reported-by: 李强 +Signed-off-by: Gerd Hoffmann +Reviewed-by: Li Qiang +Message-id: 1489735296-19047-1-git-send-email-kraxel@redhat.com +--- + hw/display/cirrus_vga_rop.h | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +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:31.346207133 -0400 ++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga_rop.h 2017-05-10 15:48:31.342207096 -0400 +@@ -220,7 +220,7 @@ 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, cirrus_src16(s, srcaddr), transp); ++ ROP_OP_TR_16(s, dstaddr - 1, cirrus_src16(s, srcaddr - 1), transp); + dstaddr -= 2; + srcaddr -= 2; + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-9.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-9.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-7980-9.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-7980-9.patch 2017-05-10 19:48:39.000000000 +0000 @@ -0,0 +1,37 @@ +From e048dac616748273c2153490e9fdf1da242f0cad Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Wed, 15 Mar 2017 13:06:46 +0100 +Subject: [PATCH] cirrus: fix cirrus_invalidate_region + +off_cur_end is exclusive, so off_cur_end == cirrus_addr_mask is valid. +Fix calculation to make sure to allow that, otherwise the assert added +by commit f153b563f8cf121aebf5a2fff5f0110faf58ccb3 can trigger for valid +blits. + +Test case: boot windows nt 4.0 + +Signed-off-by: Gerd Hoffmann +Message-id: 1489579606-26020-1-git-send-email-kraxel@redhat.com +--- + hw/display/cirrus_vga.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 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:37.558266439 -0400 ++++ qemu-2.0.0+dfsg/hw/display/cirrus_vga.c 2017-05-10 15:48:37.554266400 -0400 +@@ -700,11 +700,11 @@ static void cirrus_invalidate_region(Cir + } + + for (y = 0; y < lines; y++) { +- off_cur = off_begin; +- off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask; ++ off_cur = off_begin; ++ off_cur_end = ((off_cur + bytesperline - 1) & s->cirrus_addr_mask) + 1; + assert(off_cur_end >= off_cur); + memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur); +- off_begin += off_pitch; ++ off_begin += off_pitch; + } + } + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-8086.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-8086.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-8086.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-8086.patch 2017-05-10 19:35:47.000000000 +0000 @@ -0,0 +1,30 @@ +Backport of: + +From 4ffcdef4277a91af15a3c09f7d16af072c29f3f2 Mon Sep 17 00:00:00 2001 +From: Li Qiang +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 +Signed-off-by: Greg Kurz +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-8112.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-8112.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-8112.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-8112.patch 2017-08-22 14:15:56.000000000 +0000 @@ -0,0 +1,30 @@ +From f68826989cd4d1217797251339579c57b3c0934e Mon Sep 17 00:00:00 2001 +From: P J P +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 +Signed-off-by: P J P +Message-Id: <20170425130623.3649-1-ppandit@redhat.com> +Reviewed-by: Dmitry Fleytman +Signed-off-by: Paolo Bonzini +--- + hw/scsi/vmw_pvscsi.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: qemu-2.5+dfsg/hw/scsi/vmw_pvscsi.c +=================================================================== +--- qemu-2.5+dfsg.orig/hw/scsi/vmw_pvscsi.c 2017-08-22 09:31:06.424327183 -0400 ++++ qemu-2.5+dfsg/hw/scsi/vmw_pvscsi.c 2017-08-22 09:31:06.396327182 -0400 +@@ -176,7 +176,7 @@ pvscsi_ring_init_msg(PVSCSIRingInfo *m, + uint32_t len_log2; + uint32_t ring_size; + +- if (ri->numPages > PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES) { ++ if (!ri->numPages || ri->numPages > PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES) { + return -1; + } + ring_size = ri->numPages * PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-8309.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-8309.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-8309.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-8309.patch 2017-05-10 19:35:58.000000000 +0000 @@ -0,0 +1,35 @@ +From 3268a845f41253fb55852a8429c32b50f36f349a Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Fri, 28 Apr 2017 09:56:12 +0200 +Subject: [PATCH] audio: release capture buffers + +AUD_add_capture() allocates two buffers which are never released. +Add the missing calls to AUD_del_capture(). + +Impact: Allows vnc clients to exhaust host memory by repeatedly +starting and stopping audio capture. + +Fixes: CVE-2017-8309 +Cc: P J P +Cc: Huawei PSIRT +Reported-by: "Jiangxin (hunter, SCC)" +Signed-off-by: Gerd Hoffmann +Reviewed-by: Prasad J Pandit +Message-id: 20170428075612.9997-1-kraxel@redhat.com +--- + audio/audio.c | 2 ++ + 1 file changed, 2 insertions(+) + +Index: qemu-2.0.0+dfsg/audio/audio.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/audio/audio.c 2017-05-10 15:35:54.506981780 -0400 ++++ qemu-2.0.0+dfsg/audio/audio.c 2017-05-10 15:35:54.498981703 -0400 +@@ -2055,6 +2055,8 @@ void AUD_del_capture (CaptureVoiceOut *c + sw = sw1; + } + QLIST_REMOVE (cap, entries); ++ g_free (cap->hw.mix_buf); ++ g_free (cap->buf); + g_free (cap); + } + return; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-9330.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-9330.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-9330.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-9330.patch 2017-08-22 14:19:47.000000000 +0000 @@ -0,0 +1,30 @@ +Backport of: + +From 26f670a244982335cc08943fb1ec099a2c81e42d Mon Sep 17 00:00:00 2001 +From: Li Qiang +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 +Message-id: 5899ac3e.1033240a.944d5.9a2d@mx.google.com +Signed-off-by: Gerd Hoffmann +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-9373-1.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-9373-1.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-9373-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-9373-1.patch 2017-08-22 14:20:01.000000000 +0000 @@ -0,0 +1,50 @@ +Backport of: + +From c9f086418a255f386e1c4d2c1418c032eb349537 Mon Sep 17 00:00:00 2001 +From: Li Qiang +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 +Message-id: 1488449293-80280-3-git-send-email-liqiang6-s@360.cn +Signed-off-by: John Snow +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-9373-2.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-9373-2.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-9373-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-9373-2.patch 2017-08-22 14:21:53.000000000 +0000 @@ -0,0 +1,39 @@ +Backport of: + +From d68f0f778e7f4fbd674627274267f269e40f0b04 Mon Sep 17 00:00:00 2001 +From: Li Qiang +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 +Message-id: 1488449293-80280-4-git-send-email-liqiang6-s@360.cn +Signed-off-by: John Snow +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-9374.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-9374.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-9374.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-9374.patch 2017-08-22 14:23:31.000000000 +0000 @@ -0,0 +1,77 @@ +Backport of: + +From d710e1e7bd3d5bfc26b631f02ae87901ebe646b0 Mon Sep 17 00:00:00 2001 +From: Li Qiang +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 +Message-id: 589a85b8.3c2b9d0a.b8e6.1434@mx.google.com +Signed-off-by: Gerd Hoffmann +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-9375.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-9375.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-9375.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-9375.patch 2017-08-22 14:23:47.000000000 +0000 @@ -0,0 +1,60 @@ +Backport of: + +From 96d87bdda3919bb16f754b3d3fd1227e1f38f13c Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Thu, 2 Feb 2017 12:36:12 +0100 +Subject: [PATCH] xhci: guard xhci_kick_epctx against recursive calls + +Track xhci_kick_epctx processing being active in a variable. Check the +variable before calling xhci_kick_epctx from xhci_kick_ep. Add an +assert to make sure we don't call recursively into xhci_kick_epctx. + +Cc: 1653384@bugs.launchpad.net +Fixes: 94b037f2a451b3dc855f9f2c346e5049a361bd55 +Reported-by: Fabian Lesniak +Signed-off-by: Gerd Hoffmann +Message-id: 1486035372-3621-1-git-send-email-kraxel@redhat.com +Message-id: 1485790607-31399-5-git-send-email-kraxel@redhat.com +--- + hw/usb/hcd-xhci.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +Index: qemu-2.0.0+dfsg/hw/usb/hcd-xhci.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/usb/hcd-xhci.c 2017-08-22 10:23:44.436474445 -0400 ++++ qemu-2.0.0+dfsg/hw/usb/hcd-xhci.c 2017-08-22 10:23:44.428474445 -0400 +@@ -393,6 +393,7 @@ struct XHCIEPContext { + dma_addr_t pctx; + unsigned int max_psize; + uint32_t state; ++ uint32_t kick_active; + + /* streams */ + unsigned int max_pstreams; +@@ -2100,6 +2101,10 @@ static void xhci_kick_ep(XHCIState *xhci + return; + } + ++ if (epctx->kick_active) { ++ return; ++ } ++ + /* If the device has been detached, but the guest has not noticed this + yet the 2 above checks will succeed, but we must NOT continue */ + if (!xhci->slots[slotid - 1].uport || +@@ -2167,6 +2172,7 @@ static void xhci_kick_ep(XHCIState *xhci + } + assert(ring->dequeue != 0); + ++ epctx->kick_active++; + while (1) { + XHCITransfer *xfer = &epctx->transfers[epctx->next_xfer]; + if (xfer->running_async || xfer->running_retry) { +@@ -2225,6 +2231,7 @@ static void xhci_kick_ep(XHCIState *xhci + break; + } + } ++ epctx->kick_active--; + + ep = xhci_epid_to_usbep(xhci, slotid, epid); + if (ep) { diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-9375-regression.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-9375-regression.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-9375-regression.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-9375-regression.patch 2017-09-20 11:27:28.000000000 +0000 @@ -0,0 +1,51 @@ +Backport of: + +From ddb603ab6c981c1d67cb42266fc700c33e5b2d8f Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Mon, 30 Jan 2017 16:36:46 +0100 +Subject: [PATCH] xhci: don't kick in xhci_submit and xhci_fire_ctl_transfer + +xhci_submit and xhci_fire_ctl_transfer are is called from +xhci_kick_epctx processing loop only, so there is no need to call +xhci_kick_epctx make sure processing continues. Also eecursive calls +into xhci_kick_epctx can cause trouble. + +Drop the xhci_kick_epctx calls. + +Cc: 1653384@bugs.launchpad.net +Fixes: 94b037f2a451b3dc855f9f2c346e5049a361bd55 +Reported-by: Fabian Lesniak +Signed-off-by: Gerd Hoffmann +Message-id: 1485790607-31399-4-git-send-email-kraxel@redhat.com +--- + hw/usb/hcd-xhci.c | 8 -------- + 1 file changed, 8 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/usb/hcd-xhci.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/usb/hcd-xhci.c 2017-09-20 07:27:26.065047730 -0400 ++++ qemu-2.0.0+dfsg/hw/usb/hcd-xhci.c 2017-09-20 07:27:26.065047730 -0400 +@@ -1956,11 +1956,7 @@ static int xhci_fire_ctl_transfer(XHCISt + xfer->packet.parameter = trb_setup->parameter; + + usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); +- + xhci_complete_packet(xfer); +- if (!xfer->running_async && !xfer->running_retry) { +- xhci_kick_ep(xhci, xfer->slotid, xfer->epid, 0); +- } + return 0; + } + +@@ -2060,11 +2056,7 @@ static int xhci_submit(XHCIState *xhci, + return -1; + } + usb_handle_packet(xfer->packet.ep->dev, &xfer->packet); +- + xhci_complete_packet(xfer); +- if (!xfer->running_async && !xfer->running_retry) { +- xhci_kick_ep(xhci, xfer->slotid, xfer->epid, xfer->streamid); +- } + return 0; + } + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-9503-1.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-9503-1.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-9503-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-9503-1.patch 2017-08-22 14:26:25.000000000 +0000 @@ -0,0 +1,91 @@ +Backport of: + +From 660174fc1b346803b3f1d7c260e2a36329b66435 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Thu, 1 Jun 2017 16:45:16 +0200 +Subject: [PATCH] megasas: add qtest + +Signed-off-by: Paolo Bonzini +--- + tests/Makefile.include | 3 +++ + tests/megasas-test.c | 51 ++++++++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 54 insertions(+) + create mode 100644 tests/megasas-test.c + +Index: qemu-2.0.0+dfsg/tests/Makefile +=================================================================== +--- qemu-2.0.0+dfsg.orig/tests/Makefile 2017-08-22 10:23:59.460475146 -0400 ++++ qemu-2.0.0+dfsg/tests/Makefile 2017-08-22 10:26:18.104481611 -0400 +@@ -113,6 +113,8 @@ 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-i386-y = tests/endianness-test$(EXESUF) + check-qtest-i386-y += tests/fdc-test$(EXESUF) +@@ -288,6 +290,7 @@ tests/nvme-test$(EXESUF): tests/nvme-tes + tests/pvpanic-test$(EXESUF): tests/pvpanic-test.o + tests/i82801b11-test$(EXESUF): tests/i82801b11-test.o + tests/qemu-iotests/socket_scm_helper$(EXESUF): tests/qemu-iotests/socket_scm_helper.o ++tests/megasas-test$(EXESUF): tests/megasas-test.o $(libqos-spapr-obj-y) $(libqos-pc-obj-y) + + # QTest rules + +Index: qemu-2.0.0+dfsg/tests/megasas-test.c +=================================================================== +--- /dev/null 1970-01-01 00:00:00.000000000 +0000 ++++ qemu-2.0.0+dfsg/tests/megasas-test.c 2017-08-22 10:23:59.456475146 -0400 +@@ -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.0.0~rc1+dfsg/debian/patches/CVE-2017-9503-2.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-9503-2.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-9503-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-9503-2.patch 2017-08-22 16:28:34.000000000 +0000 @@ -0,0 +1,30 @@ +From 134550bf81a026e18cf58b81e2c2cceaf516f92e Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +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 +--- + hw/scsi/megasas.c | 6 ++++-- + 1 file changed, 4 insertions(+), 2 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:30.576823534 -0400 ++++ qemu-2.0.0+dfsg/hw/scsi/megasas.c 2017-08-22 12:28:30.572823534 -0400 +@@ -288,9 +288,11 @@ static int megasas_build_sense(MegasasCm + { + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-9503-3.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-9503-3.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-9503-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-9503-3.patch 2017-08-22 16:28:39.000000000 +0000 @@ -0,0 +1,37 @@ +From 24c0c77af515acbf0f9705e8096f33ef24d37430 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +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 +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-9503-4.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-9503-4.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-9503-4.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-9503-4.patch 2017-08-22 16:28:45.000000000 +0000 @@ -0,0 +1,115 @@ +Backport of: + +From 5104fac8539eaf155fc6de93e164be43e1e62242 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +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 +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-9503-5.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-9503-5.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-9503-5.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-9503-5.patch 2017-08-22 16:29:23.000000000 +0000 @@ -0,0 +1,223 @@ +Backport of: + +From 36c327a69d723571f02a7691631667cdb1865ee1 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +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 +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-9503-6.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-9503-6.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-9503-6.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-9503-6.patch 2017-08-22 16:31:56.000000000 +0000 @@ -0,0 +1,148 @@ +Backport of: + +From b356807fcdfc45583c437f761fc579ab2a8eab11 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +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 +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-9503-7.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-9503-7.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-9503-7.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-9503-7.patch 2017-08-22 16:32:08.000000000 +0000 @@ -0,0 +1,175 @@ +Backport of: + +From 87e459a810d7b1ec1638085b5a80ea3d9b43119a Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +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 +Signed-off-by: Paolo Bonzini +--- + 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.0.0~rc1+dfsg/debian/patches/CVE-2017-9503-pre1.patch qemu-2.0.0+dfsg/debian/patches/CVE-2017-9503-pre1.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2017-9503-pre1.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2017-9503-pre1.patch 2017-08-22 16:28:13.000000000 +0000 @@ -0,0 +1,279 @@ +Backport of: + +From 3f2cd4dd47719497540fb0e0aa0635e127f2838f Mon Sep 17 00:00:00 2001 +From: Hannes Reinecke +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 +Signed-off-by: Paolo Bonzini +--- + hw/scsi/megasas.c | 95 +++++++++++++++++++++++++++++++++++-------------------- + hw/scsi/mfi.h | 2 +- + 2 files changed, 61 insertions(+), 36 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:26:34.488818120 -0400 ++++ qemu-2.0.0+dfsg/hw/scsi/megasas.c 2017-08-22 12:27:50.268821654 -0400 +@@ -675,8 +675,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) { +@@ -705,13 +704,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); +@@ -738,13 +738,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); +@@ -903,7 +904,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; +@@ -915,22 +915,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); + } +@@ -966,7 +969,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; +@@ -1022,7 +1025,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); +@@ -1033,7 +1036,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; +@@ -1048,6 +1051,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; + +@@ -1057,7 +1061,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) { +@@ -1072,7 +1078,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; + +@@ -1083,9 +1089,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; +@@ -1096,7 +1106,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++; +@@ -1118,7 +1127,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) { +@@ -1235,7 +1244,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; +@@ -1261,7 +1270,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 | +@@ -1547,10 +1556,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, +@@ -1621,7 +1638,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); + } +@@ -2170,8 +2188,12 @@ static int megasas_scsi_init(PCIDevice * + trace_megasas_init(s->fw_sge, s->fw_cmds, + megasas_use_msix(s) ? "MSI-X" : "INTx", + 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-2.0.0+dfsg/hw/scsi/mfi.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/scsi/mfi.h 2017-08-22 12:26:34.488818120 -0400 ++++ qemu-2.0.0+dfsg/hw/scsi/mfi.h 2017-08-22 12:26:34.472818120 -0400 +@@ -1085,7 +1085,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.0.0~rc1+dfsg/debian/patches/CVE-2018-10839.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-10839.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-10839.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-10839.patch 2018-11-21 20:05:51.000000000 +0000 @@ -0,0 +1,43 @@ +From fdc89e90fac40c5ca2686733df17b6423fb8d8fb Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Wed, 30 May 2018 13:08:15 +0800 +Subject: [PATCH] ne2000: fix possible out of bound access in ne2000_receive + +In ne2000_receive(), we try to assign size_ to size which converts +from size_t to integer. This will cause troubles when size_ is greater +INT_MAX, this will lead a negative value in size and it can then pass +the check of size < MIN_BUF_SIZE which may lead out of bound access of +for both buf and buf1. + +Fixing by converting the type of size to size_t. + +CC: qemu-stable@nongnu.org +Reported-by: Daniel Shapira +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Jason Wang +--- + hw/net/ne2000.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/ne2000.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/ne2000.c 2018-11-21 15:05:47.127538541 -0500 ++++ qemu-2.0.0+dfsg/hw/net/ne2000.c 2018-11-21 15:05:47.119538522 -0500 +@@ -183,7 +183,7 @@ int ne2000_can_receive(NetClientState *n + ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_) + { + NE2000State *s = qemu_get_nic_opaque(nc); +- int size = size_; ++ size_t size = size_; + uint8_t *p; + unsigned int total_len, next, avail, len, index, mcast_idx; + uint8_t buf1[60]; +@@ -191,7 +191,7 @@ ssize_t ne2000_receive(NetClientState *n + { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + + #if defined(DEBUG_NE2000) +- printf("NE2000: received len=%d\n", size); ++ printf("NE2000: received len=%zu\n", size); + #endif + + if (s->cmd & E8390_STOP || ne2000_buffer_full(s)) diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-11806.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-11806.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-11806.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-11806.patch 2018-11-21 20:05:55.000000000 +0000 @@ -0,0 +1,95 @@ +Backport of: + +From 864036e251f54c99d31df124aad7f34f01f5344c Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Tue, 5 Jun 2018 23:38:35 +0530 +Subject: [PATCH] slirp: correct size computation while concatenating mbuf + +While reassembling incoming fragmented datagrams, 'm_cat' routine +extends the 'mbuf' buffer, if it has insufficient room. It computes +a wrong buffer size, which leads to overwriting adjacent heap buffer +area. Correct this size computation in m_cat. + +Reported-by: ZDI Disclosures +Signed-off-by: Prasad J Pandit +Signed-off-by: Samuel Thibault +--- + slirp/mbuf.c | 11 +++++------ + slirp/mbuf.h | 8 +++----- + 2 files changed, 8 insertions(+), 11 deletions(-) + +Index: qemu-2.5+dfsg/slirp/mbuf.c +=================================================================== +--- qemu-2.5+dfsg.orig/slirp/mbuf.c 2018-11-21 14:28:47.550137085 -0500 ++++ qemu-2.5+dfsg/slirp/mbuf.c 2018-11-21 14:29:32.778286414 -0500 +@@ -139,7 +139,7 @@ m_cat(struct mbuf *m, struct mbuf *n) + * If there's no room, realloc + */ + if (M_FREEROOM(m) < n->m_len) +- m_inc(m,m->m_size+MINCSIZE); ++ m_inc(m, m->m_len + n->m_len); + + memcpy(m->m_data+m->m_len, n->m_data, n->m_len); + m->m_len += n->m_len; +@@ -148,7 +148,7 @@ m_cat(struct mbuf *m, struct mbuf *n) + } + + +-/* make m size bytes large */ ++/* make m 'size' bytes large from m_data */ + void + m_inc(struct mbuf *m, int size) + { +@@ -159,12 +159,12 @@ m_inc(struct mbuf *m, int size) + + if (m->m_flags & M_EXT) { + datasize = m->m_data - m->m_ext; +- m->m_ext = (char *)realloc(m->m_ext,size); ++ m->m_ext = (char *)realloc(m->m_ext, size + datasize); + m->m_data = m->m_ext + datasize; + } else { + char *dat; + datasize = m->m_data - m->m_dat; +- dat = (char *)malloc(size); ++ dat = (char *)malloc(size + datasize); + memcpy(dat, m->m_dat, m->m_size); + + m->m_ext = dat; +@@ -172,8 +172,7 @@ m_inc(struct mbuf *m, int size) + m->m_flags |= M_EXT; + } + +- m->m_size = size; +- ++ m->m_size = size + datasize; + } + + +Index: qemu-2.5+dfsg/slirp/mbuf.h +=================================================================== +--- qemu-2.5+dfsg.orig/slirp/mbuf.h 2018-11-21 14:28:47.550137085 -0500 ++++ qemu-2.5+dfsg/slirp/mbuf.h 2018-11-21 14:28:47.546137071 -0500 +@@ -33,8 +33,6 @@ + #ifndef _MBUF_H_ + #define _MBUF_H_ + +-#define MINCSIZE 4096 /* Amount to increase mbuf if too small */ +- + /* + * Macros for type conversion + * mtod(m,t) - convert mbuf pointer to data pointer of correct type +@@ -72,11 +70,11 @@ struct mbuf { + struct mbuf *m_prevpkt; /* Flags aren't used in the output queue */ + int m_flags; /* Misc flags */ + +- int m_size; /* Size of data */ ++ int m_size; /* Size of mbuf, from m_dat or m_ext */ + struct socket *m_so; + +- caddr_t m_data; /* Location of data */ +- int m_len; /* Amount of data in this mbuf */ ++ caddr_t m_data; /* Current location of data */ ++ int m_len; /* Amount of data in this mbuf, from m_data */ + + Slirp *slirp; + bool arp_requested; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-12617.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-12617.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-12617.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-12617.patch 2018-11-21 20:07:36.000000000 +0000 @@ -0,0 +1,34 @@ +Backport of: + +From 141b197408ab398c4f474ac1a728ab316e921f2b Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Wed, 13 Jun 2018 11:46:57 +0530 +Subject: [PATCH] qga: check bytes count read by guest-file-read + +While reading file content via 'guest-file-read' command, +'qmp_guest_file_read' routine allocates buffer of count+1 +bytes. It could overflow for large values of 'count'. +Add check to avoid it. + +Reported-by: Fakhri Zulkifli +Signed-off-by: Prasad J Pandit +Cc: qemu-stable@nongnu.org +Signed-off-by: Michael Roth +--- + qga/commands-posix.c | 2 +- + qga/commands-win32.c | 2 +- + 2 files changed, 2 insertions(+), 2 deletions(-) + +Index: qemu-2.0.0+dfsg/qga/commands-posix.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/qga/commands-posix.c 2018-11-21 15:06:05.875582418 -0500 ++++ qemu-2.0.0+dfsg/qga/commands-posix.c 2018-11-21 15:06:42.635668770 -0500 +@@ -449,7 +449,7 @@ struct GuestFileRead *qmp_guest_file_rea + + if (!has_count) { + count = QGA_READ_COUNT_DEFAULT; +- } else if (count < 0) { ++ } else if (count < 0 || count >= UINT32_MAX) { + error_setg(err, "value '%" PRId64 "' is invalid for argument count", + count); + return NULL; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-17958.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-17958.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-17958.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-17958.patch 2018-11-21 20:07:58.000000000 +0000 @@ -0,0 +1,61 @@ +From 1a326646fef38782e5542280040ec3ea23e4a730 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Wed, 30 May 2018 13:07:43 +0800 +Subject: [PATCH] rtl8139: fix possible out of bound access + +In rtl8139_do_receive(), we try to assign size_ to size which converts +from size_t to integer. This will cause troubles when size_ is greater +INT_MAX, this will lead a negative value in size and it can then pass +the check of size < MIN_BUF_SIZE which may lead out of bound access of +for both buf and buf1. + +Fixing by converting the type of size to size_t. + +CC: qemu-stable@nongnu.org +Reported-by: Daniel Shapira +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Jason Wang +--- + hw/net/rtl8139.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/rtl8139.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/rtl8139.c 2018-11-21 15:07:55.943842139 -0500 ++++ qemu-2.0.0+dfsg/hw/net/rtl8139.c 2018-11-21 15:07:55.919842082 -0500 +@@ -822,7 +822,7 @@ static ssize_t rtl8139_do_receive(NetCli + RTL8139State *s = qemu_get_nic_opaque(nc); + PCIDevice *d = PCI_DEVICE(s); + /* size is the length of the buffer passed to the driver */ +- int size = size_; ++ size_t size = size_; + const uint8_t *dot1q_buf = NULL; + + uint32_t packet_header = 0; +@@ -831,7 +831,7 @@ static ssize_t rtl8139_do_receive(NetCli + static const uint8_t broadcast_macaddr[6] = + { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; + +- DPRINTF(">>> received len=%d\n", size); ++ DPRINTF(">>> received len=%zu\n", size); + + /* test if board clock is stopped */ + if (!s->clock_enabled) +@@ -1041,7 +1041,7 @@ static ssize_t rtl8139_do_receive(NetCli + + if (size+4 > rx_space) + { +- DPRINTF("C+ Rx mode : descriptor %d size %d received %d + 4\n", ++ DPRINTF("C+ Rx mode : descriptor %d size %d received %zu + 4\n", + descriptor, rx_space, size); + + s->IntrStatus |= RxOverflow; +@@ -1152,7 +1152,7 @@ static ssize_t rtl8139_do_receive(NetCli + if (avail != 0 && size + 8 >= avail) + { + DPRINTF("rx overflow: rx buffer length %d head 0x%04x " +- "read 0x%04x === available 0x%04x need 0x%04x\n", ++ "read 0x%04x === available 0x%04x need 0x%04zx\n", + s->RxBufferSize, s->RxBufAddr, s->RxBufPtr, avail, size + 8); + + s->IntrStatus |= RxOverflow; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-17962.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-17962.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-17962.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-17962.patch 2018-11-21 20:08:26.000000000 +0000 @@ -0,0 +1,42 @@ +From b1d80d12c5f7ff081bb80ab4f4241d4248691192 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Wed, 30 May 2018 12:11:30 +0800 +Subject: [PATCH] pcnet: fix possible buffer overflow + +In pcnet_receive(), we try to assign size_ to size which converts from +size_t to integer. This will cause troubles when size_ is greater +INT_MAX, this will lead a negative value in size and it can then pass +the check of size < MIN_BUF_SIZE which may lead out of bound access +for both buf and buf1. + +Fixing by converting the type of size to size_t. + +CC: qemu-stable@nongnu.org +Reported-by: Daniel Shapira +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Jason Wang +--- + hw/net/pcnet.c | 4 ++-- + 1 file changed, 2 insertions(+), 2 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/net/pcnet.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/net/pcnet.c 2018-11-21 15:08:23.035906569 -0500 ++++ qemu-2.0.0+dfsg/hw/net/pcnet.c 2018-11-21 15:08:23.027906550 -0500 +@@ -1026,14 +1026,14 @@ ssize_t pcnet_receive(NetClientState *nc + uint8_t buf1[60]; + int remaining; + int crc_err = 0; +- int size = size_; ++ size_t size = size_; + + if (CSR_DRX(s) || CSR_STOP(s) || CSR_SPND(s) || !size || + (CSR_LOOP(s) && !s->looptest)) { + return -1; + } + #ifdef PCNET_DEBUG +- printf("pcnet_receive size=%d\n", size); ++ printf("pcnet_receive size=%zu\n", size); + #endif + + /* if too small buffer, then expand it */ diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-17963.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-17963.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-17963.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-17963.patch 2018-11-21 20:08:32.000000000 +0000 @@ -0,0 +1,38 @@ +From 1592a9947036d60dde5404204a5d45975133caf5 Mon Sep 17 00:00:00 2001 +From: Jason Wang +Date: Wed, 30 May 2018 13:16:36 +0800 +Subject: [PATCH] net: ignore packet size greater than INT_MAX + +There should not be a reason for passing a packet size greater than +INT_MAX. It's usually a hint of bug somewhere, so ignore packet size +greater than INT_MAX in qemu_deliver_packet_iov() + +CC: qemu-stable@nongnu.org +Reported-by: Daniel Shapira +Reviewed-by: Michael S. Tsirkin +Signed-off-by: Jason Wang +--- + net/net.c | 7 ++++++- + 1 file changed, 6 insertions(+), 1 deletion(-) + +Index: qemu-2.0.0+dfsg/net/net.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/net/net.c 2018-11-21 15:08:30.555924485 -0500 ++++ qemu-2.0.0+dfsg/net/net.c 2018-11-21 15:08:30.543924457 -0500 +@@ -562,10 +562,15 @@ ssize_t qemu_deliver_packet_iov(NetClien + void *opaque) + { + NetClientState *nc = opaque; ++ size_t size = iov_size(iov, iovcnt); + int ret; + ++ if (size > INT_MAX) { ++ return size; ++ } ++ + if (nc->link_down) { +- return iov_size(iov, iovcnt); ++ return size; + } + + if (nc->receive_disabled) { diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-18849.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-18849.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-18849.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-18849.patch 2018-11-21 20:09:24.000000000 +0000 @@ -0,0 +1,76 @@ +Backport of: + +From e58ccf039650065a9442de43c9816f81e88f27f6 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Sat, 27 Oct 2018 01:13:14 +0530 +Subject: [PATCH] lsi53c895a: check message length value is valid + +While writing a message in 'lsi_do_msgin', message length value +in 'msg_len' could be invalid due to an invalid migration stream. +Add an assertion to avoid an out of bounds access, and reject +the incoming migration data if it contains an invalid message +length. + +Discovered by Deja vu Security. Reported by Oracle. + +Signed-off-by: Prasad J Pandit +Message-Id: <20181026194314.18663-1-ppandit@redhat.com> +Signed-off-by: Paolo Bonzini +--- + hw/scsi/lsi53c895a.c | 19 +++++++++++++++++-- + 1 file changed, 17 insertions(+), 2 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/scsi/lsi53c895a.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/scsi/lsi53c895a.c 2018-11-21 15:08:43.055954296 -0500 ++++ qemu-2.0.0+dfsg/hw/scsi/lsi53c895a.c 2018-11-21 15:09:17.060035571 -0500 +@@ -827,10 +827,11 @@ static void lsi_do_status(LSIState *s) + + static void lsi_do_msgin(LSIState *s) + { +- int len; ++ uint8_t len; + DPRINTF("Message in len=%d/%d\n", s->dbc, s->msg_len); + s->sfbr = s->msg[0]; + len = s->msg_len; ++ assert(len > 0 && len <= LSI_MAX_MSGIN_LEN); + if (len > s->dbc) + len = s->dbc; + pci_dma_write(PCI_DEVICE(s), s->dnad, s->msg, len); +@@ -1618,8 +1619,10 @@ static uint8_t lsi_reg_readb(LSIState *s + return s->ccntl1; + case 0x58: /* SBDL */ + /* Some drivers peek at the data bus during the MSG IN phase. */ +- if ((s->sstat1 & PHASE_MASK) == PHASE_MI) ++ if ((s->sstat1 & PHASE_MASK) == PHASE_MI) { ++ assert(s->msg_len > 0); + return s->msg[0]; ++ } + return 0; + case 0x59: /* SBDL high */ + return 0; +@@ -1990,12 +1993,24 @@ static void lsi_pre_save(void *opaque) + assert(QTAILQ_EMPTY(&s->queue)); + } + ++static int lsi_post_load(void *opaque, int version_id) ++{ ++ LSIState *s = opaque; ++ ++ if (s->msg_len < 0 || s->msg_len > LSI_MAX_MSGIN_LEN) { ++ return -EINVAL; ++ } ++ ++ return 0; ++} ++ + static const VMStateDescription vmstate_lsi_scsi = { + .name = "lsiscsi", + .version_id = 0, + .minimum_version_id = 0, + .minimum_version_id_old = 0, + .pre_save = lsi_pre_save, ++ .post_load = lsi_post_load, + .fields = (VMStateField []) { + VMSTATE_PCI_DEVICE(parent_obj, LSIState), + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-19364-1.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-19364-1.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-19364-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-19364-1.patch 2018-11-21 20:10:03.000000000 +0000 @@ -0,0 +1,42 @@ +From 5b76ef50f62079a2389ba28cacaf6cce68b1a0ed Mon Sep 17 00:00:00 2001 +From: Greg Kurz +Date: Wed, 7 Nov 2018 01:00:04 +0100 +Subject: [PATCH] 9p: write lock path in v9fs_co_open2() + +The assumption that the fid cannot be used by any other operation is +wrong. At least, nothing prevents a misbehaving client to create a +file with a given fid, and to pass this fid to some other operation +at the same time (ie, without waiting for the response to the creation +request). The call to v9fs_path_copy() performed by the worker thread +after the file was created can race with any access to the fid path +performed by some other thread. This causes use-after-free issues that +can be detected by ASAN with a custom 9p client. + +Unlike other operations that only read the fid path, v9fs_co_open2() +does modify it. It should hence take the write lock. + +Cc: P J P +Reported-by: zhibin hu +Signed-off-by: Greg Kurz +--- + hw/9pfs/cofile.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +Index: qemu-2.5+dfsg/hw/9pfs/cofile.c +=================================================================== +--- qemu-2.5+dfsg.orig/hw/9pfs/cofile.c 2018-11-21 14:42:46.408701137 -0500 ++++ qemu-2.5+dfsg/hw/9pfs/cofile.c 2018-11-21 14:42:46.404701125 -0500 +@@ -138,10 +138,10 @@ int v9fs_co_open2(V9fsPDU *pdu, V9fsFidS + cred.fc_gid = gid; + /* + * Hold the directory fid lock so that directory path name +- * don't change. Read lock is fine because this fid cannot +- * be used by any other operation. ++ * don't change. Take the write lock to be sure this fid ++ * cannot be used by another operation. + */ +- v9fs_path_read_lock(s); ++ v9fs_path_write_lock(s); + v9fs_co_run_in_worker( + { + err = s->ops->open2(&s->ctx, &fidp->path, diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-19364-2.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-19364-2.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-19364-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-19364-2.patch 2018-11-21 20:10:10.000000000 +0000 @@ -0,0 +1,108 @@ +Backport of: + +From 5b3c77aa581ebb215125c84b0742119483571e55 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +Date: Tue, 20 Nov 2018 13:00:35 +0100 +Subject: [PATCH] 9p: take write lock on fid path updates (CVE-2018-19364) + +Recent commit 5b76ef50f62079a fixed a race where v9fs_co_open2() could +possibly overwrite a fid path with v9fs_path_copy() while it is being +accessed by some other thread, ie, use-after-free that can be detected +by ASAN with a custom 9p client. + +It turns out that the same can happen at several locations where +v9fs_path_copy() is used to set the fid path. The fix is again to +take the write lock. + +Fixes CVE-2018-19364. + +Cc: P J P +Reported-by: zhibin hu +Reviewed-by: Prasad J Pandit +Signed-off-by: Greg Kurz +--- + hw/9pfs/9p.c | 15 +++++++++++++++ + 1 file changed, 15 insertions(+) + +Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p.c 2018-11-21 15:10:08.488158968 -0500 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c 2018-11-21 15:10:08.484158958 -0500 +@@ -1324,7 +1324,9 @@ static void v9fs_walk(void *opaque) + } + if (fid == newfid) { + BUG_ON(fidp->fid_type != P9_FID_NONE); ++ v9fs_path_write_lock(s); + v9fs_path_copy(&fidp->path, &path); ++ v9fs_path_unlock(s); + } else { + newfidp = alloc_fid(s, newfid); + if (newfidp == NULL) { +@@ -2070,6 +2072,7 @@ static void v9fs_create(void *opaque) + V9fsString extension; + int iounit; + V9fsPDU *pdu = opaque; ++ V9fsState *s = pdu->s; + + v9fs_path_init(&path); + v9fs_string_init(&name); +@@ -2110,7 +2113,9 @@ static void v9fs_create(void *opaque) + if (err < 0) { + goto out; + } ++ v9fs_path_write_lock(s); + v9fs_path_copy(&fidp->path, &path); ++ v9fs_path_unlock(s); + err = v9fs_co_opendir(pdu, fidp); + if (err < 0) { + goto out; +@@ -2126,7 +2131,9 @@ static void v9fs_create(void *opaque) + if (err < 0) { + goto out; + } ++ v9fs_path_write_lock(s); + v9fs_path_copy(&fidp->path, &path); ++ v9fs_path_unlock(s); + } else if (perm & P9_STAT_MODE_LINK) { + int32_t ofid = atoi(extension.data); + V9fsFidState *ofidp = get_fid(pdu, ofid); +@@ -2144,7 +2151,9 @@ static void v9fs_create(void *opaque) + fidp->fid_type = P9_FID_NONE; + goto out; + } ++ v9fs_path_write_lock(s); + v9fs_path_copy(&fidp->path, &path); ++ v9fs_path_unlock(s); + err = v9fs_co_lstat(pdu, &fidp->path, &stbuf); + if (err < 0) { + fidp->fid_type = P9_FID_NONE; +@@ -2182,7 +2191,9 @@ static void v9fs_create(void *opaque) + if (err < 0) { + goto out; + } ++ v9fs_path_write_lock(s); + v9fs_path_copy(&fidp->path, &path); ++ v9fs_path_unlock(s); + } else if (perm & P9_STAT_MODE_NAMED_PIPE) { + err = v9fs_co_mknod(pdu, fidp, &name, fidp->uid, -1, + 0, S_IFIFO | (perm & 0777), &stbuf); +@@ -2193,7 +2204,9 @@ static void v9fs_create(void *opaque) + if (err < 0) { + goto out; + } ++ v9fs_path_write_lock(s); + v9fs_path_copy(&fidp->path, &path); ++ v9fs_path_unlock(s); + } else if (perm & P9_STAT_MODE_SOCKET) { + err = v9fs_co_mknod(pdu, fidp, &name, fidp->uid, -1, + 0, S_IFSOCK | (perm & 0777), &stbuf); +@@ -2204,7 +2217,9 @@ static void v9fs_create(void *opaque) + if (err < 0) { + goto out; + } ++ v9fs_path_write_lock(s); + v9fs_path_copy(&fidp->path, &path); ++ v9fs_path_unlock(s); + } else { + err = v9fs_co_open2(pdu, fidp, &name, -1, + omode_to_uflags(mode)|O_CREAT, perm, &stbuf); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-19489.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-19489.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-19489.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-19489.patch 2019-03-22 21:08:29.000000000 +0000 @@ -0,0 +1,68 @@ +Backport of: + +From 1d20398694a3b67a388d955b7a945ba4aa90a8a8 Mon Sep 17 00:00:00 2001 +From: Greg Kurz +Date: Fri, 23 Nov 2018 13:28:03 +0100 +Subject: [PATCH] 9p: fix QEMU crash when renaming files + +When using the 9P2000.u version of the protocol, the following shell +command line in the guest can cause QEMU to crash: + + while true; do rm -rf aa; mkdir -p a/b & touch a/b/c & mv a aa; done + +With 9P2000.u, file renaming is handled by the WSTAT command. The +v9fs_wstat() function calls v9fs_complete_rename(), which calls +v9fs_fix_path() for every fid whose path is affected by the change. +The involved calls to v9fs_path_copy() may race with any other access +to the fid path performed by some worker thread, causing a crash like +shown below: + +Thread 12 "qemu-system-x86" received signal SIGSEGV, Segmentation fault. +0x0000555555a25da2 in local_open_nofollow (fs_ctx=0x555557d958b8, path=0x0, + flags=65536, mode=0) at hw/9pfs/9p-local.c:59 +59 while (*path && fd != -1) { +(gdb) bt +#0 0x0000555555a25da2 in local_open_nofollow (fs_ctx=0x555557d958b8, + path=0x0, flags=65536, mode=0) at hw/9pfs/9p-local.c:59 +#1 0x0000555555a25e0c in local_opendir_nofollow (fs_ctx=0x555557d958b8, + path=0x0) at hw/9pfs/9p-local.c:92 +#2 0x0000555555a261b8 in local_lstat (fs_ctx=0x555557d958b8, + fs_path=0x555556b56858, stbuf=0x7fff84830ef0) at hw/9pfs/9p-local.c:185 +#3 0x0000555555a2b367 in v9fs_co_lstat (pdu=0x555557d97498, + path=0x555556b56858, stbuf=0x7fff84830ef0) at hw/9pfs/cofile.c:53 +#4 0x0000555555a1e9e2 in v9fs_stat (opaque=0x555557d97498) + at hw/9pfs/9p.c:1083 +#5 0x0000555555e060a2 in coroutine_trampoline (i0=-669165424, i1=32767) + at util/coroutine-ucontext.c:116 +#6 0x00007fffef4f5600 in __start_context () at /lib64/libc.so.6 +#7 0x0000000000000000 in () +(gdb) + +The fix is to take the path write lock when calling v9fs_complete_rename(), +like in v9fs_rename(). + +Impact: DoS triggered by unprivileged guest users. + +Fixes: CVE-2018-19489 +Cc: P J P +Reported-by: zhibin hu +Reviewed-by: Prasad J Pandit +Signed-off-by: Greg Kurz +--- + hw/9pfs/9p.c | 3 +++ + 1 file changed, 3 insertions(+) + +Index: qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/9pfs/virtio-9p.c 2019-03-22 17:08:27.165182549 -0400 ++++ qemu-2.0.0+dfsg/hw/9pfs/virtio-9p.c 2019-03-22 17:08:27.161182539 -0400 +@@ -2799,7 +2799,9 @@ static void v9fs_wstat(void *opaque) + } + } + if (v9stat.name.size != 0) { ++ v9fs_path_write_lock(s); + err = v9fs_complete_rename(pdu, fidp, -1, &v9stat.name); ++ v9fs_path_unlock(s); + if (err < 0) { + goto out; + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-20815.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-20815.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-20815.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-20815.patch 2019-05-09 06:59:11.000000000 +0000 @@ -0,0 +1,35 @@ +From da885fe1ee8b4589047484bd7fa05a4905b52b17 Mon Sep 17 00:00:00 2001 +From: Peter Maydell +Date: Fri, 14 Dec 2018 13:30:52 +0000 +Subject: [PATCH] device_tree.c: Don't use load_image() + +The load_image() function is deprecated, as it does not let the +caller specify how large the buffer to read the file into is. +Instead use load_image_size(). + +Signed-off-by: Peter Maydell +Reviewed-by: Richard Henderson +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Michael S. Tsirkin +Reviewed-by: Eric Blake +Message-id: 20181130151712.2312-9-peter.maydell@linaro.org + +CVE-2018-20815 + +--- + device_tree.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: b/device_tree.c +=================================================================== +--- a/device_tree.c ++++ b/device_tree.c +@@ -90,7 +90,7 @@ void *load_device_tree(const char *filen + /* First allocate space in qemu for device tree */ + fdt = g_malloc0(dt_size); + +- dt_file_load_size = load_image(filename_path, fdt); ++ dt_file_load_size = load_image_size(filename_path, fdt, dt_size); + if (dt_file_load_size < 0) { + printf("Unable to open device tree file '%s'\n", + filename_path); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-20815-prereq-1.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-20815-prereq-1.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-20815-prereq-1.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-20815-prereq-1.patch 2019-05-09 06:59:27.000000000 +0000 @@ -0,0 +1,66 @@ +From ea87616d6c44d998affef3d3b9fdfc49d14b8150 Mon Sep 17 00:00:00 2001 +From: Benjamin Herrenschmidt +Date: Mon, 21 Jul 2014 13:02:03 +1000 +Subject: [PATCH] loader: Add load_image_size() to replace load_image() + +A subsequent patch to ppc/spapr needs to load the RTAS blob into +qemu memory rather than target memory (so it can later be copied +into the right spot at machine reset time). + +I would use load_image() but it is marked deprecated because it +doesn't take a buffer size as argument, so let's add load_image_size() +that does. + +Signed-off-by: Benjamin Herrenschmidt +[aik: fixed errors from checkpatch.pl] +Signed-off-by: Alexey Kardashevskiy +Signed-off-by: Alexander Graf +--- + hw/core/loader.c | 21 +++++++++++++++++++++ + include/hw/loader.h | 1 + + 2 files changed, 22 insertions(+) + +Index: b/hw/core/loader.c +=================================================================== +--- a/hw/core/loader.c ++++ b/hw/core/loader.c +@@ -89,6 +89,27 @@ int load_image(const char *filename, uin + return size; + } + ++/* return the size or -1 if error */ ++ssize_t load_image_size(const char *filename, void *addr, size_t size) ++{ ++ int fd; ++ ssize_t actsize; ++ ++ fd = open(filename, O_RDONLY | O_BINARY); ++ if (fd < 0) { ++ return -1; ++ } ++ ++ actsize = read(fd, addr, size); ++ if (actsize < 0) { ++ close(fd); ++ return -1; ++ } ++ close(fd); ++ ++ return actsize; ++} ++ + /* read()-like version */ + ssize_t read_targphys(const char *name, + int fd, hwaddr dst_addr, size_t nbytes) +Index: b/include/hw/loader.h +=================================================================== +--- a/include/hw/loader.h ++++ b/include/hw/loader.h +@@ -13,6 +13,7 @@ + */ + int get_image_size(const char *filename); + int load_image(const char *filename, uint8_t *addr); /* deprecated */ ++ssize_t load_image_size(const char *filename, void *addr, size_t size); + int load_image_targphys(const char *filename, hwaddr, + uint64_t max_sz); + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-20815-prereq-2.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-20815-prereq-2.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-20815-prereq-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-20815-prereq-2.patch 2019-05-09 06:58:22.000000000 +0000 @@ -0,0 +1,52 @@ +From 1f40547f5ce0c135faa7d14f066b97002fd8c204 Mon Sep 17 00:00:00 2001 +From: Li Zhijian +Date: Thu, 17 Jan 2019 20:49:02 +0800 +Subject: [PATCH] hw/core/loader.c: Read as long as possible in + load_image_size() + +Don't expect read(2) can always read as many as it's told. + +CC: Richard Henderson +CC: Stefano Garzarella +Signed-off-by: Li Zhijian +Reviewed-by: Richard Henderson +Reviewed-by: Stefano Garzarella +Signed-off-by: Paolo Bonzini +--- + hw/core/loader.c | 11 +++++------ + 1 file changed, 5 insertions(+), 6 deletions(-) + +diff --git a/hw/core/loader.c b/hw/core/loader.c +index 3a000d576b..fe5cb24122 100644 +--- a/hw/core/loader.c ++++ b/hw/core/loader.c +@@ -77,21 +77,20 @@ int64_t get_image_size(const char *filename) + ssize_t load_image_size(const char *filename, void *addr, size_t size) + { + int fd; +- ssize_t actsize; ++ ssize_t actsize, l = 0; + + fd = open(filename, O_RDONLY | O_BINARY); + if (fd < 0) { + return -1; + } + +- actsize = read(fd, addr, size); +- if (actsize < 0) { +- close(fd); +- return -1; ++ while ((actsize = read(fd, addr + l, size - l)) > 0) { ++ l += actsize; + } ++ + close(fd); + +- return actsize; ++ return actsize < 0 ? -1 : l; + } + + /* read()-like version */ +-- +2.17.1 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-3639-2.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-3639-2.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-3639-2.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-3639-2.patch 2018-05-23 12:02:57.000000000 +0000 @@ -0,0 +1,34 @@ +Backport of: + +From 6cf7cfef30a220709a13b987fc9aca0bd3d63110 Mon Sep 17 00:00:00 2001 +From: Konrad Rzeszutek Wilk +Date: Wed, 16 May 2018 21:37:31 -0400 +Subject: [PATCH v3 2/5] i386: define the AMD 'virt-ssbd' CPUID feature bit + (CVE-2018-3639) + +AMD Zen expose the Intel equivalant to Speculative Store Bypass Disable +via the 0x80000008_EBX[25] CPUID feature bit. + +This needs to be exposed to guest OS to allow them to protect +against CVE-2018-3639. + +Signed-off-by: Konrad Rzeszutek Wilk +--- +v2: Wrong bit position. +--- + target-i386/cpu.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +Index: qemu-2.0.0+dfsg/target-i386/cpu.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/target-i386/cpu.c 2018-05-18 15:47:28.777292738 -0400 ++++ qemu-2.0.0+dfsg/target-i386/cpu.c 2018-05-18 15:47:28.777292738 -0400 +@@ -283,7 +283,7 @@ static const char *cpuid_8000_0008_ebx_f + "ibpb", NULL, NULL, NULL, + NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, +- NULL, NULL, NULL, NULL, ++ NULL, "virt-ssbd", NULL, NULL, + NULL, NULL, NULL, NULL, + }; + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-3639-3.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-3639-3.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-3639-3.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-3639-3.patch 2018-05-23 12:03:03.000000000 +0000 @@ -0,0 +1,140 @@ +Backport of: + +From 80efc2c39c6b30aa077771903e87f8636af90605 Mon Sep 17 00:00:00 2001 +From: Konrad Rzeszutek Wilk +Date: Wed, 16 May 2018 22:27:11 -0400 +Subject: [PATCH v3 3/5] i386: Define the Virt SSBD MSR and handling of it + (CVE-2018-3639) + +"Some AMD processors only support a non-architectural means of enabling +speculative store bypass disable (SSBD). To allow a simplified view of +this to a guest, an architectural definition has been created through a new +CPUID bit, 0x80000008_EBX[25], and a new MSR, 0xc001011f. With this, a +hypervisor can virtualize the existence of this definition and provide an +architectural method for using SSBD to a guest. + +Add the new CPUID feature, the new MSR and update the existing SSBD +support to use this MSR when present." (from x86/speculation: Add virtualized +speculative store bypass disable support in Linux). + +Signed-off-by: Konrad Rzeszutek Wilk +--- + target-i386/cpu.h | 2 ++ + target-i386/kvm.c | 16 ++++++++++++++-- + target-i386/machine.c | 20 ++++++++++++++++++++ + 3 files changed, 36 insertions(+), 2 deletions(-) + +Index: qemu-2.0.0+dfsg/target-i386/cpu.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/target-i386/cpu.h 2018-05-18 16:05:42.447807156 -0400 ++++ qemu-2.0.0+dfsg/target-i386/cpu.h 2018-05-18 16:05:42.447807156 -0400 +@@ -306,6 +306,7 @@ + #define MSR_IA32_FEATURE_CONTROL 0x0000003a + #define MSR_TSC_ADJUST 0x0000003b + #define MSR_IA32_SPEC_CTRL 0x48 ++#define MSR_VIRT_SSBD 0xc001011f + #define MSR_IA32_TSCDEADLINE 0x6e0 + + #define MSR_P6_PERFCTR0 0xc1 +@@ -888,6 +889,7 @@ typedef struct CPUX86State { + }; /* break/watchpoints for dr[0..3] */ + uint32_t smbase; + uint64_t spec_ctrl; ++ uint64_t virt_ssbd; + int old_exception; /* exception in flight */ + + /* KVM states, automatically cleared on reset */ +Index: qemu-2.0.0+dfsg/target-i386/kvm.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/target-i386/kvm.c 2018-05-18 16:05:42.447807156 -0400 ++++ qemu-2.0.0+dfsg/target-i386/kvm.c 2018-05-18 16:06:01.319846437 -0400 +@@ -76,6 +76,7 @@ static bool has_msr_hv_hypercall; + static bool has_msr_hv_vapic; + static bool has_msr_hv_tsc; + static bool has_msr_spec_ctrl; ++static bool has_msr_virt_ssbd; + + static bool has_msr_architectural_pmu; + static uint32_t num_architectural_pmu_counters; +@@ -787,6 +788,10 @@ static int kvm_get_supported_msrs(KVMSta + has_msr_spec_ctrl = true; + continue; + } ++ if (kvm_msr_list->indices[i] == MSR_VIRT_SSBD) { ++ has_msr_virt_ssbd = true; ++ continue; ++ } + if (kvm_msr_list->indices[i] == MSR_IA32_TSCDEADLINE) { + has_msr_tsc_deadline = true; + continue; +@@ -1189,6 +1194,10 @@ static int kvm_put_msrs(X86CPU *cpu, int + if (has_msr_spec_ctrl) { + kvm_msr_entry_set(&msrs[n++], MSR_IA32_SPEC_CTRL, env->spec_ctrl); + } ++ if (has_msr_virt_ssbd) { ++ kvm_msr_entry_set(&msrs[n++], MSR_VIRT_SSBD, env->virt_ssbd); ++ } ++ + #ifdef TARGET_X86_64 + if (lm_capable_kernel) { + kvm_msr_entry_set(&msrs[n++], MSR_CSTAR, env->cstar); +@@ -1500,7 +1509,9 @@ static int kvm_get_msrs(X86CPU *cpu) + if (has_msr_spec_ctrl) { + msrs[n++].index = MSR_IA32_SPEC_CTRL; + } +- ++ if (has_msr_virt_ssbd) { ++ msrs[n++].index = MSR_VIRT_SSBD; ++ } + if (!env->tsc_valid) { + msrs[n++].index = MSR_IA32_TSC; + env->tsc_valid = !runstate_is_running(); +@@ -1680,6 +1691,9 @@ static int kvm_get_msrs(X86CPU *cpu) + case MSR_IA32_SPEC_CTRL: + env->spec_ctrl = msrs[i].data; + break; ++ case MSR_VIRT_SSBD: ++ env->virt_ssbd = msrs[i].data; ++ break; + } + } + +Index: qemu-2.0.0+dfsg/target-i386/machine.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/target-i386/machine.c 2018-05-18 16:05:42.447807156 -0400 ++++ qemu-2.0.0+dfsg/target-i386/machine.c 2018-05-18 16:05:42.447807156 -0400 +@@ -631,6 +631,24 @@ static const VMStateDescription vmstate_ + } + }; + ++static bool virt_ssbd_needed(void *opaque) ++{ ++ X86CPU *cpu = opaque; ++ CPUX86State *env = &cpu->env; ++ ++ return env->virt_ssbd != 0; ++} ++ ++static const VMStateDescription vmstate_msr_virt_ssbd = { ++ .name = "cpu/virt_ssbd", ++ .version_id = 1, ++ .minimum_version_id = 1, ++ .fields = (VMStateField[]){ ++ VMSTATE_UINT64(env.virt_ssbd, X86CPU), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ + const VMStateDescription vmstate_x86_cpu = { + .name = "cpu", + .version_id = 12, +@@ -778,6 +796,9 @@ const VMStateDescription vmstate_x86_cpu + .vmsd = &vmstate_spec_ctrl, + .needed = spec_ctrl_needed, + } , { ++ .vmsd = &vmstate_msr_virt_ssbd, ++ .needed = virt_ssbd_needed, ++ } , { + /* empty */ + } + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-3639.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-3639.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-3639.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-3639.patch 2018-05-17 14:08:55.000000000 +0000 @@ -0,0 +1,53 @@ +Backport of: + +From 00dbdaa9813ec9fbeb035d96a088a429b1231a93 Mon Sep 17 00:00:00 2001 +From: Konrad Rzeszutek Wilk +Date: Wed, 11 Apr 2018 17:26:51 -0400 +Subject: [PATCH v3] i386: Add bit(2) of SPEC_CTRL MSR support - SSBD + +i386: Add bit(2) of SPEC_CTRL MSR support - Reduced Data Speculation + +Now users can do: + +cpu host,+spec-ctrl,+ssbd + +to have both IBRS and SSBD support. + +Signed-off-by: Konrad Rzeszutek Wilk +--- + +v3: s/ssb/rds/ +v4: s/spec_store_bypass/rds/ + s/MDD/Reduced Data Speculation/ +v5: Rip it out of the builtin_x86_defs per Paolo's recommendation + s/RDS/SSBD/ + + target/i386/cpu.c | 22 +++++++++++----------- + target/i386/cpu.h | 1 + + 2 files changed, 12 insertions(+), 11 deletions(-) + +Index: qemu-2.0.0+dfsg/target-i386/cpu.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/target-i386/cpu.c 2018-05-17 10:08:53.451018751 -0400 ++++ qemu-2.0.0+dfsg/target-i386/cpu.c 2018-05-17 10:08:53.447018743 -0400 +@@ -273,7 +273,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, "spec-ctrl", NULL, NULL, NULL, NULL, NULL, ++ NULL, NULL, "spec-ctrl", NULL, NULL, NULL, NULL, "ssbd", + }; + + static const char *cpuid_8000_0008_ebx_feature_name[] = { +Index: qemu-2.0.0+dfsg/target-i386/cpu.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/target-i386/cpu.h 2018-05-17 10:08:53.451018751 -0400 ++++ qemu-2.0.0+dfsg/target-i386/cpu.h 2018-05-17 10:08:53.447018743 -0400 +@@ -561,6 +561,7 @@ typedef uint32_t FeatureWordArray[FEATUR + #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 */ ++#define CPUID_7_0_EDX_SPEC_CTRL_SSBD (1U << 31) /* Speculative Store Bypass Disable */ + + #define CPUID_8000_0008_EBX_IBPB (1U << 12) /* Indirect Branch Prediction Barrier */ + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-5683.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-5683.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-5683.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-5683.patch 2018-02-15 18:33:12.000000000 +0000 @@ -0,0 +1,53 @@ +From 191f59dc17396bb5a8da50f8c59b6e0a430711a4 Mon Sep 17 00:00:00 2001 +From: linzhecheng +Date: Thu, 11 Jan 2018 21:27:24 +0800 +Subject: [PATCH] vga: check the validation of memory addr when draw text + +Start a vm with qemu-kvm -enable-kvm -vnc :66 -smp 1 -m 1024 -hda +redhat_5.11.qcow2 -device pcnet -vga cirrus, +then use VNC client to connect to VM, and excute the code below in guest +OS will lead to qemu crash: + +int main() + { + iopl(3); + srand(time(NULL)); + int a,b; + while(1){ + a = rand()%0x100; + b = 0x3c0 + (rand()%0x20); + outb(a,b); + } + return 0; +} + +The above code is writing the registers of VGA randomly. +We can write VGA CRT controller registers index 0x0C or 0x0D +(which is the start address register) to modify the +the display memory address of the upper left pixel +or character of the screen. The address may be out of the +range of vga ram. So we should check the validation of memory address +when reading or writing it to avoid segfault. + +Signed-off-by: linzhecheng +Message-id: 20180111132724.13744-1-linzhecheng@huawei.com +Fixes: CVE-2018-5683 +Signed-off-by: Gerd Hoffmann +--- + hw/display/vga.c | 3 +++ + 1 file changed, 3 insertions(+) + +Index: qemu-2.0.0+dfsg/hw/display/vga.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/display/vga.c 2018-02-15 13:33:10.539156013 -0500 ++++ qemu-2.0.0+dfsg/hw/display/vga.c 2018-02-15 13:33:10.535156012 -0500 +@@ -1477,6 +1477,9 @@ static void vga_draw_text(VGACommonState + cx_min = width; + cx_max = -1; + for(cx = 0; cx < width; cx++) { ++ if (src + sizeof(uint16_t) > s->vram_ptr + s->vram_size) { ++ break; ++ } + ch_attr = *(uint16_t *)src; + if (full_update || ch_attr != *ch_attr_ptr || src == cursor_ptr) { + if (cx < cx_min) diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-7550.patch qemu-2.0.0+dfsg/debian/patches/CVE-2018-7550.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2018-7550.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2018-7550.patch 2018-05-11 17:35:03.000000000 +0000 @@ -0,0 +1,55 @@ +From 2a8fcd119eb7c6bb3837fc3669eb1b2dfb31daf8 Mon Sep 17 00:00:00 2001 +From: Jack Schwartz +Date: Thu, 21 Dec 2017 09:25:15 -0800 +Subject: [PATCH] multiboot: bss_end_addr can be zero + +The multiboot spec (https://www.gnu.org/software/grub/manual/multiboot/), +section 3.1.3, allows for bss_end_addr to be zero. + +A zero bss_end_addr signifies there is no .bss section. + +Suggested-by: Daniel Kiper +Signed-off-by: Jack Schwartz +Reviewed-by: Daniel Kiper +Reviewed-by: Prasad J Pandit +Signed-off-by: Kevin Wolf +--- + hw/i386/multiboot.c | 18 ++++++++++-------- + 1 file changed, 10 insertions(+), 8 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/i386/multiboot.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/i386/multiboot.c 2018-05-11 13:35:01.698267822 -0400 ++++ qemu-2.0.0+dfsg/hw/i386/multiboot.c 2018-05-11 13:35:01.694267814 -0400 +@@ -212,12 +212,6 @@ int load_multiboot(FWCfgState *fw_cfg, + 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); +@@ -228,8 +222,16 @@ int load_multiboot(FWCfgState *fw_cfg, + 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; ++ mb_load_size = kernel_file_size - mb_kernel_text_offset; ++ } ++ if (mh_bss_end_addr) { ++ if (mh_bss_end_addr < (mh_load_addr + mb_load_size)) { ++ fprintf(stderr, "invalid mh_bss_end_addr address\n"); ++ exit(1); ++ } ++ mb_kernel_size = mh_bss_end_addr - mh_load_addr; ++ } else { ++ mb_kernel_size = mb_load_size; + } + + /* Valid if mh_flags sets MULTIBOOT_HEADER_HAS_VBE. diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2019-6778.patch qemu-2.0.0+dfsg/debian/patches/CVE-2019-6778.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2019-6778.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2019-6778.patch 2019-03-22 21:08:33.000000000 +0000 @@ -0,0 +1,32 @@ +From a7104eda7dab99d0cdbd3595c211864cba415905 Mon Sep 17 00:00:00 2001 +From: Prasad J Pandit +Date: Sun, 13 Jan 2019 23:29:48 +0530 +Subject: [PATCH] slirp: check data length while emulating ident function + +While emulating identification protocol, tcp_emu() does not check +available space in the 'sc_rcv->sb_data' buffer. It could lead to +heap buffer overflow issue. Add check to avoid it. + +Reported-by: Kira <864786842@qq.com> +Signed-off-by: Prasad J Pandit +Signed-off-by: Samuel Thibault +--- + slirp/tcp_subr.c | 5 +++++ + 1 file changed, 5 insertions(+) + +Index: qemu-2.5+dfsg/slirp/tcp_subr.c +=================================================================== +--- qemu-2.5+dfsg.orig/slirp/tcp_subr.c 2019-03-22 14:18:51.187728005 -0400 ++++ qemu-2.5+dfsg/slirp/tcp_subr.c 2019-03-22 14:18:51.183727991 -0400 +@@ -581,6 +581,11 @@ tcp_emu(struct socket *so, struct mbuf * + socklen_t addrlen = sizeof(struct sockaddr_in); + struct sbuf *so_rcv = &so->so_rcv; + ++ if (m->m_len > so_rcv->sb_datalen ++ - (so_rcv->sb_wptr - so_rcv->sb_data)) { ++ return 1; ++ } ++ + memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); + so_rcv->sb_wptr += m->m_len; + so_rcv->sb_rptr += m->m_len; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2019-9824.patch qemu-2.0.0+dfsg/debian/patches/CVE-2019-9824.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/CVE-2019-9824.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/CVE-2019-9824.patch 2019-05-09 06:59:42.000000000 +0000 @@ -0,0 +1,49 @@ +From d3222975c7d6cda9e25809dea05241188457b113 Mon Sep 17 00:00:00 2001 +From: William Bowling +Date: Fri, 1 Mar 2019 21:45:56 +0000 +Subject: [PATCH] slirp: check sscanf result when emulating ident +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When emulating ident in tcp_emu, if the strchr checks passed but the +sscanf check failed, two uninitialized variables would be copied and +sent in the reply, so move this code inside the if(sscanf()) clause. + +Signed-off-by: William Bowling +Cc: qemu-stable@nongnu.org +Cc: secalert@redhat.com +Message-Id: <1551476756-25749-1-git-send-email-will@wbowling.info> +Signed-off-by: Samuel Thibault +Reviewed-by: Philippe Mathieu-Daudé + +CVE-2019-9824 +--- + slirp/tcp_subr.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c +index 262a42d6c8..ef9d99c154 100644 +--- a/slirp/tcp_subr.c ++++ b/slirp/tcp_subr.c +@@ -664,12 +664,12 @@ tcp_emu(struct socket *so, struct mbuf *m) + break; + } + } ++ so_rcv->sb_cc = snprintf(so_rcv->sb_data, ++ so_rcv->sb_datalen, ++ "%d,%d\r\n", n1, n2); ++ so_rcv->sb_rptr = so_rcv->sb_data; ++ so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; + } +- so_rcv->sb_cc = snprintf(so_rcv->sb_data, +- so_rcv->sb_datalen, +- "%d,%d\r\n", n1, n2); +- so_rcv->sb_rptr = so_rcv->sb_data; +- so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; + } + m_free(m); + return 0; +-- +2.17.1 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/define-trusty-machine-type.patch qemu-2.0.0+dfsg/debian/patches/define-trusty-machine-type.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/define-trusty-machine-type.patch 2014-04-08 16:48:24.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/define-trusty-machine-type.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,38 +0,0 @@ -Index: qemu-2.0.0~rc1+dfsg/hw/i386/pc_piix.c -=================================================================== ---- qemu-2.0.0~rc1+dfsg.orig/hw/i386/pc_piix.c 2014-04-03 13:56:23.000000000 -0500 -+++ qemu-2.0.0~rc1+dfsg/hw/i386/pc_piix.c 2014-04-08 11:48:23.533221934 -0500 -@@ -390,9 +390,7 @@ static void pc_xen_hvm_init(QEMUMachineI - static QEMUMachine pc_i440fx_machine_v2_0 = { - PC_I440FX_2_0_MACHINE_OPTIONS, - .name = "pc-i440fx-2.0", -- .alias = "pc", - .init = pc_init_pci, -- .is_default = 1, - }; - - #define PC_I440FX_1_7_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS -@@ -839,3 +837,23 @@ static void pc_machine_init(void) - } - - machine_init(pc_machine_init); -+ -+/* Ubuntu machine types */ -+ -+static QEMUMachine pc_machine_trusty = { -+ PC_DEFAULT_MACHINE_OPTIONS, -+ .default_machine_opts = "firmware=bios-256k.bin", -+ .hot_add_cpu = pc_hot_add_cpu, -+ .name = "pc-i440fx-trusty", -+ .alias = "pc", -+ .desc = "Ubuntu 14.04 PC (i440FX + PIIX, 1996)", -+ .init = pc_init_pci, -+ .is_default = 1, -+}; -+ -+static void ubuntu_machine_init(void) -+{ -+ qemu_register_machine(&pc_machine_trusty); -+} -+ -+machine_init(ubuntu_machine_init); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/doc-grammify-allows-to.patch qemu-2.0.0+dfsg/debian/patches/doc-grammify-allows-to.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/doc-grammify-allows-to.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/doc-grammify-allows-to.patch 2014-04-17 16:11:21.000000000 +0000 @@ -0,0 +1,72 @@ +From 923a6cce9aa6c0b6a2f562e1414a759dd1cd7caf Mon Sep 17 00:00:00 2001 +From: Michael Tokarev +Date: Mon, 7 Apr 2014 13:34:58 +0400 +Subject: [PATCH] doc: grammify "allows to" + +English language grammar does not allow usage +of the word "allows" directly followed by an +infinitive, declaring constructs like "something +allows to do somestuff" un-grammatical. Often +it is possible to just insert "one" between "allows" +and "to" to make the construct grammatical, but +usually it is better to re-phrase the statement. + +This patch tries to fix 4 examples of "allows to" +usage in qemu doc, but does not address comments +in the code with similar constructs. It also adds +missing "the" in the same line. + +Signed-off-by: Michael Tokarev +--- + qemu-doc.texi | 2 +- + qemu-options.hx | 7 ++++--- + 2 files changed, 5 insertions(+), 4 deletions(-) + +diff --git a/qemu-doc.texi b/qemu-doc.texi +index e6e20eb..88ec9bb 100644 +--- a/qemu-doc.texi ++++ b/qemu-doc.texi +@@ -823,7 +823,7 @@ In this case, the block device must be exported using qemu-nbd: + qemu-nbd --socket=/tmp/my_socket my_disk.qcow2 + @end example + +-The use of qemu-nbd allows to share a disk between several guests: ++The use of qemu-nbd allows sharing of a disk between several guests: + @example + qemu-nbd --socket=/tmp/my_socket --share=2 my_disk.qcow2 + @end example +diff --git a/qemu-options.hx b/qemu-options.hx +index 2d33815..6457034 100644 +--- a/qemu-options.hx ++++ b/qemu-options.hx +@@ -444,7 +444,8 @@ This option defines the type of the media: disk or cdrom. + @item cyls=@var{c},heads=@var{h},secs=@var{s}[,trans=@var{t}] + These options have the same definition as they have in @option{-hdachs}. + @item snapshot=@var{snapshot} +-@var{snapshot} is "on" or "off" and allows to enable snapshot for given drive (see @option{-snapshot}). ++@var{snapshot} is "on" or "off" and controls snapshot mode for the given drive ++(see @option{-snapshot}). + @item cache=@var{cache} + @var{cache} is "none", "writeback", "unsafe", "directsync" or "writethrough" and controls how the host cache is used to access block data. + @item aio=@var{aio} +@@ -1242,7 +1243,7 @@ Disable adaptive encodings. Adaptive encodings are enabled by default. + An adaptive encoding will try to detect frequently updated screen regions, + and send updates in these regions using a lossy encoding (like JPEG). + This can be really helpful to save bandwidth when playing videos. Disabling +-adaptive encodings allows to restore the original static behavior of encodings ++adaptive encodings restores the original static behavior of encodings + like Tight. + + @item share=[allow-exclusive|force-shared|ignore] +@@ -2805,7 +2806,7 @@ UTC or local time, respectively. @code{localtime} is required for correct date i + MS-DOS or Windows. To start at a specific point in time, provide @var{date} in the + format @code{2006-06-17T16:01:21} or @code{2006-06-17}. The default base is UTC. + +-By default the RTC is driven by the host system time. This allows to use the ++By default the RTC is driven by the host system time. This allows using of the + RTC as accurate reference clock inside the guest, specifically if the host + time is smoothly following an accurate external reference clock, e.g. via NTP. + If you want to isolate the guest time from the host, you can set @option{clock} +-- +1.7.10.4 + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/enable-md-clear.patch qemu-2.0.0+dfsg/debian/patches/enable-md-clear.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/enable-md-clear.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/enable-md-clear.patch 2019-04-29 22:44:32.000000000 +0000 @@ -0,0 +1,46 @@ +>From a57fa50701c6a0fbe5ac7dbcc314c3c970bff899 Mon Sep 17 00:00:00 2001 +From: Paolo Bonzini +Date: Fri, 1 Mar 2019 21:40:52 +0100 +Subject: [qemu PATCH] target/i386: define md-clear bit + +md-clear is a new CPUID bit which is set when microcode provides the +mechanism to invoke a flush of various exploitable CPU buffers by invoking +the VERW instruction. Add the new feature, and pass it down to +Hypervisor.framework guests. + +Signed-off-by: Paolo Bonzini + +[Backported to qemu 2.5 -- sbeattie] +--- + The last hunk is only needed for OS X, but anyway this is going + to be the patch that will be committed upstream. + + target-i386/cpu.c | 2 +- + target-i386/cpu.h | 1 + + 3 files changed, 4 insertions(+), 2 deletions(-) + +Index: b/target/i386/cpu.c +=================================================================== +--- a/target-i386/cpu.c ++++ b/target-i386/cpu.c +@@ -505,7 +505,7 @@ static FeatureWordInfo feature_word_info + + 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, "md-clear", NULL, NULL, NULL, NULL, NULL, + NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, + NULL, NULL, "spec-ctrl", NULL, NULL, NULL, NULL, "ssbd", + }; +Index: b/target/i386/cpu.h +=================================================================== +--- a/target-i386/cpu.h ++++ b/target-i386/cpu.h +@@ -684,6 +684,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_MD_CLEAR (1U << 10) /* Microarchitectural Data Clear */ + #define CPUID_7_0_EDX_SPEC_CTRL (1U << 26) /* Speculation Control */ + #define CPUID_7_0_EDX_SPEC_CTRL_SSBD (1U << 31) /* Speculative Store Bypass Disable */ + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/exec-limit-translation-limiting-in-address_space_translate-to-xen.diff qemu-2.0.0+dfsg/debian/patches/exec-limit-translation-limiting-in-address_space_translate-to-xen.diff --- qemu-2.0.0~rc1+dfsg/debian/patches/exec-limit-translation-limiting-in-address_space_translate-to-xen.diff 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/exec-limit-translation-limiting-in-address_space_translate-to-xen.diff 2014-04-17 13:30:59.000000000 +0000 @@ -0,0 +1,43 @@ +From: Alexey Kardashevskiy +Subject: [PATCH] exec: Limit translation limiting in address_space_translate to xen +Date: Thu, 27 Mar 2014 15:35:26 +1100 +Message-ID: <1395894926-16633-1-git-send-email-aik@ozlabs.ru> +Cc: Alexey Kardashevskiy , Paolo Bonzini +To: qemu-devel@nongnu.org +Comment: fixes windows boot BSOD with virtio-scsi (in 1.7.1 and 2.0) + +The address_space_translate() function cuts the returned plen (page size) +to hardcoded TARGET_PAGE_SIZE. This function can be used on pages bigger +than that so this limiting should not be used on such pages. + +Since originally the limiting was introduced for XEN, we can safely +limit this piece of code to XEN. So does the patch. + +Suggested-by: Paolo Bonzini +Signed-off-by: Alexey Kardashevskiy +--- + +I need this change for VFIO-on-sPAPR series as it is going to support +16MB IOMMU pages. Thanks. +--- + exec.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/exec.c b/exec.c +index 91513c6..cf12049 100644 +--- a/exec.c ++++ b/exec.c +@@ -380,7 +380,7 @@ MemoryRegion *address_space_translate(AddressSpace *as, hwaddr addr, + as = iotlb.target_as; + } + +- if (memory_access_is_direct(mr, is_write)) { ++ if (xen_enabled() && memory_access_is_direct(mr, is_write)) { + hwaddr page = ((addr & TARGET_PAGE_MASK) + TARGET_PAGE_SIZE) - addr; + len = MIN(page, len); + } +-- +1.8.4.rc4 + + + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/kvm-fix-memory-slot-page-alignment-logic.patch qemu-2.0.0+dfsg/debian/patches/kvm-fix-memory-slot-page-alignment-logic.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/kvm-fix-memory-slot-page-alignment-logic.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/kvm-fix-memory-slot-page-alignment-logic.patch 2016-09-15 14:50:46.000000000 +0000 @@ -0,0 +1,41 @@ +From: Alexander Graf +Date: Fri, 7 Nov 2014 21:12:48 +0000 (+0100) +Subject: kvm: Fix memory slot page alignment logic +X-Git-Tag: v2.2.0-rc3~8^2~1 +X-Git-Url: http://git.qemu.org/?p=qemu.git;a=commitdiff_plain;h=f2a64032a14c642d0ddc9a7a846fc3d737deede5 + +kvm: Fix memory slot page alignment logic + +Memory slots have to be page aligned to get entered into KVM. There +is existing logic that tries to ensure that we pad memory slots that +are not page aligned to the biggest region that would still fit in the +alignment requirements. + +Unfortunately, that logic is broken. It tries to calculate the start +offset based on the region size. + +Fix up the logic to do the thing it was intended to do and document it +properly in the comment above it. + +With this patch applied, I can successfully run an e500 guest with more +than 3GB RAM (at which point RAM starts overlapping subpage memory regions). + +Cc: qemu-stable@nongnu.org +Signed-off-by: Alexander Graf +--- + +--- a/kvm-all.c ++++ b/kvm-all.c +@@ -625,8 +625,10 @@ + unsigned delta; + + /* kvm works in page size chunks, but the function may be called +- with sub-page size and unaligned start address. */ +- delta = TARGET_PAGE_ALIGN(size) - size; ++ with sub-page size and unaligned start address. Pad the start ++ address to next and truncate size to previous page boundary. */ ++ delta = (TARGET_PAGE_SIZE - (start_addr & ~TARGET_PAGE_MASK)); ++ delta &= ~TARGET_PAGE_MASK; + if (delta > size) { + return; + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/lp1581936.patch qemu-2.0.0+dfsg/debian/patches/lp1581936.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/lp1581936.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/lp1581936.patch 2017-05-10 19:50:07.000000000 +0000 @@ -0,0 +1,235 @@ +Backport of: + +From 94ef4f337fb614f18b765a8e0e878a4c23cdedcd Mon Sep 17 00:00:00 2001 +From: Gerd Hoffmann +Date: Tue, 17 May 2016 10:54:54 +0200 +Subject: [PATCH] vga: add sr_vbe register set + +Commit "fd3c136 vga: make sure vga register setup for vbe stays intact +(CVE-2016-3712)." causes a regression. The win7 installer is unhappy +because it can't freely modify vga registers any more while in vbe mode. + +This patch introduces a new sr_vbe register set. The vbe_update_vgaregs +will fill sr_vbe[] instead of sr[]. Normal vga register reads and +writes go to sr[]. Any sr register read access happens through a new +sr() helper function which will read from sr_vbe[] with vbe active and +from sr[] otherwise. + +This way we can allow guests update sr[] registers as they want, without +allowing them disrupt vbe video modes that way. + +Cc: qemu-stable@nongnu.org +Reported-by: Thomas Lamprecht +Signed-off-by: Gerd Hoffmann +Message-id: 1463475294-14119-1-git-send-email-kraxel@redhat.com +--- + hw/display/vga.c | 50 ++++++++++++++++++++++++++++---------------------- + hw/display/vga_int.h | 1 + + 2 files changed, 29 insertions(+), 22 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/display/vga.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/display/vga.c 2017-05-10 15:48:52.466408763 -0400 ++++ qemu-2.0.0+dfsg/hw/display/vga.c 2017-05-10 15:49:51.418971568 -0400 +@@ -173,6 +173,11 @@ static inline bool vbe_enabled(VGACommon + return s->vbe_regs[VBE_DISPI_INDEX_ENABLE] & VBE_DISPI_ENABLED; + } + ++static inline uint8_t sr(VGACommonState *s, int idx) ++{ ++ return vbe_enabled(s) ? s->sr_vbe[idx] : s->sr[idx]; ++} ++ + static void vga_update_memory_access(VGACommonState *s) + { + MemoryRegion *region, *old_region = s->chain4_alias; +@@ -180,8 +185,8 @@ static void vga_update_memory_access(VGA + + s->chain4_alias = NULL; + +- if ((s->sr[VGA_SEQ_PLANE_WRITE] & VGA_SR02_ALL_PLANES) == +- VGA_SR02_ALL_PLANES && s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) { ++ if ((sr(s, VGA_SEQ_PLANE_WRITE) & VGA_SR02_ALL_PLANES) == ++ VGA_SR02_ALL_PLANES && sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) { + offset = 0; + switch ((s->gr[VGA_GFX_MISC] >> 2) & 3) { + case 0: +@@ -259,7 +264,7 @@ static void vga_precise_update_retrace_i + ((s->cr[VGA_CRTC_OVERFLOW] >> 6) & 2)) << 8); + vretr_end_line = s->cr[VGA_CRTC_V_SYNC_END] & 0xf; + +- clocking_mode = (s->sr[VGA_SEQ_CLOCK_MODE] >> 3) & 1; ++ clocking_mode = (sr(s, VGA_SEQ_CLOCK_MODE) >> 3) & 1; + clock_sel = (s->msr >> 2) & 3; + dots = (s->msr & 1) ? 8 : 9; + +@@ -511,7 +516,6 @@ void vga_ioport_write(void *opaque, uint + printf("vga: write SR%x = 0x%02x\n", s->sr_index, val); + #endif + s->sr[s->sr_index] = val & sr_mask[s->sr_index]; +- vbe_update_vgaregs(s); + if (s->sr_index == VGA_SEQ_CLOCK_MODE) { + s->update_retrace_info(s); + } +@@ -705,13 +709,13 @@ static void vbe_update_vgaregs(VGACommon + + if (s->vbe_regs[VBE_DISPI_INDEX_BPP] == 4) { + shift_control = 0; +- s->sr[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */ ++ s->sr_vbe[VGA_SEQ_CLOCK_MODE] &= ~8; /* no double line */ + } else { + shift_control = 2; + /* set chain 4 mode */ +- s->sr[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M; ++ s->sr_vbe[VGA_SEQ_MEMORY_MODE] |= VGA_SR04_CHN_4M; + /* activate all planes */ +- s->sr[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES; ++ s->sr_vbe[VGA_SEQ_PLANE_WRITE] |= VGA_SR02_ALL_PLANES; + } + s->gr[VGA_GFX_MODE] = (s->gr[VGA_GFX_MODE] & ~0x60) | + (shift_control << 5); +@@ -862,7 +866,7 @@ uint32_t vga_mem_readb(VGACommonState *s + break; + } + +- if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) { ++ if (sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) { + /* chain 4 mode : simplest access */ + assert(addr < s->vram_size); + ret = s->vram_ptr[addr]; +@@ -930,11 +934,11 @@ void vga_mem_writeb(VGACommonState *s, h + break; + } + +- if (s->sr[VGA_SEQ_MEMORY_MODE] & VGA_SR04_CHN_4M) { ++ if (sr(s, VGA_SEQ_MEMORY_MODE) & VGA_SR04_CHN_4M) { + /* chain 4 mode : simplest access */ + plane = addr & 3; + mask = (1 << plane); +- if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) { ++ if (sr(s, VGA_SEQ_PLANE_WRITE) & mask) { + assert(addr < s->vram_size); + s->vram_ptr[addr] = val; + #ifdef DEBUG_VGA_MEM +@@ -947,7 +951,7 @@ void vga_mem_writeb(VGACommonState *s, h + /* odd/even mode (aka text mode mapping) */ + plane = (s->gr[VGA_GFX_PLANE_READ] & 2) | (addr & 1); + mask = (1 << plane); +- if (s->sr[VGA_SEQ_PLANE_WRITE] & mask) { ++ if (sr(s, VGA_SEQ_PLANE_WRITE) & mask) { + addr = ((addr & ~1) << 1) | plane; + if (addr >= s->vram_size) { + return; +@@ -1022,7 +1026,7 @@ void vga_mem_writeb(VGACommonState *s, h + + do_write: + /* mask data according to sr[2] */ +- mask = s->sr[VGA_SEQ_PLANE_WRITE]; ++ mask = sr(s, VGA_SEQ_PLANE_WRITE); + s->plane_updated |= mask; /* only used to detect font change */ + write_mask = mask16[mask]; + if (addr * sizeof(uint32_t) >= s->vram_size) { +@@ -1313,10 +1317,10 @@ static void vga_get_text_resolution(VGAC + /* total width & height */ + cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1; + cwidth = 8; +- if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) { ++ if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) { + cwidth = 9; + } +- if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) { ++ if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) { + cwidth = 16; /* NOTE: no 18 pixel wide */ + } + width = (s->cr[VGA_CRTC_H_DISP] + 1); +@@ -1372,7 +1376,7 @@ static void vga_draw_text(VGACommonState + int64_t now = qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL); + + /* compute font data address (in plane 2) */ +- v = s->sr[VGA_SEQ_CHARACTER_MAP]; ++ v = sr(s, VGA_SEQ_CHARACTER_MAP); + offset = (((v >> 4) & 1) | ((v << 1) & 6)) * 8192 * 4 + 2; + if (offset != s->font_offsets[0]) { + s->font_offsets[0] = offset; +@@ -1743,11 +1747,11 @@ static void vga_draw_graphic(VGACommonSt + } + + if (shift_control == 0) { +- if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) { ++ if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) { + disp_width <<= 1; + } + } else if (shift_control == 1) { +- if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) { ++ if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) { + disp_width <<= 1; + } + } +@@ -1787,7 +1791,7 @@ static void vga_draw_graphic(VGACommonSt + + if (shift_control == 0) { + full_update |= update_palette16(s); +- if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) { ++ if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) { + v = VGA_DRAW_LINE4D2; + } else { + v = VGA_DRAW_LINE4; +@@ -1795,7 +1799,7 @@ static void vga_draw_graphic(VGACommonSt + bits = 4; + } else if (shift_control == 1) { + full_update |= update_palette16(s); +- if (s->sr[VGA_SEQ_CLOCK_MODE] & 8) { ++ if (sr(s, VGA_SEQ_CLOCK_MODE) & 8) { + v = VGA_DRAW_LINE2D2; + } else { + v = VGA_DRAW_LINE2; +@@ -1843,7 +1847,7 @@ static void vga_draw_graphic(VGACommonSt + #if 0 + printf("w=%d h=%d v=%d line_offset=%d cr[0x09]=0x%02x cr[0x17]=0x%02x linecmp=%d sr[0x01]=0x%02x\n", + width, height, v, line_offset, s->cr[9], s->cr[VGA_CRTC_MODE], +- s->line_compare, s->sr[VGA_SEQ_CLOCK_MODE]); ++ s->line_compare, sr(s, VGA_SEQ_CLOCK_MODE)); + #endif + addr1 = (s->start_addr * 4); + bwidth = (width * bits + 7) / 8; +@@ -2002,6 +2006,7 @@ void vga_common_reset(VGACommonState *s) + { + s->sr_index = 0; + memset(s->sr, '\0', sizeof(s->sr)); ++ memset(s->sr_vbe, '\0', sizeof(s->sr_vbe)); + s->gr_index = 0; + memset(s->gr, '\0', sizeof(s->gr)); + s->ar_index = 0; +@@ -2103,10 +2108,10 @@ static void vga_update_text(void *opaque + /* total width & height */ + cheight = (s->cr[VGA_CRTC_MAX_SCAN] & 0x1f) + 1; + cw = 8; +- if (!(s->sr[VGA_SEQ_CLOCK_MODE] & VGA_SR01_CHAR_CLK_8DOTS)) { ++ if (!(sr(s, VGA_SEQ_CLOCK_MODE) & VGA_SR01_CHAR_CLK_8DOTS)) { + cw = 9; + } +- if (s->sr[VGA_SEQ_CLOCK_MODE] & 0x08) { ++ if (sr(s, VGA_SEQ_CLOCK_MODE) & 0x08) { + cw = 16; /* NOTE: no 18 pixel wide */ + } + width = (s->cr[VGA_CRTC_H_DISP] + 1); +@@ -2272,6 +2277,7 @@ static int vga_common_post_load(void *op + + /* force refresh */ + s->graphic_mode = -1; ++ vbe_update_vgaregs(s); + return 0; + } + +Index: qemu-2.0.0+dfsg/hw/display/vga_int.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/display/vga_int.h 2017-05-10 15:48:52.466408763 -0400 ++++ qemu-2.0.0+dfsg/hw/display/vga_int.h 2017-05-10 15:48:52.462408725 -0400 +@@ -98,6 +98,7 @@ typedef struct VGACommonState { + MemoryRegion *chain4_alias; + uint8_t sr_index; + uint8_t sr[256]; ++ uint8_t sr_vbe[256]; + uint8_t gr_index; + uint8_t gr[256]; + uint8_t ar_index; diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/move-ncalrpc-dir-to-tmp.patch qemu-2.0.0+dfsg/debian/patches/move-ncalrpc-dir-to-tmp.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/move-ncalrpc-dir-to-tmp.patch 2014-03-27 17:56:07.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/move-ncalrpc-dir-to-tmp.patch 2014-04-14 09:26:57.000000000 +0000 @@ -18,10 +18,10 @@ --- -Index: qemu-2.0~git-20140327.3768d50/net/slirp.c +Index: qemu-1.6.0+dfsg/net/slirp.c =================================================================== ---- qemu-2.0~git-20140327.3768d50.orig/net/slirp.c 2014-03-27 12:55:45.514902971 -0500 -+++ qemu-2.0~git-20140327.3768d50/net/slirp.c 2014-03-27 12:55:45.506902971 -0500 +--- qemu-1.6.0+dfsg.orig/net/slirp.c ++++ qemu-1.6.0+dfsg/net/slirp.c @@ -527,6 +527,7 @@ static int slirp_smb(SlirpState* s, cons "pid directory=%s\n" "lock directory=%s\n" diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/qemu-nbd-fix-vdi-corruption.patch qemu-2.0.0+dfsg/debian/patches/qemu-nbd-fix-vdi-corruption.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/qemu-nbd-fix-vdi-corruption.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/qemu-nbd-fix-vdi-corruption.patch 2015-08-27 13:27:39.000000000 +0000 @@ -0,0 +1,86 @@ +From f0ab6f109630940146cbaf47d0cd99993ddba824 Mon Sep 17 00:00:00 2001 +From: Max Reitz +Date: Fri, 27 Feb 2015 14:54:39 -0500 +Subject: [PATCH 1/1] block/vdi: Add locking for parallel requests +Origin: backport, http://git.qemu.org/?p=qemu.git;a=commit;h=f0ab6f109630940146cbaf47d0cd99993ddba824 +Bug: https://bugs.launchpad.net/qemu/+bug/1422307 + +When allocating a new cluster, the first write to it must be the one +doing the allocation, because that one pads its write request to the +cluster size; if another write to that cluster is executed before it, +that write will be overwritten due to the padding. + +See https://bugs.launchpad.net/qemu/+bug/1422307 for what can go wrong +without this patch. + +Cc: qemu-stable +Signed-off-by: Max Reitz +Reviewed-by: Stefan Hajnoczi +Reviewed-by: Paolo Bonzini +Signed-off-by: Kevin Wolf +--- + block/vdi.c | 25 +++++++++++++++++++++++++ + 1 files changed, 25 insertions(+), 0 deletions(-) + +Index: qemu-2.0.0+dfsg/block/vdi.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/block/vdi.c 2015-08-18 23:04:27.817046941 +0200 ++++ qemu-2.0.0+dfsg/block/vdi.c 2015-08-18 23:04:27.813046920 +0200 +@@ -53,6 +53,7 @@ + #include "block/block_int.h" + #include "qemu/module.h" + #include "migration/migration.h" ++#include "block/coroutine.h" + + #if defined(CONFIG_UUID) + #include +@@ -184,6 +185,8 @@ + /* VDI header (converted to host endianness). */ + VdiHeader header; + ++ CoMutex write_lock; ++ + Error *migration_blocker; + } BDRVVdiState; + +@@ -483,6 +486,8 @@ + "vdi", bs->device_name, "live migration"); + migrate_add_blocker(s->migration_blocker); + ++ qemu_co_mutex_init(&s->write_lock); ++ + return 0; + + fail_free_bmap: +@@ -618,11 +623,31 @@ + buf, n_sectors * SECTOR_SIZE); + memset(block + (sector_in_block + n_sectors) * SECTOR_SIZE, 0, + (s->block_sectors - n_sectors - sector_in_block) * SECTOR_SIZE); ++ ++ /* Note that this coroutine does not yield anywhere from reading the ++ * bmap entry until here, so in regards to all the coroutines trying ++ * to write to this cluster, the one doing the allocation will ++ * always be the first to try to acquire the lock. ++ * Therefore, it is also the first that will actually be able to ++ * acquire the lock and thus the padded cluster is written before ++ * the other coroutines can write to the affected area. */ ++ qemu_co_mutex_lock(&s->write_lock); + ret = bdrv_write(bs->file, offset, block, s->block_sectors); ++ qemu_co_mutex_unlock(&s->write_lock); + } else { + uint64_t offset = s->header.offset_data / SECTOR_SIZE + + (uint64_t)bmap_entry * s->block_sectors + + sector_in_block; ++ qemu_co_mutex_lock(&s->write_lock); ++ /* This lock is only used to make sure the following write operation ++ * is executed after the write issued by the coroutine allocating ++ * this cluster, therefore we do not need to keep it locked. ++ * As stated above, the allocating coroutine will always try to lock ++ * the mutex before all the other concurrent accesses to that ++ * cluster, therefore at this point we can be absolutely certain ++ * that that write operation has returned (there may be other writes ++ * in flight, but they do not concern this very operation). */ ++ qemu_co_mutex_unlock(&s->write_lock); + ret = bdrv_write(bs->file, offset, buf, n_sectors); + } + diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/retry-pxe-after-efi.patch qemu-2.0.0+dfsg/debian/patches/retry-pxe-after-efi.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/retry-pxe-after-efi.patch 2014-03-27 17:56:08.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/retry-pxe-after-efi.patch 2014-04-17 13:30:59.000000000 +0000 @@ -14,10 +14,8 @@ /mjt -Index: qemu-2.0~git-20140327.3768d50/vl.c -=================================================================== ---- qemu-2.0~git-20140327.3768d50.orig/vl.c 2014-03-27 12:55:45.438902973 -0500 -+++ qemu-2.0~git-20140327.3768d50/vl.c 2014-03-27 12:56:08.000000000 -0500 +--- a/vl.c ++++ b/vl.c @@ -2365,6 +2365,7 @@ char *qemu_find_file(int type, const cha abort(); } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/series qemu-2.0.0+dfsg/debian/patches/series --- qemu-2.0.0~rc1+dfsg/debian/patches/series 2014-04-09 03:28:32.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/series 2019-05-09 06:59:42.000000000 +0000 @@ -2,6 +2,283 @@ retry-pxe-after-efi.patch use-fixed-data-path.patch move-ncalrpc-dir-to-tmp.patch +doc-grammify-allows-to.patch +exec-limit-translation-limiting-in-address_space_translate-to-xen.diff ubuntu/expose-vmx_qemu64cpu.patch -define-trusty-machine-type.patch -ubuntu/kvm_physical_sync_dirty_bitmap-ignore-ENOENT-from-kv.patch +ubuntu/define-trusty-machine-type.patch +CVE-2013-4148.patch +CVE-2013-4149.patch +CVE-2013-4150.patch +CVE-2013-4151.patch +CVE-2013-4526.patch +CVE-2013-4527.patch +CVE-2013-4529.patch +CVE-2013-4530.patch +CVE-2013-4531.patch +CVE-2013-4532.patch +CVE-2013-4533.patch +CVE-2013-4534.patch +CVE-2013-4535_4536.patch +CVE-2013-4537.patch +CVE-2013-4538.patch +CVE-2013-4539.patch +CVE-2013-4540.patch +CVE-2013-4541.patch +CVE-2013-4542.patch +CVE-2013-6399.patch +CVE-2014-0182.patch +CVE-2014-0222.patch +CVE-2014-0223.patch +CVE-2014-3461.patch +CVE-2014-3471.patch +ubuntu/add-machine-type-pc-1.0-qemu-kvm-for-live-migrate-co.patch +CVE-2014-3615.patch +CVE-2014-3640.patch +CVE-2014-3689.patch +CVE-2014-5263.patch +CVE-2014-5388.patch +CVE-2014-7815.patch +501-block-raw-posix-fix-disk-corruption-in-try-fiemap +CVE-2014-7840.patch +CVE-2014-8106.patch +upstream-xen_disk-fix-unmapping-of-persistent-grants.patch +CVE-2015-1779-1.patch +CVE-2015-1779-2.patch +CVE-2015-2756.patch +CVE-2015-3456.patch +CVE-2015-3209-pre.patch +CVE-2015-3209.patch +CVE-2015-4037.patch +CVE-2015-4103.patch +CVE-2015-4104.patch +CVE-2015-4105.patch +CVE-2015-4106-1.patch +CVE-2015-4106-2.patch +CVE-2015-4106-3.patch +CVE-2015-4106-4.patch +CVE-2015-4106-5.patch +CVE-2015-4106-6.patch +CVE-2015-4106-7.patch +CVE-2015-4106-8.patch +ubuntu/add-machine-type-pc-i440fx-1.5-qemu-kvm-for-live-migrate.patch +CVE-2015-3214.patch +CVE-2015-5154.patch +CVE-2014-9718.patch +CVE-2015-5165.patch +CVE-2015-5745.patch +qemu-nbd-fix-vdi-corruption.patch +CVE-2015-5239.patch +CVE-2015-5278.patch +CVE-2015-5279.patch +CVE-2015-6815.patch +CVE-2015-6855.patch +upstream-fix-irq-route-entries.patch +CVE-2015-7295.patch +CVE-2015-7504.patch +CVE-2015-7512.patch +CVE-2015-8345.patch +CVE-2015-7549.patch +CVE-2015-8504.patch +CVE-2015-8550-1.patch +CVE-2015-8550-2.patch +CVE-2015-8558.patch +CVE-2015-856x.patch +CVE-2015-8613.patch +CVE-2015-8619.patch +CVE-2015-8666.patch +CVE-2015-8743.patch +CVE-2015-8744.patch +CVE-2015-8745.patch +CVE-2016-1568.patch +CVE-2016-1714.patch +CVE-2016-1922.patch +CVE-2016-1981.patch +CVE-2016-2198.patch +CVE-2016-2391.patch +CVE-2016-2392.patch +CVE-2016-2538.patch +CVE-2016-2841.patch +CVE-2016-2857.patch +CVE-2016-2858.patch +CVE-2016-3710.patch +CVE-2016-3712.patch +CVE-2016-4001.patch +CVE-2016-4002.patch +CVE-2016-4020.patch +CVE-2016-4037.patch +ubuntu/backport-fixtime.patch +CVE-2016-4439.patch +CVE-2016-4441.patch +CVE-2016-4454.patch +CVE-2016-4453.patch +CVE-2016-4952.patch +CVE-2016-5105.patch +CVE-2016-5106.patch +CVE-2016-5107.patch +CVE-2016-5126.patch +CVE-2016-5238.patch +CVE-2016-5337.patch +CVE-2016-5338.patch +CVE-2016-5403.patch +CVE-2016-6351.patch +kvm-fix-memory-slot-page-alignment-logic.patch +CVE-2016-5403-2.patch +CVE-2016-5403-3.patch +CVE-2016-5403-4.patch +CVE-2016-6833.patch +CVE-2016-6834.patch +CVE-2016-6835.patch +CVE-2016-6836.patch +CVE-2016-6888.patch +CVE-2016-7116-1.patch +CVE-2016-7116-2.patch +CVE-2016-7116-3.patch +CVE-2016-7116-4.patch +CVE-2016-7155.patch +CVE-2016-7156.patch +CVE-2016-7161.patch +CVE-2016-7170.patch +CVE-2016-7421.patch +CVE-2016-7908.patch +CVE-2016-7909.patch +CVE-2016-8576.patch +CVE-2016-8577.patch +CVE-2016-8578.patch +CVE-2016-8909.patch +CVE-2016-8910.patch +CVE-2016-9101.patch +CVE-2016-9103.patch +CVE-2016-9102.patch +CVE-2016-9104.patch +CVE-2016-9105.patch +CVE-2016-9106.patch +0001-aio-fix-qemu_bh_schedule-bh-ctx-race-condition.patch +0002-aio-strengthen-memory-barriers-for-bottom-half-sched.patch +atomics-add-explicit-compiler-fence-in-__atomic-memo.patch +CVE-2016-8667.patch +CVE-2016-8669.patch +CVE-2016-9381.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-9913.patch +CVE-2016-9914-1.patch +CVE-2016-9914-2.patch +CVE-2016-9915.patch +CVE-2016-9916.patch +CVE-2016-9603.patch +CVE-2016-9776.patch +CVE-2016-9907.patch +CVE-2016-9921-9922.patch +CVE-2016-10155.patch +CVE-2017-2620-pre.patch +CVE-2017-2620.patch +CVE-2017-5525.patch +CVE-2017-5526.patch +CVE-2017-5579.patch +CVE-2017-5667.patch +CVE-2017-5856.patch +CVE-2017-5898.patch +CVE-2017-5973.patch +CVE-2017-5987-1.patch +CVE-2017-5987-2.patch +CVE-2017-5987-3.patch +CVE-2017-5987-4.patch +CVE-2017-6505.patch +CVE-2016-9911.patch +CVE-2017-2615.patch +CVE-2016-5403-5.patch +CVE-2016-5403-6.patch +CVE-2017-2633.patch +CVE-2017-7377.patch +CVE-2017-7718.patch +CVE-2017-8086.patch +CVE-2017-8309.patch +CVE-2017-7980-1.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-7980-8.patch +CVE-2017-7980-9.patch +lp1581936.patch +CVE-2017-7493.patch +CVE-2017-8112.patch +CVE-2017-9330.patch +CVE-2017-9373-1.patch +CVE-2017-9373-2.patch +CVE-2017-9374.patch +CVE-2017-9375.patch +CVE-2017-9503-1.patch +CVE-2017-9503-pre1.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.patch +CVE-2017-10806.patch +CVE-2017-10911.patch +CVE-2017-11434.patch +CVE-2017-9375-regression.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-14167.patch +CVE-2017-15038.patch +CVE-2017-15289.patch +CVE-2017-18043.patch +CVE-2018-5683.patch +CVE-2018-7550.patch +CVE-2018-3639.patch +CVE-2018-3639-2.patch +CVE-2018-3639-3.patch +CVE-2018-10839.patch +CVE-2018-11806.patch +CVE-2018-12617.patch +CVE-2018-17958.patch +CVE-2018-17962.patch +CVE-2018-17963.patch +CVE-2018-18849.patch +CVE-2018-19364-1.patch +CVE-2018-19364-2.patch +CVE-2018-19489.patch +CVE-2019-6778.patch +enable-md-clear.patch +CVE-2018-20815-prereq-1.patch +CVE-2018-20815-prereq-2.patch +CVE-2018-20815.patch +CVE-2019-9824.patch diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/ubuntu/add-machine-type-pc-1.0-qemu-kvm-for-live-migrate-co.patch qemu-2.0.0+dfsg/debian/patches/ubuntu/add-machine-type-pc-1.0-qemu-kvm-for-live-migrate-co.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/ubuntu/add-machine-type-pc-1.0-qemu-kvm-for-live-migrate-co.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/ubuntu/add-machine-type-pc-1.0-qemu-kvm-for-live-migrate-co.patch 2016-10-10 07:05:09.000000000 +0000 @@ -0,0 +1,247 @@ +From 6dedc2c0566c651c695bb356c43382e1fcdc042e Mon Sep 17 00:00:00 2001 +From: Alex Bligh +Date: Tue, 22 Jul 2014 19:14:48 +0100 +Subject: [PATCH 1/2] Add machine type pc-1.0-qemu-kvm for live migrate + compatibility with qemu-kvm + +Add a machine type pc-1.0-qemu-kvm for live migrate compatibility +with qemu-kvm version 1.0. +Changelog: (Serge Hallyn) + * add pc-1.0-precise as an alias to pc-1.0-qemu-kvm + * PC_COMPAT_1_0_QEMU_KVM - specify the legacy pxe romfiles + +*Update* +It was found that the alias pc-1.0-qemu-kvm to pc-1.0 with the same string +as the new type for precise being pc-1.0-qemu-kvm can break live migration. +Therefore this duplicate alias has been dropped (LP: #1536331). + +Last-Update: 2016-10-10 +--- + hw/acpi/piix4.c | 49 ++++++++++++++++++++++++++++++++++++++++++++++-- + hw/i386/pc_piix.c | 31 ++++++++++++++++++++++++++++++ + hw/timer/i8254_common.c | 41 ++++++++++++++++++++++++++++++++++++++++ + include/hw/acpi/piix4.h | 1 + + include/hw/timer/i8254.h | 2 ++ + 5 files changed, 122 insertions(+), 2 deletions(-) + +--- a/hw/acpi/piix4.c ++++ b/hw/acpi/piix4.c +@@ -247,8 +247,9 @@ + } + + /* qemu-kvm 1.2 uses version 3 but advertised as 2 +- * To support incoming qemu-kvm 1.2 migration, change version_id +- * and minimum_version_id to 2 below (which breaks migration from ++ * To support incoming qemu-kvm 1.2 migration, we support ++ * via a command line option a change to minimum_version_id ++ * of 2 in a _compat structure (which breaks migration from + * qemu 1.2). + * + */ +@@ -280,6 +281,34 @@ + } + }; + ++static const VMStateDescription vmstate_acpi_compat = { ++ .name = "piix4_pm", ++ .version_id = 3, ++ .minimum_version_id = 2, ++ .minimum_version_id_old = 1, ++ .load_state_old = acpi_load_old, ++ .post_load = vmstate_acpi_post_load, ++ .fields = (VMStateField[]) { ++ VMSTATE_PCI_DEVICE(parent_obj, PIIX4PMState), ++ VMSTATE_UINT16(ar.pm1.evt.sts, PIIX4PMState), ++ VMSTATE_UINT16(ar.pm1.evt.en, PIIX4PMState), ++ VMSTATE_UINT16(ar.pm1.cnt.cnt, PIIX4PMState), ++ VMSTATE_STRUCT(apm, PIIX4PMState, 0, vmstate_apm, APMState), ++ VMSTATE_TIMER(ar.tmr.timer, PIIX4PMState), ++ VMSTATE_INT64(ar.tmr.overflow_time, PIIX4PMState), ++ VMSTATE_STRUCT(ar.gpe, PIIX4PMState, 2, vmstate_gpe, ACPIGPE), ++ VMSTATE_STRUCT_TEST( ++ acpi_pci_hotplug.acpi_pcihp_pci_status[ACPI_PCIHP_BSEL_DEFAULT], ++ PIIX4PMState, ++ vmstate_test_no_use_acpi_pci_hotplug, ++ 2, vmstate_pci_status, ++ struct AcpiPciHpPciStatus), ++ VMSTATE_PCI_HOTPLUG(acpi_pci_hotplug, PIIX4PMState, ++ vmstate_test_use_acpi_pci_hotplug), ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ + static void piix4_reset(void *opaque) + { + PIIX4PMState *s = opaque; +@@ -557,6 +586,22 @@ + hc->unplug = piix4_pci_device_unplug_cb; + } + ++void piix4_pm_class_fix_compat(void) ++{ ++ GSList *el, *devices = object_class_get_list(TYPE_DEVICE, false); ++ /* ++ * Change the vmstate field in this class and any derived classes ++ * if not overriden. As no other classes should be using this ++ * vmstate, we can simply iterate the class list ++ */ ++ for (el = devices; el; el = el->next) { ++ DeviceClass *dc = el->data; ++ if (dc->vmsd == &vmstate_acpi) { ++ dc->vmsd = &vmstate_acpi_compat; ++ } ++ } ++} ++ + static const TypeInfo piix4_pm_info = { + .name = TYPE_PIIX4_PM, + .parent = TYPE_PCI_DEVICE, +--- a/hw/i386/pc_piix.c ++++ b/hw/i386/pc_piix.c +@@ -48,6 +48,8 @@ + #include "exec/address-spaces.h" + #include "hw/acpi/acpi.h" + #include "cpu.h" ++#include "hw/acpi/piix4.h" ++#include "hw/timer/i8254.h" + #ifdef CONFIG_XEN + # include + #endif +@@ -340,6 +342,15 @@ + pc_init_pci(args); + } + ++/* PC machine init function for qemu-kvm 1.0 */ ++static void pc_init_pci_1_2_qemu_kvm(QEMUMachineInitArgs *args) ++{ ++ piix4_pm_class_fix_compat(); ++ pit_common_class_fix_compat(); ++ pc_compat_1_2(args); ++ pc_init_pci(args); ++} ++ + /* PC init function for pc-0.10 to pc-0.13, and reused by xenfv */ + static void pc_init_pci_no_kvmclock(QEMUMachineInitArgs *args) + { +@@ -583,6 +594,38 @@ + .hw_version = "1.0", + }; + ++#define PC_COMPAT_1_0_QEMU_KVM \ ++ PC_COMPAT_1_0,\ ++ {\ ++ .driver = "cirrus-vga",\ ++ .property = "vgamem_mb",\ ++ .value = stringify(16),\ ++ }, {\ ++ .driver = "virtio-net-pci", \ ++ .property = "romfile", \ ++ .value = "pxe-virtio.rom.12.04", \ ++ },{\ ++ .driver = "rtl8139",\ ++ .property = "romfile",\ ++ .value = "pxe-rtl8139.rom.12.04",\ ++ },{\ ++ .driver = "e1000",\ ++ .property = "romfile",\ ++ .value = "pxe-e1000.rom.12.04",\ ++ } ++ ++static QEMUMachine pc_machine_v1_0_qemu_kvm = { ++ PC_I440FX_1_2_MACHINE_OPTIONS, ++ .name = "pc-1.0-qemu-kvm", ++ .alias = "pc-1.0-precise", ++ .init = pc_init_pci_1_2_qemu_kvm, ++ .compat_props = (GlobalProperty[]) { ++ PC_COMPAT_1_0_QEMU_KVM, ++ { /* end of list */ } ++ }, ++ .hw_version = "1.0", ++}; ++ + #define PC_COMPAT_0_15 \ + PC_COMPAT_1_0 + +@@ -824,6 +867,7 @@ + qemu_register_machine(&pc_machine_v1_2); + qemu_register_machine(&pc_machine_v1_1); + qemu_register_machine(&pc_machine_v1_0); ++ qemu_register_machine(&pc_machine_v1_0_qemu_kvm); + qemu_register_machine(&pc_machine_v0_15); + qemu_register_machine(&pc_machine_v0_14); + qemu_register_machine(&pc_machine_v0_13); +--- a/hw/timer/i8254_common.c ++++ b/hw/timer/i8254_common.c +@@ -276,6 +276,29 @@ + } + }; + ++static const VMStateDescription vmstate_pit_common_compat = { ++ .name = "i8254", ++ .version_id = 3, ++ .minimum_version_id = 2, ++ .minimum_version_id_old = 1, ++ .load_state_old = pit_load_old, ++ .pre_save = pit_dispatch_pre_save, ++ .post_load = pit_dispatch_post_load, ++ .fields = (VMStateField[]) { ++ /* qemu-kvm version_id=2 had 'flags' here which is equivalent ++ * This fixes incoming migration from qemu-kvm 1.0, but breaks ++ * incoming migration from qemu < 1.1 ++ */ ++ /* VMSTATE_UINT32_V(channels[0].irq_disabled, PITCommonState, 3), */ ++ VMSTATE_UINT32(channels[0].irq_disabled, PITCommonState), ++ VMSTATE_STRUCT_ARRAY(channels, PITCommonState, 3, 2, ++ vmstate_pit_channel, PITChannelState), ++ VMSTATE_INT64(channels[0].next_transition_time, ++ PITCommonState), /* formerly irq_timer */ ++ VMSTATE_END_OF_LIST() ++ } ++}; ++ + static void pit_common_class_init(ObjectClass *klass, void *data) + { + DeviceClass *dc = DEVICE_CLASS(klass); +@@ -290,6 +313,24 @@ + dc->cannot_instantiate_with_device_add_yet = true; + } + ++void pit_common_class_fix_compat(void) ++{ ++ GSList *el, *devices = object_class_get_list(TYPE_DEVICE, false); ++ /* ++ * Change the vmstate field in this class and any derived classes ++ * if not overriden. As no other classes should be using this ++ * vmstate, we can simply iterate the class list ++ */ ++ for (el = devices; el; el = el->next) { ++ DeviceClass *dc = el->data; ++ if (dc->vmsd == &vmstate_pit_common) { ++ dc->vmsd = &vmstate_pit_common_compat; ++ } ++ } ++ ++ g_slist_free(devices); ++} ++ + static const TypeInfo pit_common_type = { + .name = TYPE_PIT_COMMON, + .parent = TYPE_ISA_DEVICE, +--- a/include/hw/acpi/piix4.h ++++ b/include/hw/acpi/piix4.h +@@ -4,5 +4,6 @@ + #include "qemu/typedefs.h" + + Object *piix4_pm_find(void); ++void piix4_pm_class_fix_compat(void); + + #endif +--- a/include/hw/timer/i8254.h ++++ b/include/hw/timer/i8254.h +@@ -72,4 +72,6 @@ + void pit_set_gate(ISADevice *dev, int channel, int val); + void pit_get_channel_info(ISADevice *dev, int channel, PITChannelInfo *info); + ++void pit_common_class_fix_compat(void); ++ + #endif /* !HW_I8254_H */ diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/ubuntu/add-machine-type-pc-i440fx-1.5-qemu-kvm-for-live-migrate.patch qemu-2.0.0+dfsg/debian/patches/ubuntu/add-machine-type-pc-i440fx-1.5-qemu-kvm-for-live-migrate.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/ubuntu/add-machine-type-pc-i440fx-1.5-qemu-kvm-for-live-migrate.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/ubuntu/add-machine-type-pc-i440fx-1.5-qemu-kvm-for-live-migrate.patch 2015-06-15 17:10:49.000000000 +0000 @@ -0,0 +1,57 @@ +--- a/hw/i386/pc_piix.c ++++ b/hw/i386/pc_piix.c +@@ -438,6 +438,46 @@ + }, + }; + ++/* PC machine init function for qemu-kvm 1.5 */ ++static void pc_init_pci_1_5_qemu_kvm(QEMUMachineInitArgs *args) ++{ ++ piix4_pm_class_fix_compat(); ++ pit_common_class_fix_compat(); ++ pc_compat_1_5(args); ++ pc_init_pci(args); ++} ++ ++#define PC_COMPAT_1_5_QEMU_KVM \ ++ PC_COMPAT_1_5,\ ++ {\ ++ .driver = "cirrus-vga",\ ++ .property = "vgamem_mb",\ ++ .value = stringify(8),\ ++ },{\ ++ .driver = "virtio-net-pci", \ ++ .property = "romfile", \ ++ .value = "pxe-virtio.rom", \ ++ },{\ ++ .driver = "rtl8139",\ ++ .property = "romfile",\ ++ .value = "pxe-rtl8139.rom",\ ++ },{\ ++ .driver = "e1000",\ ++ .property = "romfile",\ ++ .value = "pxe-e1000.rom",\ ++ } ++ ++static QEMUMachine pc_i440fx_machine_v1_5_qemu_kvm = { ++ PC_I440FX_1_6_MACHINE_OPTIONS, ++ .name = "pc-i440fx-1.5-qemu-kvm", ++ .alias = "pc-i440fx-1.5-saucy", ++ .init = pc_init_pci_1_5_qemu_kvm, ++ .compat_props = (GlobalProperty[]) { ++ PC_COMPAT_1_5_QEMU_KVM, ++ { /* end of list */ } ++ }, ++}; ++ + #define PC_I440FX_1_4_MACHINE_OPTIONS \ + PC_I440FX_1_6_MACHINE_OPTIONS, \ + .hot_add_cpu = NULL +@@ -863,6 +903,7 @@ + qemu_register_machine(&pc_i440fx_machine_v1_7); + qemu_register_machine(&pc_i440fx_machine_v1_6); + qemu_register_machine(&pc_i440fx_machine_v1_5); ++ qemu_register_machine(&pc_i440fx_machine_v1_5_qemu_kvm); + qemu_register_machine(&pc_i440fx_machine_v1_4); + qemu_register_machine(&pc_machine_v1_3); + qemu_register_machine(&pc_machine_v1_2); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/ubuntu/backport-fixtime.patch qemu-2.0.0+dfsg/debian/patches/ubuntu/backport-fixtime.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/ubuntu/backport-fixtime.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/ubuntu/backport-fixtime.patch 2016-07-01 08:26:41.000000000 +0000 @@ -0,0 +1,178 @@ +Index: qemu-2.0.0+dfsg/cpus.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/cpus.c ++++ qemu-2.0.0+dfsg/cpus.c +@@ -522,6 +522,15 @@ void cpu_synchronize_all_post_init(void) + } + } + ++void cpu_clean_all_dirty(void) ++{ ++ CPUState *cpu; ++ ++ CPU_FOREACH(cpu) { ++ cpu_clean_state(cpu); ++ } ++} ++ + static int do_vm_stop(RunState state) + { + int ret = 0; +Index: qemu-2.0.0+dfsg/include/sysemu/cpus.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/include/sysemu/cpus.h ++++ qemu-2.0.0+dfsg/include/sysemu/cpus.h +@@ -10,6 +10,7 @@ void cpu_stop_current(void); + void cpu_synchronize_all_states(void); + void cpu_synchronize_all_post_reset(void); + void cpu_synchronize_all_post_init(void); ++void cpu_clean_all_dirty(void); + + void qtest_clock_warp(int64_t dest); + +Index: qemu-2.0.0+dfsg/include/sysemu/kvm.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/include/sysemu/kvm.h ++++ qemu-2.0.0+dfsg/include/sysemu/kvm.h +@@ -307,6 +307,7 @@ int kvm_physical_memory_addr_from_host(K + void kvm_cpu_synchronize_state(CPUState *cpu); + void kvm_cpu_synchronize_post_reset(CPUState *cpu); + void kvm_cpu_synchronize_post_init(CPUState *cpu); ++void kvm_cpu_clean_state(CPUState *cpu); + + /* generic hooks - to be moved/refactored once there are more users */ + +@@ -331,6 +332,13 @@ static inline void cpu_synchronize_post_ + } + } + ++static inline void cpu_clean_state(CPUState *cpu) ++{ ++ if (kvm_enabled()) { ++ kvm_cpu_clean_state(cpu); ++ } ++} ++ + int kvm_irqchip_add_msi_route(KVMState *s, MSIMessage msg); + int kvm_irqchip_update_msi_route(KVMState *s, int virq, MSIMessage msg); + void kvm_irqchip_release_virq(KVMState *s, int virq); +Index: qemu-2.0.0+dfsg/kvm-all.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/kvm-all.c ++++ qemu-2.0.0+dfsg/kvm-all.c +@@ -1645,6 +1645,11 @@ void kvm_cpu_synchronize_post_init(CPUSt + cpu->kvm_vcpu_dirty = false; + } + ++void kvm_cpu_clean_state(CPUState *cpu) ++{ ++ cpu->kvm_vcpu_dirty = false; ++} ++ + int kvm_cpu_exec(CPUState *cpu) + { + struct kvm_run *run = cpu->kvm_run; +Index: qemu-2.0.0+dfsg/hw/i386/kvm/clock.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/i386/kvm/clock.c ++++ qemu-2.0.0+dfsg/hw/i386/kvm/clock.c +@@ -14,8 +14,10 @@ + */ + + #include "qemu-common.h" ++#include "qemu/host-utils.h" + #include "sysemu/sysemu.h" + #include "sysemu/kvm.h" ++#include "sysemu/cpus.h" + #include "hw/sysbus.h" + #include "hw/kvm/clock.h" + +@@ -34,6 +36,48 @@ typedef struct KVMClockState { + bool clock_valid; + } KVMClockState; + ++struct pvclock_vcpu_time_info { ++ uint32_t version; ++ uint32_t pad0; ++ uint64_t tsc_timestamp; ++ uint64_t system_time; ++ uint32_t tsc_to_system_mul; ++ int8_t tsc_shift; ++ uint8_t flags; ++ uint8_t pad[2]; ++} __attribute__((__packed__)); /* 32 bytes */ ++ ++static uint64_t kvmclock_current_nsec(KVMClockState *s) ++{ ++ CPUState *cpu = first_cpu; ++ CPUX86State *env = cpu->env_ptr; ++ hwaddr kvmclock_struct_pa = env->system_time_msr & ~1ULL; ++ uint64_t migration_tsc = env->tsc; ++ struct pvclock_vcpu_time_info time; ++ uint64_t delta; ++ uint64_t nsec_lo; ++ uint64_t nsec_hi; ++ uint64_t nsec; ++ ++ if (!(env->system_time_msr & 1ULL)) { ++ /* KVM clock not active */ ++ return 0; ++ } ++ ++ cpu_physical_memory_read(kvmclock_struct_pa, &time, sizeof(time)); ++ ++ assert(time.tsc_timestamp <= migration_tsc); ++ delta = migration_tsc - time.tsc_timestamp; ++ if (time.tsc_shift < 0) { ++ delta >>= -time.tsc_shift; ++ } else { ++ delta <<= time.tsc_shift; ++ } ++ ++ mulu64(&nsec_lo, &nsec_hi, delta, time.tsc_to_system_mul); ++ nsec = (nsec_lo >> 32) | (nsec_hi << 32); ++ return nsec + time.system_time; ++} + + static void kvmclock_vm_state_change(void *opaque, int running, + RunState state) +@@ -45,9 +89,15 @@ static void kvmclock_vm_state_change(voi + + if (running) { + struct kvm_clock_data data; ++ uint64_t time_at_migration = kvmclock_current_nsec(s); + + s->clock_valid = false; + ++ /* We can't rely on the migrated clock value, just discard it */ ++ if (time_at_migration) { ++ s->clock = time_at_migration; ++ } ++ + data.clock = s->clock; + data.flags = 0; + ret = kvm_vm_ioctl(kvm_state, KVM_SET_CLOCK, &data); +@@ -75,6 +125,23 @@ static void kvmclock_vm_state_change(voi + if (s->clock_valid) { + return; + } ++ ++ cpu_synchronize_all_states(); ++ /* In theory, the cpu_synchronize_all_states() call above wouldn't ++ * affect the rest of the code, as the VCPU state inside CPUState ++ * is supposed to always match the VCPU state on the kernel side. ++ * ++ * In practice, calling cpu_synchronize_state() too soon will load the ++ * kernel-side APIC state into X86CPU.apic_state too early, APIC state ++ * won't be reloaded later because CPUState.vcpu_dirty==true, and ++ * outdated APIC state may be migrated to another host. ++ * ++ * The real fix would be to make sure outdated APIC state is read ++ * from the kernel again when necessary. While this is not fixed, we ++ * need the cpu_clean_all_dirty() call below. ++ */ ++ cpu_clean_all_dirty(); ++ + ret = kvm_vm_ioctl(kvm_state, KVM_GET_CLOCK, &data); + if (ret < 0) { + fprintf(stderr, "KVM_GET_CLOCK failed: %s\n", strerror(ret)); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/ubuntu/define-trusty-machine-type.patch qemu-2.0.0+dfsg/debian/patches/ubuntu/define-trusty-machine-type.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/ubuntu/define-trusty-machine-type.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/ubuntu/define-trusty-machine-type.patch 2014-04-18 16:13:12.000000000 +0000 @@ -0,0 +1,38 @@ +Index: qemu-2.0.0~rc1+dfsg/hw/i386/pc_piix.c +=================================================================== +--- qemu-2.0.0~rc1+dfsg.orig/hw/i386/pc_piix.c 2014-04-03 13:56:23.000000000 -0500 ++++ qemu-2.0.0~rc1+dfsg/hw/i386/pc_piix.c 2014-04-08 11:48:23.533221934 -0500 +@@ -390,9 +390,7 @@ static void pc_xen_hvm_init(QEMUMachineI + static QEMUMachine pc_i440fx_machine_v2_0 = { + PC_I440FX_2_0_MACHINE_OPTIONS, + .name = "pc-i440fx-2.0", +- .alias = "pc", + .init = pc_init_pci, +- .is_default = 1, + }; + + #define PC_I440FX_1_7_MACHINE_OPTIONS PC_I440FX_MACHINE_OPTIONS +@@ -839,3 +837,23 @@ static void pc_machine_init(void) + } + + machine_init(pc_machine_init); ++ ++/* Ubuntu machine types */ ++ ++static QEMUMachine pc_machine_trusty = { ++ PC_DEFAULT_MACHINE_OPTIONS, ++ .default_machine_opts = "firmware=bios-256k.bin", ++ .hot_add_cpu = pc_hot_add_cpu, ++ .name = "pc-i440fx-trusty", ++ .alias = "pc", ++ .desc = "Ubuntu 14.04 PC (i440FX + PIIX, 1996)", ++ .init = pc_init_pci, ++ .is_default = 1, ++}; ++ ++static void ubuntu_machine_init(void) ++{ ++ qemu_register_machine(&pc_machine_trusty); ++} ++ ++machine_init(ubuntu_machine_init); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/ubuntu/kvm_physical_sync_dirty_bitmap-ignore-ENOENT-from-kv.patch qemu-2.0.0+dfsg/debian/patches/ubuntu/kvm_physical_sync_dirty_bitmap-ignore-ENOENT-from-kv.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/ubuntu/kvm_physical_sync_dirty_bitmap-ignore-ENOENT-from-kv.patch 2014-04-09 03:29:16.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/ubuntu/kvm_physical_sync_dirty_bitmap-ignore-ENOENT-from-kv.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,36 +0,0 @@ -From 0d818e334f6db88b2770e9a1076ae1e68c41e460 Mon Sep 17 00:00:00 2001 -From: Serge Hallyn -Date: Tue, 8 Apr 2014 22:14:20 -0500 -Subject: [PATCH 1/1] kvm_physical_sync_dirty_bitmap: ignore ENOENT from - kvm_vm_ioctl - -ENOENT (iiuc) means the kernel has an empty dirty bitmap for this -slot. Don't abort in that case. This appears to solve the bug -reported at - -https://bugs.launchpad.net/ubuntu/+source/qemu/+bug/1303926 - -Signed-off-by: Serge Hallyn ---- - kvm-all.c | 5 ++++- - 1 file changed, 4 insertions(+), 1 deletion(-) - -Index: qemu-2.0.0~rc1+dfsg/kvm-all.c -=================================================================== ---- qemu-2.0.0~rc1+dfsg.orig/kvm-all.c 2014-04-08 22:28:38.000722081 -0500 -+++ qemu-2.0.0~rc1+dfsg/kvm-all.c 2014-04-08 22:29:14.644722904 -0500 -@@ -441,10 +441,13 @@ static int kvm_physical_sync_dirty_bitma - - d.slot = mem->slot; - -- if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) < 0) { -+ ret = kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d); -+ if (ret < 0 && ret != -ENOENT) { - DPRINTF("ioctl failed %d\n", errno); - ret = -1; - break; -+ } else if (ret < 0) { -+ ret = 0; - } - - kvm_get_dirty_pages_log_range(section, d.dirty_bitmap); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/upstream-fix-irq-route-entries.patch qemu-2.0.0+dfsg/debian/patches/upstream-fix-irq-route-entries.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/upstream-fix-irq-route-entries.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/upstream-fix-irq-route-entries.patch 2015-10-09 15:17:42.000000000 +0000 @@ -0,0 +1,89 @@ +From bdf026317daa3b9dfa281f29e96fbb6fd48394c8 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?=E9=A9=AC=E6=96=87=E9=9C=9C?= +Date: Wed, 1 Jul 2015 15:41:41 +0200 +Subject: [PATCH] Fix irq route entries exceeding KVM_MAX_IRQ_ROUTES + +Last month, we experienced several guests crash(6cores-8cores), qemu logs +display the following messages: + +qemu-system-x86_64: /build/qemu-2.1.2/kvm-all.c:976: +kvm_irqchip_commit_routes: Assertion `ret == 0' failed. + +After analysis and verification, we can confirm it's irq-balance +daemon(in guest) leads to the assertion failure. Start a 8 core guest with +two disks, execute the following scripts will reproduce the BUG quickly: + +irq_affinity.sh +======================================================================== + +vda_irq_num=25 +vdb_irq_num=27 +while [ 1 ] +do + for irq in {1,2,4,8,10,20,40,80} + do + echo $irq > /proc/irq/$vda_irq_num/smp_affinity + echo $irq > /proc/irq/$vdb_irq_num/smp_affinity + dd if=/dev/vda of=/dev/zero bs=4K count=100 iflag=direct + dd if=/dev/vdb of=/dev/zero bs=4K count=100 iflag=direct + done +done +======================================================================== + +QEMU setup static irq route entries in kvm_pc_setup_irq_routing(), PIC and +IOAPIC share the first 15 GSI numbers, take up 23 GSI numbers, but take up +38 irq route entries. When change irq smp_affinity in guest, a dynamic route +entry may be setup, the current logic is: if allocate GSI number succeeds, +a new route entry can be added. The available dynamic GSI numbers is +1021(KVM_MAX_IRQ_ROUTES-23), but available irq route entries is only +986(KVM_MAX_IRQ_ROUTES-38), GSI numbers greater than route entries. +irq-balance's behavior will eventually leads to total irq route entries +exceed KVM_MAX_IRQ_ROUTES, ioctl(KVM_SET_GSI_ROUTING) fail and +kvm_irqchip_commit_routes() trigger assertion failure. + +This patch fix the BUG. + +Signed-off-by: Wenshuang Ma +Cc: qemu-stable@nongnu.org +Signed-off-by: Paolo Bonzini +Signed-off-by: Stefan Bader +--- + kvm-all.c | 17 ++++++++++------- + 1 file changed, 10 insertions(+), 7 deletions(-) + +Index: qemu-2.3+dfsg/kvm-all.c +=================================================================== +--- qemu-2.3+dfsg.orig/kvm-all.c 2015-10-09 15:46:03.134069031 +0200 ++++ qemu-2.3+dfsg/kvm-all.c 2015-10-09 15:46:03.130069031 +0200 +@@ -1142,9 +1142,17 @@ static int kvm_irqchip_get_virq(KVMState + uint32_t *word = s->used_gsi_bitmap; + int max_words = ALIGN(s->gsi_count, 32) / 32; + int i, bit; +- bool retry = true; + +-again: ++ /* ++ * PIC and IOAPIC share the first 16 GSI numbers, thus the available ++ * GSI numbers are more than the number of IRQ route. Allocating a GSI ++ * number can succeed even though a new route entry cannot be added. ++ * When this happens, flush dynamic MSI entries to free IRQ route entries. ++ */ ++ if (!s->direct_msi && s->irq_routes->nr == s->gsi_count) { ++ kvm_flush_dynamic_msi_routes(s); ++ } ++ + /* Return the lowest unused GSI in the bitmap */ + for (i = 0; i < max_words; i++) { + bit = ffs(~word[i]); +@@ -1154,11 +1162,6 @@ again: + + return bit - 1 + i * 32; + } +- if (!s->direct_msi && retry) { +- retry = false; +- kvm_flush_dynamic_msi_routes(s); +- goto again; +- } + return -ENOSPC; + + } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/upstream-xen_disk-fix-unmapping-of-persistent-grants.patch qemu-2.0.0+dfsg/debian/patches/upstream-xen_disk-fix-unmapping-of-persistent-grants.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/upstream-xen_disk-fix-unmapping-of-persistent-grants.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/upstream-xen_disk-fix-unmapping-of-persistent-grants.patch 2014-12-15 08:57:13.000000000 +0000 @@ -0,0 +1,173 @@ +From 2f01dfacb56bc7a0d4639adc9dff9aae131e6216 Mon Sep 17 00:00:00 2001 +From: Roger Pau Monne +Date: Thu, 13 Nov 2014 18:42:09 +0100 +Subject: [PATCH] xen_disk: fix unmapping of persistent grants +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +This patch fixes two issues with persistent grants and the disk PV backend +(Qdisk): + + - Keep track of memory regions where persistent grants have been mapped + since we need to unmap them as a whole. It is not possible to unmap a + single grant if it has been batch-mapped. A new check has also been added + to make sure persistent grants are only used if the whole mapped region + can be persistently mapped in the batch_maps case. + - Unmap persistent grants before switching to the closed state, so the + frontend can also free them. + +Signed-off-by: Roger Pau Monné +Reported-by: George Dunlap +Cc: Stefano Stabellini +Cc: Kevin Wolf +Cc: Stefan Hajnoczi +Cc: George Dunlap +Cc: Konrad Rzeszutek Wilk + +(cherry-picked from 2f01dfacb56bc7a0d4639adc9dff9aae131e6216 qemu-upstream) +Signed-off-by: Stefan Bader +--- + hw/block/xen_disk.c | 72 ++++++++++++++++++++++++++++++++++++++++++++++++----- + 1 file changed, 66 insertions(+), 6 deletions(-) + +Index: qemu-2.0.0+dfsg/hw/block/xen_disk.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/block/xen_disk.c 2014-12-10 19:49:07.235424877 +0100 ++++ qemu-2.0.0+dfsg/hw/block/xen_disk.c 2014-12-10 19:49:07.231424878 +0100 +@@ -58,6 +58,13 @@ struct PersistentGrant { + + typedef struct PersistentGrant PersistentGrant; + ++struct PersistentRegion { ++ void *addr; ++ int num; ++}; ++ ++typedef struct PersistentRegion PersistentRegion; ++ + struct ioreq { + blkif_request_t req; + int16_t status; +@@ -116,6 +123,7 @@ struct XenBlkDev { + /* Persistent grants extension */ + gboolean feature_persistent; + GTree *persistent_gnts; ++ GSList *persistent_regions; + unsigned int persistent_gnt_count; + unsigned int max_grants; + +@@ -175,6 +183,23 @@ static void destroy_grant(gpointer pgnt) + g_free(grant); + } + ++static void remove_persistent_region(gpointer data, gpointer dev) ++{ ++ PersistentRegion *region = data; ++ struct XenBlkDev *blkdev = dev; ++ XenGnttab gnt = blkdev->xendev.gnttabdev; ++ ++ if (xc_gnttab_munmap(gnt, region->addr, region->num) != 0) { ++ xen_be_printf(&blkdev->xendev, 0, ++ "xc_gnttab_munmap region %p failed: %s\n", ++ region->addr, strerror(errno)); ++ } ++ xen_be_printf(&blkdev->xendev, 3, ++ "unmapped grant region %p with %d pages\n", ++ region->addr, region->num); ++ g_free(region); ++} ++ + static struct ioreq *ioreq_start(struct XenBlkDev *blkdev) + { + struct ioreq *ioreq = NULL; +@@ -339,6 +364,7 @@ static int ioreq_map(struct ioreq *ioreq + void *page[BLKIF_MAX_SEGMENTS_PER_REQUEST]; + int i, j, new_maps = 0; + PersistentGrant *grant; ++ PersistentRegion *region; + /* domids and refs variables will contain the information necessary + * to map the grants that are needed to fulfill this request. + * +@@ -417,7 +443,22 @@ static int ioreq_map(struct ioreq *ioreq + } + } + } +- if (ioreq->blkdev->feature_persistent) { ++ if (ioreq->blkdev->feature_persistent && new_maps != 0 && ++ (!batch_maps || (ioreq->blkdev->persistent_gnt_count + new_maps <= ++ ioreq->blkdev->max_grants))) { ++ /* ++ * If we are using persistent grants and batch mappings only ++ * add the new maps to the list of persistent grants if the whole ++ * area can be persistently mapped. ++ */ ++ if (batch_maps) { ++ region = g_malloc0(sizeof(*region)); ++ region->addr = ioreq->pages; ++ region->num = new_maps; ++ ioreq->blkdev->persistent_regions = g_slist_append( ++ ioreq->blkdev->persistent_regions, ++ region); ++ } + while ((ioreq->blkdev->persistent_gnt_count < ioreq->blkdev->max_grants) + && new_maps) { + /* Go through the list of newly mapped grants and add as many +@@ -443,6 +484,7 @@ static int ioreq_map(struct ioreq *ioreq + grant); + ioreq->blkdev->persistent_gnt_count++; + } ++ assert(!batch_maps || new_maps == 0); + } + for (i = 0; i < ioreq->v.niov; i++) { + ioreq->v.iov[i].iov_base += (uintptr_t)page[i]; +@@ -929,7 +971,10 @@ static int blk_connect(struct XenDevice + blkdev->max_grants = max_requests * BLKIF_MAX_SEGMENTS_PER_REQUEST; + blkdev->persistent_gnts = g_tree_new_full((GCompareDataFunc)int_cmp, + NULL, NULL, ++ batch_maps ? ++ (GDestroyNotify)g_free : + (GDestroyNotify)destroy_grant); ++ blkdev->persistent_regions = NULL; + blkdev->persistent_gnt_count = 0; + } + +@@ -958,6 +1003,26 @@ static void blk_disconnect(struct XenDev + blkdev->cnt_map--; + blkdev->sring = NULL; + } ++ ++ /* ++ * Unmap persistent grants before switching to the closed state ++ * so the frontend can free them. ++ * ++ * In the !batch_maps case g_tree_destroy will take care of unmapping ++ * the grant, but in the batch_maps case we need to iterate over every ++ * region in persistent_regions and unmap it. ++ */ ++ if (blkdev->feature_persistent) { ++ g_tree_destroy(blkdev->persistent_gnts); ++ assert(batch_maps || blkdev->persistent_gnt_count == 0); ++ if (batch_maps) { ++ blkdev->persistent_gnt_count = 0; ++ g_slist_foreach(blkdev->persistent_regions, ++ (GFunc)remove_persistent_region, blkdev); ++ g_slist_free(blkdev->persistent_regions); ++ } ++ blkdev->feature_persistent = false; ++ } + } + + static int blk_free(struct XenDevice *xendev) +@@ -969,11 +1034,6 @@ static int blk_free(struct XenDevice *xe + blk_disconnect(xendev); + } + +- /* Free persistent grants */ +- if (blkdev->feature_persistent) { +- g_tree_destroy(blkdev->persistent_gnts); +- } +- + while (!QLIST_EMPTY(&blkdev->freelist)) { + ioreq = QLIST_FIRST(&blkdev->freelist); + QLIST_REMOVE(ioreq, list); diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/use-fixed-data-path.patch qemu-2.0.0+dfsg/debian/patches/use-fixed-data-path.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/use-fixed-data-path.patch 2014-03-27 17:56:08.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/use-fixed-data-path.patch 2014-04-17 13:30:59.000000000 +0000 @@ -7,10 +7,8 @@ This way it is possible to move qemu binary to another directory and it will still work. -Index: qemu-2.0~git-20140327.3768d50/os-posix.c -=================================================================== ---- qemu-2.0~git-20140327.3768d50.orig/os-posix.c 2014-03-27 12:55:45.478902972 -0500 -+++ qemu-2.0~git-20140327.3768d50/os-posix.c 2014-03-27 12:55:45.470902972 -0500 +--- a/os-posix.c ++++ b/os-posix.c @@ -75,6 +75,7 @@ void os_setup_signal_handling(void) sigaction(SIGTERM, &act, NULL); } @@ -27,10 +25,8 @@ void os_set_proc_name(const char *s) { -Index: qemu-2.0~git-20140327.3768d50/vl.c -=================================================================== ---- qemu-2.0~git-20140327.3768d50.orig/vl.c 2014-03-27 12:55:45.478902972 -0500 -+++ qemu-2.0~git-20140327.3768d50/vl.c 2014-03-27 12:55:45.470902972 -0500 +--- a/vl.c ++++ b/vl.c @@ -3997,14 +3997,6 @@ int main(int argc, char **argv, char **e } } diff -Nru qemu-2.0.0~rc1+dfsg/debian/patches/virtio-net-fix-guest-triggerable-buffer-overrun-CVE-2014-0150.patch qemu-2.0.0+dfsg/debian/patches/virtio-net-fix-guest-triggerable-buffer-overrun-CVE-2014-0150.patch --- qemu-2.0.0~rc1+dfsg/debian/patches/virtio-net-fix-guest-triggerable-buffer-overrun-CVE-2014-0150.patch 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/patches/virtio-net-fix-guest-triggerable-buffer-overrun-CVE-2014-0150.patch 2014-04-17 13:30:47.000000000 +0000 @@ -0,0 +1,47 @@ +From edc243851279e3393000b28b6b69454cae1190ef Mon Sep 17 00:00:00 2001 +From: "Michael S. Tsirkin" +Date: Fri, 11 Apr 2014 15:18:08 +0300 +Subject: [PATCH] virtio-net: fix guest-triggerable buffer overrun +Bug-Debian: http://bugs.debian.org/744221 + +When VM guest programs multicast addresses for +a virtio net card, it supplies a 32 bit +entries counter for the number of addresses. +These addresses are read into tail portion of +a fixed macs array which has size MAC_TABLE_ENTRIES, +at offset equal to in_use. + +To avoid overflow of this array by guest, qemu attempts +to test the size as follows: +- if (in_use + mac_data.entries <= MAC_TABLE_ENTRIES) { + +however, as mac_data.entries is uint32_t, this sum +can overflow, e.g. if in_use is 1 and mac_data.entries +is 0xffffffff then in_use + mac_data.entries will be 0. + +Qemu will then read guest supplied buffer into this +memory, overflowing buffer on heap. + +CVE-2014-0150 + +Cc: qemu-stable@nongnu.org +Signed-off-by: Michael S. Tsirkin +Message-id: 1397218574-25058-1-git-send-email-mst@redhat.com +Reviewed-by: Michael Tokarev +Signed-off-by: Peter Maydell +Backported-to-1.7: Michael Tokarev +--- + hw/net/virtio-net.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/hw/net/virtio-net.c ++++ b/hw/net/virtio-net.c +@@ -656,7 +656,7 @@ static int virtio_net_handle_mac(VirtION + goto error; + } + +- if (n->mac_table.in_use + mac_data.entries <= MAC_TABLE_ENTRIES) { ++ if (mac_data.entries <= MAC_TABLE_ENTRIES - n->mac_table.in_use) { + s = iov_to_buf(iov, iov_cnt, 0, + &n->mac_table.macs[n->mac_table.in_use * ETH_ALEN], + mac_data.entries * ETH_ALEN); diff -Nru qemu-2.0.0~rc1+dfsg/debian/qemu-debootstrap qemu-2.0.0+dfsg/debian/qemu-debootstrap --- qemu-2.0.0~rc1+dfsg/debian/qemu-debootstrap 2014-02-04 14:27:01.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/qemu-debootstrap 2014-04-18 16:23:39.000000000 +0000 @@ -140,6 +140,9 @@ armel|armhf) qemu_arch="arm" ;; + arm64) + qemu_arch="aarch64" + ;; lpia) qemu_arch="i386" ;; diff -Nru qemu-2.0.0~rc1+dfsg/debian/qemu-system-alternatives.in qemu-2.0.0+dfsg/debian/qemu-system-alternatives.in --- qemu-2.0.0~rc1+dfsg/debian/qemu-system-alternatives.in 2014-02-04 14:27:01.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/qemu-system-alternatives.in 2014-05-07 22:32:55.000000000 +0000 @@ -1,26 +1,9 @@ # == begin update-alternatives maintscript fragment == -# This is a script fragment used in postinst, prerm and postrm maintscripts. -# Set up /usr/bin/qemu alternative to be one the qemu-system emulators. -# See #722914 for details about how it is done - -arches="@ARCH@" # our architectures - -case "$DPKG_MAINTSCRIPT_NAME:$1" in - - postinst:configure ) - for arch in $arches ; do - # Set i386 as highest priority, - # as it has been the default qemu for quite some time. - case $arch in i386) prio=20;; *) prio=10;; esac - update-alternatives --install /usr/bin/qemu qemu \ - /usr/bin/qemu-system-$arch $prio - done;; - - prerm:remove | postrm:disappear ) - for arch in $arches ; do - update-alternatives --remove qemu /usr/bin/qemu-system-$arch - done;; - -esac - +# this should go away for jessie+1 +if [ ".$1" = .configure ] && dpkg --compare-versions "$2" lt-nl "2.0.0+dfsg-2ubuntu3" +then + for arch in @ARCH@ ; do + update-alternatives --remove qemu /usr/bin/qemu-system-$arch + done +fi # == end update-alternatives maintscript fragment == diff -Nru qemu-2.0.0~rc1+dfsg/debian/qemu-system-common.NEWS qemu-2.0.0+dfsg/debian/qemu-system-common.NEWS --- qemu-2.0.0~rc1+dfsg/debian/qemu-system-common.NEWS 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/qemu-system-common.NEWS 2014-05-07 22:32:55.000000000 +0000 @@ -0,0 +1,14 @@ +qemu (2.0.0~rc1+dfsg-2exp) experimental; urgency=low + +qemu-system-* packages does not provide /usr/bin/qemu alternative +anymore, and all various alternatives will be unregistered at new +individual qemu-system packages install. This is because different +architectures are not really alternatives, and never has been. +Historically, qemu emulated just one architecture, so the name "qemu" +was used for the binary. However when more architectures were added, +the old name "qemu" was used as an alternative, pointing to one of +the emulators. Upstream does not use the name "qemu" for binaries +for a long time. If you have scripts using the old name "qemu" +please update them to use the right qemu-system-* binary. + + -- Michael Tokarev Fri, 11 Apr 2014 19:57:22 +0400 diff -Nru qemu-2.0.0~rc1+dfsg/debian/qemu-system-x86.postinst qemu-2.0.0+dfsg/debian/qemu-system-x86.postinst --- qemu-2.0.0~rc1+dfsg/debian/qemu-system-x86.postinst 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/qemu-system-x86.postinst 2014-09-15 00:40:36.000000000 +0000 @@ -0,0 +1,21 @@ +#! /bin/sh + +set -e + +# dh_installdeb will replace this with shell code automatically +# generated by other debhelper scripts. +#DEBHELPER# + +# If the host had already installed kvm_intel.ko without nested=1, then +# re-load it now, honoring whatever is in qemu-system-x86.modprobe +if [ "$1" = configure ] ; then + INTEL_NESTED=/sys/module/kvm_intel/parameters/nested + if grep -q kvm_intel /proc/modules && [ -f $INTEL_NESTED ]; then + v=`cat $INTEL_NESTED` + if [ "x$v" != "xY" ]; then + rmmod kvm_intel && modprobe kvm_intel || true + fi + fi +fi + +exit 0 diff -Nru qemu-2.0.0~rc1+dfsg/debian/qemu-system-x86.qemu-kvm.upstart qemu-2.0.0+dfsg/debian/qemu-system-x86.qemu-kvm.upstart --- qemu-2.0.0~rc1+dfsg/debian/qemu-system-x86.qemu-kvm.upstart 2014-02-04 16:28:27.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/qemu-system-x86.qemu-kvm.upstart 2014-11-20 17:24:49.000000000 +0000 @@ -7,7 +7,7 @@ pre-start script # Silently exit if the package isn't installed anymore - if [ ! -e /usr/bin/kvm ]; then + if [ ! -e /usr/bin/qemu-system-x86_64 ]; then exit 0 fi [ -r /etc/default/qemu-kvm ] && . /etc/default/qemu-kvm @@ -17,6 +17,11 @@ elif grep -qs "^flags.* svm" /proc/cpuinfo; then modprobe -b kvm_amd || true fi + if running-in-container; then + mknod /dev/kvm c 10 232 || true + chown root:kvm /dev/kvm || true + chmod g+rw /dev/kvm || true + fi # Enable KSM, respecting the default configuration file if [ "$KSM_ENABLED" = "1" ]; then [ -w /sys/kernel/mm/ksm/run ] && echo 1 > /sys/kernel/mm/ksm/run || true diff -Nru qemu-2.0.0~rc1+dfsg/debian/README.Debian qemu-2.0.0+dfsg/debian/README.Debian --- qemu-2.0.0~rc1+dfsg/debian/README.Debian 1970-01-01 00:00:00.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/README.Debian 2014-10-06 22:36:28.000000000 +0000 @@ -0,0 +1,16 @@ +QEMU/kvm pc-1.0 Machine Type migration +=============================== +In 14.04 Ubuntu switched from the qemu-kvm source tree to the qemu source tree. +The pc-1.0 machine type in the two source trees differed. This made +live migration of a pc-1.0 machine type guest from a 12.04 host to a 14.04 +host fail. Fixing this transparently is impossible at this point as it +would break migration from pc-1.0 machine type VMs started in 14.04. + +To work around this, a new machine type, called pc-1.0-qemu-kvm and aliased +to "pc-1.0-precise", has been introduced. To accept incoming migration from +a pc-1.0 machine from another 14.04 host, simply use "-M pc-1.0" as before. +To accept incoming migration from a pc-1.0 machine from a 12.04 host, +use "-M pc-1.0-precise". This will require the kvm-ipxe-precise package to +be installed, which provides the ipxe-roms used by that machine type. + + -- Serge Hallyn Mon, 06 Oct 2014 17:11:54 -0500 diff -Nru qemu-2.0.0~rc1+dfsg/debian/rules qemu-2.0.0+dfsg/debian/rules --- qemu-2.0.0~rc1+dfsg/debian/rules 2014-04-05 00:14:35.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/rules 2015-08-04 18:57:57.000000000 +0000 @@ -174,9 +174,8 @@ binary: install define inst-system - for x in postinst prerm postrm; do \ - sed 's/@ARCH@/${sysarch_$1}/' debian/qemu-system-alternatives.in > debian/qemu-system-$1.$$x.debhelper; \ - done +# remove alternatives for jessie+1 + sed 's/@ARCH@/${sysarch_$1}/' debian/qemu-system-alternatives.in > debian/qemu-system-$1.postinst.debhelper mkdir -p debian/qemu-system-$1/usr/share/man/man1 debian/qemu-system-$1/usr/bin for t in ${sysarch_$1}; do \ mv debian/tmp/usr/bin/qemu-system-$$t debian/qemu-system-$1/usr/bin/; \ @@ -204,11 +203,10 @@ ifeq ($(DEB_HOST_ARCH_OS),linux) -# /usr/bin/kvm compat script. This needs some more work for other arches -# How about a manpage for it? -ifneq ($(filter $(DEB_HOST_ARCH),amd64 i386),) - dh_install -pqemu-kvm debian/kvm /usr/bin/ - dh_install -pqemu-kvm debian/kvm.1 /usr/share/man/man1/ +# /usr/bin/kvm compat script. +ifneq ($(filter $(DEB_HOST_ARCH),amd64 i386 x32),) + install -D -m755 debian/kvm.x86 debian/qemu-kvm/usr/bin/kvm + install -D -m644 debian/kvm.1 debian/qemu-kvm/usr/share/man/man1/kvm.1 ifeq ($(DEB_VENDOR),Ubuntu) mkdir -p debian/qemu-kvm/usr/bin ln -s kvm debian/qemu-kvm/usr/bin/kvm-spice @@ -216,6 +214,15 @@ dh_installmodules -pqemu-system-x86 endif endif +ifneq ($(filter $(DEB_HOST_ARCH),arm64),) + install -D -m755 debian/kvm.arm64 debian/qemu-kvm/usr/bin/kvm +endif +ifneq ($(filter $(DEB_HOST_ARCH),armhf armel),) + install -D -m755 debian/kvm.arm32 debian/qemu-kvm/usr/bin/kvm +endif +ifneq ($(filter $(DEB_HOST_ARCH),ppc64 ppc64el powerpc),) + install -D -m755 debian/kvm.powerpc debian/qemu-kvm/usr/bin/kvm +endif # virtfs-proxy-helper is linux-specific for f in usr/bin/virtfs-proxy-helper \ @@ -275,7 +282,7 @@ # we load kvm module only on x86 (modern kernels don't need even that), # and we don't want to fail installation if module can't be loaded # remoe past jessie (and maybe for jessie too) - dh_installinit -pqemu-system-x86 --no-restart-on-upgrade --error-handler=: -- start 20 S . + dh_installinit -pqemu-system-x86 --no-restart-on-upgrade --error-handler=true --name=qemu-kvm endif endif dh_installinit -pqemu-guest-agent diff -Nru qemu-2.0.0~rc1+dfsg/debian/TODO qemu-2.0.0+dfsg/debian/TODO --- qemu-2.0.0~rc1+dfsg/debian/TODO 2014-02-04 14:27:01.000000000 +0000 +++ qemu-2.0.0+dfsg/debian/TODO 2014-05-07 22:32:55.000000000 +0000 @@ -21,6 +21,8 @@ * startup script for qemu-guest-agent: check dependencies & runlevels. +* remove /usr/bin/qemu alternative removing for jessie+1 + * maybe provide activation for udev & systemd: SUBSYSTEM=="virtio-ports", ATTR{name}=="org.qemu.guest_agent.0", \ diff -Nru qemu-2.0.0~rc1+dfsg/dma-helpers.c qemu-2.0.0+dfsg/dma-helpers.c --- qemu-2.0.0~rc1+dfsg/dma-helpers.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/dma-helpers.c 2014-04-17 14:26:43.000000000 +0000 @@ -213,6 +213,7 @@ dbs->sg_cur_index = 0; dbs->sg_cur_byte = 0; dbs->dir = dir; + dbs->in_cancel = false; dbs->io_func = io_func; dbs->bh = NULL; qemu_iovec_init(&dbs->iov, sg->nsg); diff -Nru qemu-2.0.0~rc1+dfsg/fpu/softfloat.c qemu-2.0.0+dfsg/fpu/softfloat.c --- qemu-2.0.0~rc1+dfsg/fpu/softfloat.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/fpu/softfloat.c 2014-04-17 14:26:43.000000000 +0000 @@ -1628,6 +1628,26 @@ /*---------------------------------------------------------------------------- | Returns the result of converting the single-precision floating-point value +| `a' to the 64-bit unsigned integer format. The conversion is +| performed according to the IEC/IEEE Standard for Binary Floating-Point +| Arithmetic, except that the conversion is always rounded toward zero. If +| `a' is a NaN, the largest unsigned integer is returned. Otherwise, if the +| conversion overflows, the largest unsigned integer is returned. If the +| 'a' is negative, the result is rounded and zero is returned; values that do +| not round to zero will raise the inexact flag. +*----------------------------------------------------------------------------*/ + +uint64 float32_to_uint64_round_to_zero(float32 a STATUS_PARAM) +{ + signed char current_rounding_mode = STATUS(float_rounding_mode); + set_float_rounding_mode(float_round_to_zero STATUS_VAR); + int64_t v = float32_to_uint64(a STATUS_VAR); + set_float_rounding_mode(current_rounding_mode STATUS_VAR); + return v; +} + +/*---------------------------------------------------------------------------- +| Returns the result of converting the single-precision floating-point value | `a' to the 64-bit two's complement integer format. The conversion is | performed according to the IEC/IEEE Standard for Binary Floating-Point | Arithmetic, except that the conversion is always rounded toward zero. If diff -Nru qemu-2.0.0~rc1+dfsg/hw/arm/highbank.c qemu-2.0.0+dfsg/hw/arm/highbank.c --- qemu-2.0.0~rc1+dfsg/hw/arm/highbank.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/hw/arm/highbank.c 2014-04-17 14:26:43.000000000 +0000 @@ -230,18 +230,23 @@ for (n = 0; n < smp_cpus; n++) { ObjectClass *oc = cpu_class_by_name(TYPE_ARM_CPU, cpu_model); + Object *cpuobj; ARMCPU *cpu; Error *err = NULL; - cpu = ARM_CPU(object_new(object_class_get_name(oc))); - - object_property_set_int(OBJECT(cpu), MPCORE_PERIPHBASE, "reset-cbar", - &err); - if (err) { - error_report("%s", error_get_pretty(err)); + if (!oc) { + error_report("Unable to find CPU definition"); exit(1); } - object_property_set_bool(OBJECT(cpu), true, "realized", &err); + + cpuobj = object_new(object_class_get_name(oc)); + cpu = ARM_CPU(cpuobj); + + if (object_property_find(cpuobj, "reset-cbar", NULL)) { + object_property_set_int(cpuobj, MPCORE_PERIPHBASE, + "reset-cbar", &error_abort); + } + object_property_set_bool(cpuobj, true, "realized", &err); if (err) { error_report("%s", error_get_pretty(err)); exit(1); diff -Nru qemu-2.0.0~rc1+dfsg/hw/arm/vexpress.c qemu-2.0.0+dfsg/hw/arm/vexpress.c --- qemu-2.0.0~rc1+dfsg/hw/arm/vexpress.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/hw/arm/vexpress.c 2014-04-17 14:26:43.000000000 +0000 @@ -192,10 +192,9 @@ Object *cpuobj = object_new(object_class_get_name(cpu_oc)); Error *err = NULL; - object_property_set_int(cpuobj, periphbase, "reset-cbar", &err); - if (err) { - error_report("%s", error_get_pretty(err)); - exit(1); + if (object_property_find(cpuobj, "reset-cbar", NULL)) { + object_property_set_int(cpuobj, periphbase, + "reset-cbar", &error_abort); } object_property_set_bool(cpuobj, true, "realized", &err); if (err) { diff -Nru qemu-2.0.0~rc1+dfsg/hw/block/dataplane/virtio-blk.c qemu-2.0.0+dfsg/hw/block/dataplane/virtio-blk.c --- qemu-2.0.0~rc1+dfsg/hw/block/dataplane/virtio-blk.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/hw/block/dataplane/virtio-blk.c 2014-04-17 14:26:43.000000000 +0000 @@ -23,7 +23,7 @@ #include "virtio-blk.h" #include "block/aio.h" #include "hw/virtio/virtio-bus.h" -#include "monitor/monitor.h" /* for object_add() */ +#include "qom/object_interfaces.h" enum { SEG_MAX = 126, /* maximum number of I/O segments */ @@ -59,7 +59,7 @@ * use it). */ IOThread *iothread; - bool internal_iothread; + IOThread internal_iothread_obj; AioContext *ctx; EventNotifier io_notifier; /* Linux AIO completion */ EventNotifier host_notifier; /* doorbell */ @@ -391,23 +391,19 @@ s->blk = blk; if (blk->iothread) { - s->internal_iothread = false; s->iothread = blk->iothread; + object_ref(OBJECT(s->iothread)); } else { - /* Create per-device IOThread if none specified */ - Error *local_err = NULL; - - s->internal_iothread = true; - object_add(TYPE_IOTHREAD, vdev->name, NULL, NULL, &local_err); - if (error_is_set(&local_err)) { - error_propagate(errp, local_err); - g_free(s); - return; - } - s->iothread = iothread_find(vdev->name); - assert(s->iothread); + /* Create per-device IOThread if none specified. This is for + * x-data-plane option compatibility. If x-data-plane is removed we + * can drop this. + */ + object_initialize(&s->internal_iothread_obj, + sizeof(s->internal_iothread_obj), + TYPE_IOTHREAD); + user_creatable_complete(OBJECT(&s->internal_iothread_obj), &error_abort); + s->iothread = &s->internal_iothread_obj; } - object_ref(OBJECT(s->iothread)); s->ctx = iothread_get_aio_context(s->iothread); /* Prevent block operations that conflict with data plane thread */ @@ -426,9 +422,6 @@ virtio_blk_data_plane_stop(s); bdrv_set_in_use(s->blk->conf.bs, 0); object_unref(OBJECT(s->iothread)); - if (s->internal_iothread) { - object_unparent(OBJECT(s->iothread)); - } g_free(s); } diff -Nru qemu-2.0.0~rc1+dfsg/hw/char/serial.c qemu-2.0.0+dfsg/hw/char/serial.c --- qemu-2.0.0~rc1+dfsg/hw/char/serial.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/hw/char/serial.c 2014-04-17 14:26:43.000000000 +0000 @@ -225,8 +225,10 @@ if (s->tsr_retry <= 0) { if (s->fcr & UART_FCR_FE) { - s->tsr = fifo8_is_empty(&s->xmit_fifo) ? - 0 : fifo8_pop(&s->xmit_fifo); + if (fifo8_is_empty(&s->xmit_fifo)) { + return FALSE; + } + s->tsr = fifo8_pop(&s->xmit_fifo); if (!s->xmit_fifo.num) { s->lsr |= UART_LSR_THRE; } diff -Nru qemu-2.0.0~rc1+dfsg/hw/core/fw-path-provider.c qemu-2.0.0+dfsg/hw/core/fw-path-provider.c --- qemu-2.0.0~rc1+dfsg/hw/core/fw-path-provider.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/hw/core/fw-path-provider.c 2014-04-17 14:26:43.000000000 +0000 @@ -3,7 +3,8 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; under version 2 of the License. + * the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff -Nru qemu-2.0.0~rc1+dfsg/hw/i386/acpi-build.c qemu-2.0.0+dfsg/hw/i386/acpi-build.c --- qemu-2.0.0~rc1+dfsg/hw/i386/acpi-build.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/hw/i386/acpi-build.c 2014-04-17 14:26:43.000000000 +0000 @@ -391,7 +391,7 @@ build_append_byte(table, 0x01); /* OneOp */ } else if (value <= 0xFF) { build_append_value(table, value, 1); - } else if (value <= 0xFFFFF) { + } else if (value <= 0xFFFF) { build_append_value(table, value, 2); } else { build_append_value(table, value, 4); diff -Nru qemu-2.0.0~rc1+dfsg/hw/i386/acpi-dsdt-cpu-hotplug.dsl qemu-2.0.0+dfsg/hw/i386/acpi-dsdt-cpu-hotplug.dsl --- qemu-2.0.0~rc1+dfsg/hw/i386/acpi-dsdt-cpu-hotplug.dsl 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/hw/i386/acpi-dsdt-cpu-hotplug.dsl 2014-04-17 14:26:43.000000000 +0000 @@ -93,7 +93,7 @@ } Device(CPU_HOTPLUG_RESOURCE_DEVICE) { - Name(_HID, "ACPI0004") + Name(_HID, EisaId("PNP0A06")) Name(_CRS, ResourceTemplate() { IO(Decode16, CPU_STATUS_BASE, CPU_STATUS_BASE, 0, CPU_STATUS_LEN) diff -Nru qemu-2.0.0~rc1+dfsg/hw/i386/acpi-dsdt.hex.generated qemu-2.0.0+dfsg/hw/i386/acpi-dsdt.hex.generated --- qemu-2.0.0~rc1+dfsg/hw/i386/acpi-dsdt.hex.generated 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/hw/i386/acpi-dsdt.hex.generated 2014-04-17 14:26:43.000000000 +0000 @@ -3,12 +3,12 @@ 0x53, 0x44, 0x54, -0x85, +0x80, 0x11, 0x0, 0x0, 0x1, -0x8b, +0x60, 0x42, 0x58, 0x50, @@ -31,8 +31,8 @@ 0x4e, 0x54, 0x4c, -0x23, -0x8, +0x15, +0x11, 0x13, 0x20, 0x10, @@ -4010,7 +4010,7 @@ 0x53, 0x1, 0x10, -0x47, +0x42, 0x11, 0x5f, 0x53, @@ -4243,7 +4243,7 @@ 0x60, 0x5b, 0x82, -0x2e, +0x29, 0x50, 0x52, 0x45, @@ -4253,16 +4253,11 @@ 0x48, 0x49, 0x44, -0xd, +0xc, 0x41, -0x43, -0x50, -0x49, -0x30, -0x30, -0x30, -0x34, -0x0, +0xd0, +0xa, +0x6, 0x8, 0x5f, 0x43, diff -Nru qemu-2.0.0~rc1+dfsg/hw/i386/q35-acpi-dsdt.hex.generated qemu-2.0.0+dfsg/hw/i386/q35-acpi-dsdt.hex.generated --- qemu-2.0.0~rc1+dfsg/hw/i386/q35-acpi-dsdt.hex.generated 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/hw/i386/q35-acpi-dsdt.hex.generated 2014-04-17 14:26:43.000000000 +0000 @@ -3,12 +3,12 @@ 0x53, 0x44, 0x54, -0xd7, +0xd2, 0x1c, 0x0, 0x0, 0x1, -0x3e, +0x13, 0x42, 0x58, 0x50, @@ -31,8 +31,8 @@ 0x4e, 0x54, 0x4c, -0x23, -0x8, +0x15, +0x11, 0x13, 0x20, 0x10, @@ -6959,7 +6959,7 @@ 0x53, 0x1, 0x10, -0x47, +0x42, 0x11, 0x5f, 0x53, @@ -7192,7 +7192,7 @@ 0x60, 0x5b, 0x82, -0x2e, +0x29, 0x50, 0x52, 0x45, @@ -7202,16 +7202,11 @@ 0x48, 0x49, 0x44, -0xd, +0xc, 0x41, -0x43, -0x50, -0x49, -0x30, -0x30, -0x30, -0x34, -0x0, +0xd0, +0xa, +0x6, 0x8, 0x5f, 0x43, diff -Nru qemu-2.0.0~rc1+dfsg/hw/ide/core.c qemu-2.0.0+dfsg/hw/ide/core.c --- qemu-2.0.0~rc1+dfsg/hw/ide/core.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/hw/ide/core.c 2014-04-17 14:26:44.000000000 +0000 @@ -1602,7 +1602,7 @@ case 2: /* extended self test */ s->smart_selftest_count++; if (s->smart_selftest_count > 21) { - s->smart_selftest_count = 0; + s->smart_selftest_count = 1; } n = 2 + (s->smart_selftest_count - 1) * 24; s->smart_selftest_data[n] = s->sector; diff -Nru qemu-2.0.0~rc1+dfsg/hw/net/virtio-net.c qemu-2.0.0+dfsg/hw/net/virtio-net.c --- qemu-2.0.0~rc1+dfsg/hw/net/virtio-net.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/hw/net/virtio-net.c 2014-04-17 14:26:44.000000000 +0000 @@ -677,7 +677,7 @@ goto error; } - if (in_use + mac_data.entries <= MAC_TABLE_ENTRIES) { + if (mac_data.entries <= MAC_TABLE_ENTRIES - in_use) { s = iov_to_buf(iov, iov_cnt, 0, &macs[in_use * ETH_ALEN], mac_data.entries * ETH_ALEN); if (s != mac_data.entries * ETH_ALEN) { diff -Nru qemu-2.0.0~rc1+dfsg/hw/net/vmxnet3.c qemu-2.0.0+dfsg/hw/net/vmxnet3.c --- qemu-2.0.0~rc1+dfsg/hw/net/vmxnet3.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/hw/net/vmxnet3.c 2014-04-17 14:26:44.000000000 +0000 @@ -52,6 +52,9 @@ #define VMXNET3_DEVICE_VERSION 0x1 #define VMXNET3_DEVICE_REVISION 0x1 +/* Number of interrupt vectors for non-MSIx modes */ +#define VMXNET3_MAX_NMSIX_INTRS (1) + /* Macros for rings descriptors access */ #define VMXNET3_READ_TX_QUEUE_DESCR8(dpa, field) \ (vmw_shmem_ld8(dpa + offsetof(struct Vmxnet3_TxQueueDesc, field))) @@ -1305,6 +1308,51 @@ (pci_get_byte(s->parent_obj.config + PCI_INTERRUPT_PIN) - 1)); } +static void vmxnet3_validate_interrupt_idx(bool is_msix, int idx) +{ + int max_ints = is_msix ? VMXNET3_MAX_INTRS : VMXNET3_MAX_NMSIX_INTRS; + if (idx >= max_ints) { + hw_error("Bad interrupt index: %d\n", idx); + } +} + +static void vmxnet3_validate_interrupts(VMXNET3State *s) +{ + int i; + + VMW_CFPRN("Verifying event interrupt index (%d)", s->event_int_idx); + vmxnet3_validate_interrupt_idx(s->msix_used, s->event_int_idx); + + for (i = 0; i < s->txq_num; i++) { + int idx = s->txq_descr[i].intr_idx; + VMW_CFPRN("Verifying TX queue %d interrupt index (%d)", i, idx); + vmxnet3_validate_interrupt_idx(s->msix_used, idx); + } + + for (i = 0; i < s->rxq_num; i++) { + int idx = s->rxq_descr[i].intr_idx; + VMW_CFPRN("Verifying RX queue %d interrupt index (%d)", i, idx); + vmxnet3_validate_interrupt_idx(s->msix_used, idx); + } +} + +static void vmxnet3_validate_queues(VMXNET3State *s) +{ + /* + * txq_num and rxq_num are total number of queues + * configured by guest. These numbers must not + * exceed corresponding maximal values. + */ + + if (s->txq_num > VMXNET3_DEVICE_MAX_TX_QUEUES) { + hw_error("Bad TX queues number: %d\n", s->txq_num); + } + + if (s->rxq_num > VMXNET3_DEVICE_MAX_RX_QUEUES) { + hw_error("Bad RX queues number: %d\n", s->rxq_num); + } +} + static void vmxnet3_activate_device(VMXNET3State *s) { int i; @@ -1351,7 +1399,7 @@ VMXNET3_READ_DRV_SHARED8(s->drv_shmem, devRead.misc.numRxQueues); VMW_CFPRN("Number of TX/RX queues %u/%u", s->txq_num, s->rxq_num); - assert(s->txq_num <= VMXNET3_DEVICE_MAX_TX_QUEUES); + vmxnet3_validate_queues(s); qdescr_table_pa = VMXNET3_READ_DRV_SHARED64(s->drv_shmem, devRead.misc.queueDescPA); @@ -1447,6 +1495,8 @@ sizeof(s->rxq_descr[i].rxq_stats)); } + vmxnet3_validate_interrupts(s); + /* Make sure everything is in place before device activation */ smp_wmb(); @@ -2005,7 +2055,6 @@ } } -#define VMXNET3_MSI_NUM_VECTORS (1) #define VMXNET3_MSI_OFFSET (0x50) #define VMXNET3_USE_64BIT (true) #define VMXNET3_PER_VECTOR_MASK (false) @@ -2016,7 +2065,7 @@ PCIDevice *d = PCI_DEVICE(s); int res; - res = msi_init(d, VMXNET3_MSI_OFFSET, VMXNET3_MSI_NUM_VECTORS, + res = msi_init(d, VMXNET3_MSI_OFFSET, VMXNET3_MAX_NMSIX_INTRS, VMXNET3_USE_64BIT, VMXNET3_PER_VECTOR_MASK); if (0 > res) { VMW_WRPRN("Failed to initialize MSI, error %d", res); @@ -2342,6 +2391,9 @@ } } + vmxnet3_validate_queues(s); + vmxnet3_validate_interrupts(s); + return 0; } diff -Nru qemu-2.0.0~rc1+dfsg/hw/pci-host/prep.c qemu-2.0.0+dfsg/hw/pci-host/prep.c --- qemu-2.0.0~rc1+dfsg/hw/pci-host/prep.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/hw/pci-host/prep.c 2014-04-17 14:26:44.000000000 +0000 @@ -145,9 +145,9 @@ if (size == 1) { return buf[0]; } else if (size == 2) { - return lduw_p(buf); + return lduw_le_p(buf); } else if (size == 4) { - return ldl_p(buf); + return ldl_le_p(buf); } else { g_assert_not_reached(); } @@ -164,9 +164,9 @@ if (size == 1) { buf[0] = val; } else if (size == 2) { - stw_p(buf, val); + stw_le_p(buf, val); } else if (size == 4) { - stl_p(buf, val); + stl_le_p(buf, val); } else { g_assert_not_reached(); } diff -Nru qemu-2.0.0~rc1+dfsg/hw/ppc/e500.c qemu-2.0.0+dfsg/hw/ppc/e500.c --- qemu-2.0.0~rc1+dfsg/hw/ppc/e500.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/hw/ppc/e500.c 2014-04-17 14:26:44.000000000 +0000 @@ -649,7 +649,7 @@ input = (qemu_irq *)env->irq_inputs; irqs[i][OPENPIC_OUTPUT_INT] = input[PPCE500_INPUT_INT]; irqs[i][OPENPIC_OUTPUT_CINT] = input[PPCE500_INPUT_CINT]; - env->spr[SPR_BOOKE_PIR] = cs->cpu_index = i; + env->spr_cb[SPR_BOOKE_PIR].default_value = cs->cpu_index = i; env->mpic_iack = MPC8544_CCSRBAR_BASE + MPC8544_MPIC_REGS_OFFSET + 0xa0; diff -Nru qemu-2.0.0~rc1+dfsg/hw/ppc/ppc.c qemu-2.0.0+dfsg/hw/ppc/ppc.c --- qemu-2.0.0~rc1+dfsg/hw/ppc/ppc.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/hw/ppc/ppc.c 2014-04-17 14:26:44.000000000 +0000 @@ -620,6 +620,13 @@ } } +bool ppc_decr_clear_on_delivery(CPUPPCState *env) +{ + ppc_tb_t *tb_env = env->tb_env; + int flags = PPC_DECR_UNDERFLOW_TRIGGERED | PPC_DECR_UNDERFLOW_LEVEL; + return ((tb_env->flags & flags) == PPC_DECR_UNDERFLOW_TRIGGERED); +} + static inline uint32_t _cpu_ppc_load_decr(CPUPPCState *env, uint64_t next) { ppc_tb_t *tb_env = env->tb_env; @@ -677,6 +684,11 @@ ppc_set_irq(cpu, PPC_INTERRUPT_DECR, 1); } +static inline void cpu_ppc_decr_lower(PowerPCCPU *cpu) +{ + ppc_set_irq(cpu, PPC_INTERRUPT_DECR, 0); +} + static inline void cpu_ppc_hdecr_excp(PowerPCCPU *cpu) { /* Raise it */ @@ -684,11 +696,16 @@ ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 1); } +static inline void cpu_ppc_hdecr_lower(PowerPCCPU *cpu) +{ + ppc_set_irq(cpu, PPC_INTERRUPT_HDECR, 0); +} + static void __cpu_ppc_store_decr(PowerPCCPU *cpu, uint64_t *nextp, QEMUTimer *timer, - void (*raise_excp)(PowerPCCPU *), - uint32_t decr, uint32_t value, - int is_excp) + void (*raise_excp)(void *), + void (*lower_excp)(PowerPCCPU *), + uint32_t decr, uint32_t value) { CPUPPCState *env = &cpu->env; ppc_tb_t *tb_env = env->tb_env; @@ -702,59 +719,74 @@ return; } - now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); - next = now + muldiv64(value, get_ticks_per_sec(), tb_env->decr_freq); - if (is_excp) { - next += *nextp - now; + /* + * Going from 2 -> 1, 1 -> 0 or 0 -> -1 is the event to generate a DEC + * interrupt. + * + * If we get a really small DEC value, we can assume that by the time we + * handled it we should inject an interrupt already. + * + * On MSB level based DEC implementations the MSB always means the interrupt + * is pending, so raise it on those. + * + * On MSB edge based DEC implementations the MSB going from 0 -> 1 triggers + * an edge interrupt, so raise it here too. + */ + if ((value < 3) || + ((tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL) && (value & 0x80000000)) || + ((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) && (value & 0x80000000) + && !(decr & 0x80000000))) { + (*raise_excp)(cpu); + return; } - if (next == now) { - next++; + + /* On MSB level based systems a 0 for the MSB stops interrupt delivery */ + if (!(value & 0x80000000) && (tb_env->flags & PPC_DECR_UNDERFLOW_LEVEL)) { + (*lower_excp)(cpu); } + + /* Calculate the next timer event */ + now = qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL); + next = now + muldiv64(value, get_ticks_per_sec(), tb_env->decr_freq); *nextp = next; + /* Adjust timer */ timer_mod(timer, next); - - /* If we set a negative value and the decrementer was positive, raise an - * exception. - */ - if ((tb_env->flags & PPC_DECR_UNDERFLOW_TRIGGERED) - && (value & 0x80000000) - && !(decr & 0x80000000)) { - (*raise_excp)(cpu); - } } static inline void _cpu_ppc_store_decr(PowerPCCPU *cpu, uint32_t decr, - uint32_t value, int is_excp) + uint32_t value) { ppc_tb_t *tb_env = cpu->env.tb_env; __cpu_ppc_store_decr(cpu, &tb_env->decr_next, tb_env->decr_timer, - &cpu_ppc_decr_excp, decr, value, is_excp); + tb_env->decr_timer->cb, &cpu_ppc_decr_lower, decr, + value); } void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value) { PowerPCCPU *cpu = ppc_env_get_cpu(env); - _cpu_ppc_store_decr(cpu, cpu_ppc_load_decr(env), value, 0); + _cpu_ppc_store_decr(cpu, cpu_ppc_load_decr(env), value); } static void cpu_ppc_decr_cb(void *opaque) { PowerPCCPU *cpu = opaque; - _cpu_ppc_store_decr(cpu, 0x00000000, 0xFFFFFFFF, 1); + cpu_ppc_decr_excp(cpu); } static inline void _cpu_ppc_store_hdecr(PowerPCCPU *cpu, uint32_t hdecr, - uint32_t value, int is_excp) + uint32_t value) { ppc_tb_t *tb_env = cpu->env.tb_env; if (tb_env->hdecr_timer != NULL) { __cpu_ppc_store_decr(cpu, &tb_env->hdecr_next, tb_env->hdecr_timer, - &cpu_ppc_hdecr_excp, hdecr, value, is_excp); + tb_env->hdecr_timer->cb, &cpu_ppc_hdecr_lower, + hdecr, value); } } @@ -762,14 +794,14 @@ { PowerPCCPU *cpu = ppc_env_get_cpu(env); - _cpu_ppc_store_hdecr(cpu, cpu_ppc_load_hdecr(env), value, 0); + _cpu_ppc_store_hdecr(cpu, cpu_ppc_load_hdecr(env), value); } static void cpu_ppc_hdecr_cb(void *opaque) { PowerPCCPU *cpu = opaque; - _cpu_ppc_store_hdecr(cpu, 0x00000000, 0xFFFFFFFF, 1); + cpu_ppc_hdecr_excp(cpu); } static void cpu_ppc_store_purr(PowerPCCPU *cpu, uint64_t value) @@ -792,8 +824,8 @@ * if a decrementer exception is pending when it enables msr_ee at startup, * it's not ready to handle it... */ - _cpu_ppc_store_decr(cpu, 0xFFFFFFFF, 0xFFFFFFFF, 0); - _cpu_ppc_store_hdecr(cpu, 0xFFFFFFFF, 0xFFFFFFFF, 0); + _cpu_ppc_store_decr(cpu, 0xFFFFFFFF, 0xFFFFFFFF); + _cpu_ppc_store_hdecr(cpu, 0xFFFFFFFF, 0xFFFFFFFF); cpu_ppc_store_purr(cpu, 0x0000000000000000ULL); } @@ -806,6 +838,10 @@ tb_env = g_malloc0(sizeof(ppc_tb_t)); env->tb_env = tb_env; tb_env->flags = PPC_DECR_UNDERFLOW_TRIGGERED; + if (env->insns_flags & PPC_SEGMENT_64B) { + /* All Book3S 64bit CPUs implement level based DEC logic */ + tb_env->flags |= PPC_DECR_UNDERFLOW_LEVEL; + } /* Create new timer */ tb_env->decr_timer = timer_new_ns(QEMU_CLOCK_VIRTUAL, &cpu_ppc_decr_cb, cpu); if (0) { diff -Nru qemu-2.0.0~rc1+dfsg/hw/ppc/ppce500_spin.c qemu-2.0.0+dfsg/hw/ppc/ppce500_spin.c --- qemu-2.0.0~rc1+dfsg/hw/ppc/ppce500_spin.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/hw/ppc/ppce500_spin.c 2014-04-17 14:26:44.000000000 +0000 @@ -65,9 +65,9 @@ for (i = 0; i < MAX_CPUS; i++) { SpinInfo *info = &s->spin[i]; - info->pir = i; - info->r3 = i; - info->addr = 1; + stl_p(&info->pir, i); + stq_p(&info->r3, i); + stq_p(&info->addr, 1); } } diff -Nru qemu-2.0.0~rc1+dfsg/include/block/block.h qemu-2.0.0+dfsg/include/block/block.h --- qemu-2.0.0~rc1+dfsg/include/block/block.h 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/include/block/block.h 2014-04-17 14:26:44.000000000 +0000 @@ -190,6 +190,7 @@ QDict *options, const char *bdref_key, int flags, bool allow_none, Error **errp); int bdrv_open_backing_file(BlockDriverState *bs, QDict *options, Error **errp); +void bdrv_append_temp_snapshot(BlockDriverState *bs, Error **errp); int bdrv_open(BlockDriverState **pbs, const char *filename, const char *reference, QDict *options, int flags, BlockDriver *drv, Error **errp); diff -Nru qemu-2.0.0~rc1+dfsg/include/fpu/softfloat.h qemu-2.0.0+dfsg/include/fpu/softfloat.h --- qemu-2.0.0~rc1+dfsg/include/fpu/softfloat.h 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/include/fpu/softfloat.h 2014-04-17 14:26:44.000000000 +0000 @@ -342,6 +342,7 @@ uint32 float32_to_uint32_round_to_zero( float32 STATUS_PARAM ); int64 float32_to_int64( float32 STATUS_PARAM ); uint64 float32_to_uint64(float32 STATUS_PARAM); +uint64 float32_to_uint64_round_to_zero(float32 STATUS_PARAM); int64 float32_to_int64_round_to_zero( float32 STATUS_PARAM ); float64 float32_to_float64( float32 STATUS_PARAM ); floatx80 float32_to_floatx80( float32 STATUS_PARAM ); diff -Nru qemu-2.0.0~rc1+dfsg/include/hw/fw-path-provider.h qemu-2.0.0+dfsg/include/hw/fw-path-provider.h --- qemu-2.0.0~rc1+dfsg/include/hw/fw-path-provider.h 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/include/hw/fw-path-provider.h 2014-04-17 14:26:44.000000000 +0000 @@ -3,7 +3,8 @@ * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; under version 2 of the License. + * the Free Software Foundation; either version 2 of the License, + * or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of diff -Nru qemu-2.0.0~rc1+dfsg/include/hw/ppc/ppc.h qemu-2.0.0+dfsg/include/hw/ppc/ppc.h --- qemu-2.0.0~rc1+dfsg/include/hw/ppc/ppc.h 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/include/hw/ppc/ppc.h 2014-04-17 14:26:44.000000000 +0000 @@ -44,6 +44,9 @@ #define PPC_DECR_ZERO_TRIGGERED (1 << 3) /* Decr interrupt triggered when * the decrementer reaches zero. */ +#define PPC_DECR_UNDERFLOW_LEVEL (1 << 4) /* Decr interrupt active when + * the most significant bit is 1. + */ uint64_t cpu_ppc_get_tb(ppc_tb_t *tb_env, uint64_t vmclk, int64_t tb_offset); clk_setup_cb cpu_ppc_tb_init (CPUPPCState *env, uint32_t freq); diff -Nru qemu-2.0.0~rc1+dfsg/include/sysemu/iothread.h qemu-2.0.0+dfsg/include/sysemu/iothread.h --- qemu-2.0.0~rc1+dfsg/include/sysemu/iothread.h 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/include/sysemu/iothread.h 2014-04-17 14:26:44.000000000 +0000 @@ -15,10 +15,20 @@ #define IOTHREAD_H #include "block/aio.h" +#include "qemu/thread.h" #define TYPE_IOTHREAD "iothread" -typedef struct IOThread IOThread; +typedef struct { + Object parent_obj; + + QemuThread thread; + AioContext *ctx; + QemuMutex init_done_lock; + QemuCond init_done_cond; /* is thread initialization done? */ + bool stopping; + int thread_id; +} IOThread; #define IOTHREAD(obj) \ OBJECT_CHECK(IOThread, obj, TYPE_IOTHREAD) diff -Nru qemu-2.0.0~rc1+dfsg/iothread.c qemu-2.0.0+dfsg/iothread.c --- qemu-2.0.0~rc1+dfsg/iothread.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/iothread.c 2014-04-17 14:26:44.000000000 +0000 @@ -14,7 +14,6 @@ #include "qom/object.h" #include "qom/object_interfaces.h" #include "qemu/module.h" -#include "qemu/thread.h" #include "block/aio.h" #include "sysemu/iothread.h" #include "qmp-commands.h" @@ -22,16 +21,6 @@ #define IOTHREADS_PATH "/objects" typedef ObjectClass IOThreadClass; -struct IOThread { - Object parent_obj; - - QemuThread thread; - AioContext *ctx; - QemuMutex init_done_lock; - QemuCond init_done_cond; /* is thread initialization done? */ - bool stopping; - int thread_id; -}; #define IOTHREAD_GET_CLASS(obj) \ OBJECT_GET_CLASS(IOThreadClass, obj, TYPE_IOTHREAD) diff -Nru qemu-2.0.0~rc1+dfsg/kvm-all.c qemu-2.0.0+dfsg/kvm-all.c --- qemu-2.0.0~rc1+dfsg/kvm-all.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/kvm-all.c 2014-04-17 14:26:44.000000000 +0000 @@ -441,7 +441,7 @@ d.slot = mem->slot; - if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) < 0) { + if (kvm_vm_ioctl(s, KVM_GET_DIRTY_LOG, &d) == -1) { DPRINTF("ioctl failed %d\n", errno); ret = -1; break; diff -Nru qemu-2.0.0~rc1+dfsg/MAINTAINERS qemu-2.0.0+dfsg/MAINTAINERS --- qemu-2.0.0~rc1+dfsg/MAINTAINERS 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/MAINTAINERS 2014-04-17 14:26:43.000000000 +0000 @@ -717,7 +717,8 @@ Graphics M: Anthony Liguori -S: Maintained +M: Gerd Hoffmann +S: Odd Fixes F: ui/ Cocoa graphics diff -Nru qemu-2.0.0~rc1+dfsg/Makefile qemu-2.0.0+dfsg/Makefile --- qemu-2.0.0~rc1+dfsg/Makefile 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/Makefile 2014-04-17 14:26:43.000000000 +0000 @@ -133,6 +133,7 @@ stub-obj-y \ util-obj-y \ qga-obj-y \ + qga-vss-dll-obj-y \ block-obj-y \ block-obj-m \ common-obj-y \ @@ -376,7 +377,7 @@ ifneq ($(CONFIG_MODULES),) $(INSTALL_DIR) "$(DESTDIR)$(qemu_moddir)" for s in $(patsubst %.mo,%$(DSOSUF),$(modules-m)); do \ - $(INSTALL_PROG) $(STRIP_OPT) $$s "$(DESTDIR)$(qemu_moddir)/$${s//\//-}"; \ + $(INSTALL_PROG) $(STRIP_OPT) $$s "$(DESTDIR)$(qemu_moddir)/$$(echo $$s | tr / -)"; \ done endif ifneq ($(HELPERS-y),) diff -Nru qemu-2.0.0~rc1+dfsg/pc-bios/README qemu-2.0.0+dfsg/pc-bios/README --- qemu-2.0.0~rc1+dfsg/pc-bios/README 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/pc-bios/README 2014-04-17 14:26:44.000000000 +0000 @@ -17,7 +17,7 @@ - SLOF (Slimline Open Firmware) is a free IEEE 1275 Open Firmware implementation for certain IBM POWER hardware. The sources are at https://github.com/aik/SLOF, and the image currently in qemu is - built from git tag qemu-slof-20140304. + built from git tag qemu-slof-20140404. - sgabios (the Serial Graphics Adapter option ROM) provides a means for legacy x86 software to communicate with an attached serial console as diff -Nru qemu-2.0.0~rc1+dfsg/qga/vss-win32/install.cpp qemu-2.0.0+dfsg/qga/vss-win32/install.cpp --- qemu-2.0.0~rc1+dfsg/qga/vss-win32/install.cpp 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/qga/vss-win32/install.cpp 2014-04-17 14:26:44.000000000 +0000 @@ -75,10 +75,13 @@ #define chk(status) _chk(hr, status, "Failed to " #status, out) +#if !defined(__MINGW64_VERSION_MAJOR) || !defined(__MINGW64_VERSION_MINOR) || \ + __MINGW64_VERSION_MAJOR * 100 + __MINGW64_VERSION_MINOR < 301 void __stdcall _com_issue_error(HRESULT hr) { errmsg(hr, "Unexpected error in COM"); } +#endif template HRESULT put_Value(ICatalogObject *pObj, LPCWSTR name, T val) diff -Nru qemu-2.0.0~rc1+dfsg/qom/object.c qemu-2.0.0+dfsg/qom/object.c --- qemu-2.0.0~rc1+dfsg/qom/object.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/qom/object.c 2014-04-17 14:26:44.000000000 +0000 @@ -1225,7 +1225,8 @@ } if (object_property_is_link(prop)) { - return *(Object **)prop->opaque; + LinkProperty *lprop = prop->opaque; + return *lprop->child; } else if (object_property_is_child(prop)) { return prop->opaque; } else { diff -Nru qemu-2.0.0~rc1+dfsg/target-i386/machine.c qemu-2.0.0+dfsg/target-i386/machine.c --- qemu-2.0.0~rc1+dfsg/target-i386/machine.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/target-i386/machine.c 2014-04-17 14:26:44.000000000 +0000 @@ -569,8 +569,8 @@ .minimum_version_id = 1, .minimum_version_id_old = 1, .fields = (VMStateField []) { - VMSTATE_UINT64(env.msr_hv_hypercall, X86CPU), VMSTATE_UINT64(env.msr_hv_guest_os_id, X86CPU), + VMSTATE_UINT64(env.msr_hv_hypercall, X86CPU), VMSTATE_END_OF_LIST() } }; diff -Nru qemu-2.0.0~rc1+dfsg/target-ppc/cpu.h qemu-2.0.0+dfsg/target-ppc/cpu.h --- qemu-2.0.0~rc1+dfsg/target-ppc/cpu.h 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/target-ppc/cpu.h 2014-04-17 14:26:44.000000000 +0000 @@ -1133,6 +1133,7 @@ uint32_t cpu_ppc_load_atbu (CPUPPCState *env); void cpu_ppc_store_atbl (CPUPPCState *env, uint32_t value); void cpu_ppc_store_atbu (CPUPPCState *env, uint32_t value); +bool ppc_decr_clear_on_delivery(CPUPPCState *env); uint32_t cpu_ppc_load_decr (CPUPPCState *env); void cpu_ppc_store_decr (CPUPPCState *env, uint32_t value); uint32_t cpu_ppc_load_hdecr (CPUPPCState *env); diff -Nru qemu-2.0.0~rc1+dfsg/target-ppc/excp_helper.c qemu-2.0.0+dfsg/target-ppc/excp_helper.c --- qemu-2.0.0~rc1+dfsg/target-ppc/excp_helper.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/target-ppc/excp_helper.c 2014-04-17 14:26:44.000000000 +0000 @@ -723,7 +723,6 @@ if ((msr_ee != 0 || msr_hv == 0 || msr_pr != 0) && hdice != 0) { /* Hypervisor decrementer exception */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_HDECR)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_HDECR); powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_HDECR); return; } @@ -767,7 +766,9 @@ } /* Decrementer exception */ if (env->pending_interrupts & (1 << PPC_INTERRUPT_DECR)) { - env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR); + if (ppc_decr_clear_on_delivery(env)) { + env->pending_interrupts &= ~(1 << PPC_INTERRUPT_DECR); + } powerpc_excp(cpu, env->excp_model, POWERPC_EXCP_DECR); return; } diff -Nru qemu-2.0.0~rc1+dfsg/target-ppc/fpu_helper.c qemu-2.0.0+dfsg/target-ppc/fpu_helper.c --- qemu-2.0.0~rc1+dfsg/target-ppc/fpu_helper.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/target-ppc/fpu_helper.c 2014-04-17 14:26:44.000000000 +0000 @@ -1782,11 +1782,19 @@ float64 f64[2]; } ppc_vsr_t; +#if defined(HOST_WORDS_BIGENDIAN) +#define VsrW(i) u32[i] +#define VsrD(i) u64[i] +#else +#define VsrW(i) u32[3-(i)] +#define VsrD(i) u64[1-(i)] +#endif + static void getVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env) { if (n < 32) { - vsr->f64[0] = env->fpr[n]; - vsr->u64[1] = env->vsr[n]; + vsr->VsrD(0) = env->fpr[n]; + vsr->VsrD(1) = env->vsr[n]; } else { vsr->u64[0] = env->avr[n-32].u64[0]; vsr->u64[1] = env->avr[n-32].u64[1]; @@ -1796,8 +1804,8 @@ static void putVSR(int n, ppc_vsr_t *vsr, CPUPPCState *env) { if (n < 32) { - env->fpr[n] = vsr->f64[0]; - env->vsr[n] = vsr->u64[1]; + env->fpr[n] = vsr->VsrD(0); + env->vsr[n] = vsr->VsrD(1); } else { env->avr[n-32].u64[0] = vsr->u64[0]; env->avr[n-32].u64[1] = vsr->u64[1]; @@ -1812,7 +1820,7 @@ * op - operation (add or sub) * nels - number of elements (1, 2 or 4) * tp - type (float32 or float64) - * fld - vsr_t field (f32 or f64) + * fld - vsr_t field (VsrD(*) or VsrW(*)) * sfprf - set FPRF */ #define VSX_ADD_SUB(name, op, nels, tp, fld, sfprf, r2sp) \ @@ -1829,44 +1837,44 @@ for (i = 0; i < nels; i++) { \ float_status tstat = env->fp_status; \ set_float_exception_flags(0, &tstat); \ - xt.fld[i] = tp##_##op(xa.fld[i], xb.fld[i], &tstat); \ + xt.fld = tp##_##op(xa.fld, xb.fld, &tstat); \ env->fp_status.float_exception_flags |= tstat.float_exception_flags; \ \ if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ - if (tp##_is_infinity(xa.fld[i]) && tp##_is_infinity(xb.fld[i])) {\ + if (tp##_is_infinity(xa.fld) && tp##_is_infinity(xb.fld)) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf); \ - } else if (tp##_is_signaling_nan(xa.fld[i]) || \ - tp##_is_signaling_nan(xb.fld[i])) { \ + } else if (tp##_is_signaling_nan(xa.fld) || \ + tp##_is_signaling_nan(xb.fld)) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ } \ } \ \ if (r2sp) { \ - xt.fld[i] = helper_frsp(env, xt.fld[i]); \ + xt.fld = helper_frsp(env, xt.fld); \ } \ \ if (sfprf) { \ - helper_compute_fprf(env, xt.fld[i], sfprf); \ + helper_compute_fprf(env, xt.fld, sfprf); \ } \ } \ putVSR(xT(opcode), &xt, env); \ helper_float_check_status(env); \ } -VSX_ADD_SUB(xsadddp, add, 1, float64, f64, 1, 0) -VSX_ADD_SUB(xsaddsp, add, 1, float64, f64, 1, 1) -VSX_ADD_SUB(xvadddp, add, 2, float64, f64, 0, 0) -VSX_ADD_SUB(xvaddsp, add, 4, float32, f32, 0, 0) -VSX_ADD_SUB(xssubdp, sub, 1, float64, f64, 1, 0) -VSX_ADD_SUB(xssubsp, sub, 1, float64, f64, 1, 1) -VSX_ADD_SUB(xvsubdp, sub, 2, float64, f64, 0, 0) -VSX_ADD_SUB(xvsubsp, sub, 4, float32, f32, 0, 0) +VSX_ADD_SUB(xsadddp, add, 1, float64, VsrD(0), 1, 0) +VSX_ADD_SUB(xsaddsp, add, 1, float64, VsrD(0), 1, 1) +VSX_ADD_SUB(xvadddp, add, 2, float64, VsrD(i), 0, 0) +VSX_ADD_SUB(xvaddsp, add, 4, float32, VsrW(i), 0, 0) +VSX_ADD_SUB(xssubdp, sub, 1, float64, VsrD(0), 1, 0) +VSX_ADD_SUB(xssubsp, sub, 1, float64, VsrD(0), 1, 1) +VSX_ADD_SUB(xvsubdp, sub, 2, float64, VsrD(i), 0, 0) +VSX_ADD_SUB(xvsubsp, sub, 4, float32, VsrW(i), 0, 0) /* VSX_MUL - VSX floating point multiply * op - instruction mnemonic * nels - number of elements (1, 2 or 4) * tp - type (float32 or float64) - * fld - vsr_t field (f32 or f64) + * fld - vsr_t field (VsrD(*) or VsrW(*)) * sfprf - set FPRF */ #define VSX_MUL(op, nels, tp, fld, sfprf, r2sp) \ @@ -1883,25 +1891,25 @@ for (i = 0; i < nels; i++) { \ float_status tstat = env->fp_status; \ set_float_exception_flags(0, &tstat); \ - xt.fld[i] = tp##_mul(xa.fld[i], xb.fld[i], &tstat); \ + xt.fld = tp##_mul(xa.fld, xb.fld, &tstat); \ env->fp_status.float_exception_flags |= tstat.float_exception_flags; \ \ if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ - if ((tp##_is_infinity(xa.fld[i]) && tp##_is_zero(xb.fld[i])) || \ - (tp##_is_infinity(xb.fld[i]) && tp##_is_zero(xa.fld[i]))) { \ + if ((tp##_is_infinity(xa.fld) && tp##_is_zero(xb.fld)) || \ + (tp##_is_infinity(xb.fld) && tp##_is_zero(xa.fld))) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIMZ, sfprf); \ - } else if (tp##_is_signaling_nan(xa.fld[i]) || \ - tp##_is_signaling_nan(xb.fld[i])) { \ + } else if (tp##_is_signaling_nan(xa.fld) || \ + tp##_is_signaling_nan(xb.fld)) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ } \ } \ \ if (r2sp) { \ - xt.fld[i] = helper_frsp(env, xt.fld[i]); \ + xt.fld = helper_frsp(env, xt.fld); \ } \ \ if (sfprf) { \ - helper_compute_fprf(env, xt.fld[i], sfprf); \ + helper_compute_fprf(env, xt.fld, sfprf); \ } \ } \ \ @@ -1909,16 +1917,16 @@ helper_float_check_status(env); \ } -VSX_MUL(xsmuldp, 1, float64, f64, 1, 0) -VSX_MUL(xsmulsp, 1, float64, f64, 1, 1) -VSX_MUL(xvmuldp, 2, float64, f64, 0, 0) -VSX_MUL(xvmulsp, 4, float32, f32, 0, 0) +VSX_MUL(xsmuldp, 1, float64, VsrD(0), 1, 0) +VSX_MUL(xsmulsp, 1, float64, VsrD(0), 1, 1) +VSX_MUL(xvmuldp, 2, float64, VsrD(i), 0, 0) +VSX_MUL(xvmulsp, 4, float32, VsrW(i), 0, 0) /* VSX_DIV - VSX floating point divide * op - instruction mnemonic * nels - number of elements (1, 2 or 4) * tp - type (float32 or float64) - * fld - vsr_t field (f32 or f64) + * fld - vsr_t field (VsrD(*) or VsrW(*)) * sfprf - set FPRF */ #define VSX_DIV(op, nels, tp, fld, sfprf, r2sp) \ @@ -1935,27 +1943,27 @@ for (i = 0; i < nels; i++) { \ float_status tstat = env->fp_status; \ set_float_exception_flags(0, &tstat); \ - xt.fld[i] = tp##_div(xa.fld[i], xb.fld[i], &tstat); \ + xt.fld = tp##_div(xa.fld, xb.fld, &tstat); \ env->fp_status.float_exception_flags |= tstat.float_exception_flags; \ \ if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ - if (tp##_is_infinity(xa.fld[i]) && tp##_is_infinity(xb.fld[i])) { \ + if (tp##_is_infinity(xa.fld) && tp##_is_infinity(xb.fld)) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXIDI, sfprf); \ - } else if (tp##_is_zero(xa.fld[i]) && \ - tp##_is_zero(xb.fld[i])) { \ + } else if (tp##_is_zero(xa.fld) && \ + tp##_is_zero(xb.fld)) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXZDZ, sfprf); \ - } else if (tp##_is_signaling_nan(xa.fld[i]) || \ - tp##_is_signaling_nan(xb.fld[i])) { \ + } else if (tp##_is_signaling_nan(xa.fld) || \ + tp##_is_signaling_nan(xb.fld)) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ } \ } \ \ if (r2sp) { \ - xt.fld[i] = helper_frsp(env, xt.fld[i]); \ + xt.fld = helper_frsp(env, xt.fld); \ } \ \ if (sfprf) { \ - helper_compute_fprf(env, xt.fld[i], sfprf); \ + helper_compute_fprf(env, xt.fld, sfprf); \ } \ } \ \ @@ -1963,16 +1971,16 @@ helper_float_check_status(env); \ } -VSX_DIV(xsdivdp, 1, float64, f64, 1, 0) -VSX_DIV(xsdivsp, 1, float64, f64, 1, 1) -VSX_DIV(xvdivdp, 2, float64, f64, 0, 0) -VSX_DIV(xvdivsp, 4, float32, f32, 0, 0) +VSX_DIV(xsdivdp, 1, float64, VsrD(0), 1, 0) +VSX_DIV(xsdivsp, 1, float64, VsrD(0), 1, 1) +VSX_DIV(xvdivdp, 2, float64, VsrD(i), 0, 0) +VSX_DIV(xvdivsp, 4, float32, VsrW(i), 0, 0) /* VSX_RE - VSX floating point reciprocal estimate * op - instruction mnemonic * nels - number of elements (1, 2 or 4) * tp - type (float32 or float64) - * fld - vsr_t field (f32 or f64) + * fld - vsr_t field (VsrD(*) or VsrW(*)) * sfprf - set FPRF */ #define VSX_RE(op, nels, tp, fld, sfprf, r2sp) \ @@ -1986,17 +1994,17 @@ helper_reset_fpstatus(env); \ \ for (i = 0; i < nels; i++) { \ - if (unlikely(tp##_is_signaling_nan(xb.fld[i]))) { \ + if (unlikely(tp##_is_signaling_nan(xb.fld))) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ } \ - xt.fld[i] = tp##_div(tp##_one, xb.fld[i], &env->fp_status); \ + xt.fld = tp##_div(tp##_one, xb.fld, &env->fp_status); \ \ if (r2sp) { \ - xt.fld[i] = helper_frsp(env, xt.fld[i]); \ + xt.fld = helper_frsp(env, xt.fld); \ } \ \ if (sfprf) { \ - helper_compute_fprf(env, xt.fld[0], sfprf); \ + helper_compute_fprf(env, xt.fld, sfprf); \ } \ } \ \ @@ -2004,16 +2012,16 @@ helper_float_check_status(env); \ } -VSX_RE(xsredp, 1, float64, f64, 1, 0) -VSX_RE(xsresp, 1, float64, f64, 1, 1) -VSX_RE(xvredp, 2, float64, f64, 0, 0) -VSX_RE(xvresp, 4, float32, f32, 0, 0) +VSX_RE(xsredp, 1, float64, VsrD(0), 1, 0) +VSX_RE(xsresp, 1, float64, VsrD(0), 1, 1) +VSX_RE(xvredp, 2, float64, VsrD(i), 0, 0) +VSX_RE(xvresp, 4, float32, VsrW(i), 0, 0) /* VSX_SQRT - VSX floating point square root * op - instruction mnemonic * nels - number of elements (1, 2 or 4) * tp - type (float32 or float64) - * fld - vsr_t field (f32 or f64) + * fld - vsr_t field (VsrD(*) or VsrW(*)) * sfprf - set FPRF */ #define VSX_SQRT(op, nels, tp, fld, sfprf, r2sp) \ @@ -2029,23 +2037,23 @@ for (i = 0; i < nels; i++) { \ float_status tstat = env->fp_status; \ set_float_exception_flags(0, &tstat); \ - xt.fld[i] = tp##_sqrt(xb.fld[i], &tstat); \ + xt.fld = tp##_sqrt(xb.fld, &tstat); \ env->fp_status.float_exception_flags |= tstat.float_exception_flags; \ \ if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ - if (tp##_is_neg(xb.fld[i]) && !tp##_is_zero(xb.fld[i])) { \ + if (tp##_is_neg(xb.fld) && !tp##_is_zero(xb.fld)) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf); \ - } else if (tp##_is_signaling_nan(xb.fld[i])) { \ + } else if (tp##_is_signaling_nan(xb.fld)) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ } \ } \ \ if (r2sp) { \ - xt.fld[i] = helper_frsp(env, xt.fld[i]); \ + xt.fld = helper_frsp(env, xt.fld); \ } \ \ if (sfprf) { \ - helper_compute_fprf(env, xt.fld[i], sfprf); \ + helper_compute_fprf(env, xt.fld, sfprf); \ } \ } \ \ @@ -2053,16 +2061,16 @@ helper_float_check_status(env); \ } -VSX_SQRT(xssqrtdp, 1, float64, f64, 1, 0) -VSX_SQRT(xssqrtsp, 1, float64, f64, 1, 1) -VSX_SQRT(xvsqrtdp, 2, float64, f64, 0, 0) -VSX_SQRT(xvsqrtsp, 4, float32, f32, 0, 0) +VSX_SQRT(xssqrtdp, 1, float64, VsrD(0), 1, 0) +VSX_SQRT(xssqrtsp, 1, float64, VsrD(0), 1, 1) +VSX_SQRT(xvsqrtdp, 2, float64, VsrD(i), 0, 0) +VSX_SQRT(xvsqrtsp, 4, float32, VsrW(i), 0, 0) /* VSX_RSQRTE - VSX floating point reciprocal square root estimate * op - instruction mnemonic * nels - number of elements (1, 2 or 4) * tp - type (float32 or float64) - * fld - vsr_t field (f32 or f64) + * fld - vsr_t field (VsrD(*) or VsrW(*)) * sfprf - set FPRF */ #define VSX_RSQRTE(op, nels, tp, fld, sfprf, r2sp) \ @@ -2078,24 +2086,24 @@ for (i = 0; i < nels; i++) { \ float_status tstat = env->fp_status; \ set_float_exception_flags(0, &tstat); \ - xt.fld[i] = tp##_sqrt(xb.fld[i], &tstat); \ - xt.fld[i] = tp##_div(tp##_one, xt.fld[i], &tstat); \ + xt.fld = tp##_sqrt(xb.fld, &tstat); \ + xt.fld = tp##_div(tp##_one, xt.fld, &tstat); \ env->fp_status.float_exception_flags |= tstat.float_exception_flags; \ \ if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ - if (tp##_is_neg(xb.fld[i]) && !tp##_is_zero(xb.fld[i])) { \ + if (tp##_is_neg(xb.fld) && !tp##_is_zero(xb.fld)) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSQRT, sfprf); \ - } else if (tp##_is_signaling_nan(xb.fld[i])) { \ + } else if (tp##_is_signaling_nan(xb.fld)) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ } \ } \ \ if (r2sp) { \ - xt.fld[i] = helper_frsp(env, xt.fld[i]); \ + xt.fld = helper_frsp(env, xt.fld); \ } \ \ if (sfprf) { \ - helper_compute_fprf(env, xt.fld[i], sfprf); \ + helper_compute_fprf(env, xt.fld, sfprf); \ } \ } \ \ @@ -2103,16 +2111,16 @@ helper_float_check_status(env); \ } -VSX_RSQRTE(xsrsqrtedp, 1, float64, f64, 1, 0) -VSX_RSQRTE(xsrsqrtesp, 1, float64, f64, 1, 1) -VSX_RSQRTE(xvrsqrtedp, 2, float64, f64, 0, 0) -VSX_RSQRTE(xvrsqrtesp, 4, float32, f32, 0, 0) +VSX_RSQRTE(xsrsqrtedp, 1, float64, VsrD(0), 1, 0) +VSX_RSQRTE(xsrsqrtesp, 1, float64, VsrD(0), 1, 1) +VSX_RSQRTE(xvrsqrtedp, 2, float64, VsrD(i), 0, 0) +VSX_RSQRTE(xvrsqrtesp, 4, float32, VsrW(i), 0, 0) /* VSX_TDIV - VSX floating point test for divide * op - instruction mnemonic * nels - number of elements (1, 2 or 4) * tp - type (float32 or float64) - * fld - vsr_t field (f32 or f64) + * fld - vsr_t field (VsrD(*) or VsrW(*)) * emin - minimum unbiased exponent * emax - maximum unbiased exponent * nbits - number of fraction bits @@ -2129,28 +2137,28 @@ getVSR(xB(opcode), &xb, env); \ \ for (i = 0; i < nels; i++) { \ - if (unlikely(tp##_is_infinity(xa.fld[i]) || \ - tp##_is_infinity(xb.fld[i]) || \ - tp##_is_zero(xb.fld[i]))) { \ + if (unlikely(tp##_is_infinity(xa.fld) || \ + tp##_is_infinity(xb.fld) || \ + tp##_is_zero(xb.fld))) { \ fe_flag = 1; \ fg_flag = 1; \ } else { \ - int e_a = ppc_##tp##_get_unbiased_exp(xa.fld[i]); \ - int e_b = ppc_##tp##_get_unbiased_exp(xb.fld[i]); \ + int e_a = ppc_##tp##_get_unbiased_exp(xa.fld); \ + int e_b = ppc_##tp##_get_unbiased_exp(xb.fld); \ \ - if (unlikely(tp##_is_any_nan(xa.fld[i]) || \ - tp##_is_any_nan(xb.fld[i]))) { \ + if (unlikely(tp##_is_any_nan(xa.fld) || \ + tp##_is_any_nan(xb.fld))) { \ fe_flag = 1; \ } else if ((e_b <= emin) || (e_b >= (emax-2))) { \ fe_flag = 1; \ - } else if (!tp##_is_zero(xa.fld[i]) && \ + } else if (!tp##_is_zero(xa.fld) && \ (((e_a - e_b) >= emax) || \ ((e_a - e_b) <= (emin+1)) || \ (e_a <= (emin+nbits)))) { \ fe_flag = 1; \ } \ \ - if (unlikely(tp##_is_zero_or_denormal(xb.fld[i]))) { \ + if (unlikely(tp##_is_zero_or_denormal(xb.fld))) { \ /* XB is not zero because of the above check and */ \ /* so must be denormalized. */ \ fg_flag = 1; \ @@ -2161,15 +2169,15 @@ env->crf[BF(opcode)] = 0x8 | (fg_flag ? 4 : 0) | (fe_flag ? 2 : 0); \ } -VSX_TDIV(xstdivdp, 1, float64, f64, -1022, 1023, 52) -VSX_TDIV(xvtdivdp, 2, float64, f64, -1022, 1023, 52) -VSX_TDIV(xvtdivsp, 4, float32, f32, -126, 127, 23) +VSX_TDIV(xstdivdp, 1, float64, VsrD(0), -1022, 1023, 52) +VSX_TDIV(xvtdivdp, 2, float64, VsrD(i), -1022, 1023, 52) +VSX_TDIV(xvtdivsp, 4, float32, VsrW(i), -126, 127, 23) /* VSX_TSQRT - VSX floating point test for square root * op - instruction mnemonic * nels - number of elements (1, 2 or 4) * tp - type (float32 or float64) - * fld - vsr_t field (f32 or f64) + * fld - vsr_t field (VsrD(*) or VsrW(*)) * emin - minimum unbiased exponent * emax - maximum unbiased exponent * nbits - number of fraction bits @@ -2186,25 +2194,25 @@ getVSR(xB(opcode), &xb, env); \ \ for (i = 0; i < nels; i++) { \ - if (unlikely(tp##_is_infinity(xb.fld[i]) || \ - tp##_is_zero(xb.fld[i]))) { \ + if (unlikely(tp##_is_infinity(xb.fld) || \ + tp##_is_zero(xb.fld))) { \ fe_flag = 1; \ fg_flag = 1; \ } else { \ - int e_b = ppc_##tp##_get_unbiased_exp(xb.fld[i]); \ + int e_b = ppc_##tp##_get_unbiased_exp(xb.fld); \ \ - if (unlikely(tp##_is_any_nan(xb.fld[i]))) { \ + if (unlikely(tp##_is_any_nan(xb.fld))) { \ fe_flag = 1; \ - } else if (unlikely(tp##_is_zero(xb.fld[i]))) { \ + } else if (unlikely(tp##_is_zero(xb.fld))) { \ fe_flag = 1; \ - } else if (unlikely(tp##_is_neg(xb.fld[i]))) { \ + } else if (unlikely(tp##_is_neg(xb.fld))) { \ fe_flag = 1; \ - } else if (!tp##_is_zero(xb.fld[i]) && \ + } else if (!tp##_is_zero(xb.fld) && \ (e_b <= (emin+nbits))) { \ fe_flag = 1; \ } \ \ - if (unlikely(tp##_is_zero_or_denormal(xb.fld[i]))) { \ + if (unlikely(tp##_is_zero_or_denormal(xb.fld))) { \ /* XB is not zero because of the above check and */ \ /* therefore must be denormalized. */ \ fg_flag = 1; \ @@ -2215,15 +2223,15 @@ env->crf[BF(opcode)] = 0x8 | (fg_flag ? 4 : 0) | (fe_flag ? 2 : 0); \ } -VSX_TSQRT(xstsqrtdp, 1, float64, f64, -1022, 52) -VSX_TSQRT(xvtsqrtdp, 2, float64, f64, -1022, 52) -VSX_TSQRT(xvtsqrtsp, 4, float32, f32, -126, 23) +VSX_TSQRT(xstsqrtdp, 1, float64, VsrD(0), -1022, 52) +VSX_TSQRT(xvtsqrtdp, 2, float64, VsrD(i), -1022, 52) +VSX_TSQRT(xvtsqrtsp, 4, float32, VsrW(i), -126, 23) /* VSX_MADD - VSX floating point muliply/add variations * op - instruction mnemonic * nels - number of elements (1, 2 or 4) * tp - type (float32 or float64) - * fld - vsr_t field (f32 or f64) + * fld - vsr_t field (VsrD(*) or VsrW(*)) * maddflgs - flags for the float*muladd routine that control the * various forms (madd, msub, nmadd, nmsub) * afrm - A form (1=A, 0=M) @@ -2259,43 +2267,43 @@ /* Avoid double rounding errors by rounding the intermediate */ \ /* result to odd. */ \ set_float_rounding_mode(float_round_to_zero, &tstat); \ - xt_out.fld[i] = tp##_muladd(xa.fld[i], b->fld[i], c->fld[i], \ + xt_out.fld = tp##_muladd(xa.fld, b->fld, c->fld, \ maddflgs, &tstat); \ - xt_out.fld[i] |= (get_float_exception_flags(&tstat) & \ + xt_out.fld |= (get_float_exception_flags(&tstat) & \ float_flag_inexact) != 0; \ } else { \ - xt_out.fld[i] = tp##_muladd(xa.fld[i], b->fld[i], c->fld[i], \ + xt_out.fld = tp##_muladd(xa.fld, b->fld, c->fld, \ maddflgs, &tstat); \ } \ env->fp_status.float_exception_flags |= tstat.float_exception_flags; \ \ if (unlikely(tstat.float_exception_flags & float_flag_invalid)) { \ - if (tp##_is_signaling_nan(xa.fld[i]) || \ - tp##_is_signaling_nan(b->fld[i]) || \ - tp##_is_signaling_nan(c->fld[i])) { \ + if (tp##_is_signaling_nan(xa.fld) || \ + tp##_is_signaling_nan(b->fld) || \ + tp##_is_signaling_nan(c->fld)) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, sfprf); \ tstat.float_exception_flags &= ~float_flag_invalid; \ } \ - if ((tp##_is_infinity(xa.fld[i]) && tp##_is_zero(b->fld[i])) || \ - (tp##_is_zero(xa.fld[i]) && tp##_is_infinity(b->fld[i]))) { \ - xt_out.fld[i] = float64_to_##tp(fload_invalid_op_excp(env, \ + if ((tp##_is_infinity(xa.fld) && tp##_is_zero(b->fld)) || \ + (tp##_is_zero(xa.fld) && tp##_is_infinity(b->fld))) { \ + xt_out.fld = float64_to_##tp(fload_invalid_op_excp(env, \ POWERPC_EXCP_FP_VXIMZ, sfprf), &env->fp_status); \ tstat.float_exception_flags &= ~float_flag_invalid; \ } \ if ((tstat.float_exception_flags & float_flag_invalid) && \ - ((tp##_is_infinity(xa.fld[i]) || \ - tp##_is_infinity(b->fld[i])) && \ - tp##_is_infinity(c->fld[i]))) { \ + ((tp##_is_infinity(xa.fld) || \ + tp##_is_infinity(b->fld)) && \ + tp##_is_infinity(c->fld))) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXISI, sfprf); \ } \ } \ \ if (r2sp) { \ - xt_out.fld[i] = helper_frsp(env, xt_out.fld[i]); \ + xt_out.fld = helper_frsp(env, xt_out.fld); \ } \ \ if (sfprf) { \ - helper_compute_fprf(env, xt_out.fld[i], sfprf); \ + helper_compute_fprf(env, xt_out.fld, sfprf); \ } \ } \ putVSR(xT(opcode), &xt_out, env); \ @@ -2307,41 +2315,41 @@ #define NMADD_FLGS float_muladd_negate_result #define NMSUB_FLGS (float_muladd_negate_c | float_muladd_negate_result) -VSX_MADD(xsmaddadp, 1, float64, f64, MADD_FLGS, 1, 1, 0) -VSX_MADD(xsmaddmdp, 1, float64, f64, MADD_FLGS, 0, 1, 0) -VSX_MADD(xsmsubadp, 1, float64, f64, MSUB_FLGS, 1, 1, 0) -VSX_MADD(xsmsubmdp, 1, float64, f64, MSUB_FLGS, 0, 1, 0) -VSX_MADD(xsnmaddadp, 1, float64, f64, NMADD_FLGS, 1, 1, 0) -VSX_MADD(xsnmaddmdp, 1, float64, f64, NMADD_FLGS, 0, 1, 0) -VSX_MADD(xsnmsubadp, 1, float64, f64, NMSUB_FLGS, 1, 1, 0) -VSX_MADD(xsnmsubmdp, 1, float64, f64, NMSUB_FLGS, 0, 1, 0) - -VSX_MADD(xsmaddasp, 1, float64, f64, MADD_FLGS, 1, 1, 1) -VSX_MADD(xsmaddmsp, 1, float64, f64, MADD_FLGS, 0, 1, 1) -VSX_MADD(xsmsubasp, 1, float64, f64, MSUB_FLGS, 1, 1, 1) -VSX_MADD(xsmsubmsp, 1, float64, f64, MSUB_FLGS, 0, 1, 1) -VSX_MADD(xsnmaddasp, 1, float64, f64, NMADD_FLGS, 1, 1, 1) -VSX_MADD(xsnmaddmsp, 1, float64, f64, NMADD_FLGS, 0, 1, 1) -VSX_MADD(xsnmsubasp, 1, float64, f64, NMSUB_FLGS, 1, 1, 1) -VSX_MADD(xsnmsubmsp, 1, float64, f64, NMSUB_FLGS, 0, 1, 1) - -VSX_MADD(xvmaddadp, 2, float64, f64, MADD_FLGS, 1, 0, 0) -VSX_MADD(xvmaddmdp, 2, float64, f64, MADD_FLGS, 0, 0, 0) -VSX_MADD(xvmsubadp, 2, float64, f64, MSUB_FLGS, 1, 0, 0) -VSX_MADD(xvmsubmdp, 2, float64, f64, MSUB_FLGS, 0, 0, 0) -VSX_MADD(xvnmaddadp, 2, float64, f64, NMADD_FLGS, 1, 0, 0) -VSX_MADD(xvnmaddmdp, 2, float64, f64, NMADD_FLGS, 0, 0, 0) -VSX_MADD(xvnmsubadp, 2, float64, f64, NMSUB_FLGS, 1, 0, 0) -VSX_MADD(xvnmsubmdp, 2, float64, f64, NMSUB_FLGS, 0, 0, 0) - -VSX_MADD(xvmaddasp, 4, float32, f32, MADD_FLGS, 1, 0, 0) -VSX_MADD(xvmaddmsp, 4, float32, f32, MADD_FLGS, 0, 0, 0) -VSX_MADD(xvmsubasp, 4, float32, f32, MSUB_FLGS, 1, 0, 0) -VSX_MADD(xvmsubmsp, 4, float32, f32, MSUB_FLGS, 0, 0, 0) -VSX_MADD(xvnmaddasp, 4, float32, f32, NMADD_FLGS, 1, 0, 0) -VSX_MADD(xvnmaddmsp, 4, float32, f32, NMADD_FLGS, 0, 0, 0) -VSX_MADD(xvnmsubasp, 4, float32, f32, NMSUB_FLGS, 1, 0, 0) -VSX_MADD(xvnmsubmsp, 4, float32, f32, NMSUB_FLGS, 0, 0, 0) +VSX_MADD(xsmaddadp, 1, float64, VsrD(0), MADD_FLGS, 1, 1, 0) +VSX_MADD(xsmaddmdp, 1, float64, VsrD(0), MADD_FLGS, 0, 1, 0) +VSX_MADD(xsmsubadp, 1, float64, VsrD(0), MSUB_FLGS, 1, 1, 0) +VSX_MADD(xsmsubmdp, 1, float64, VsrD(0), MSUB_FLGS, 0, 1, 0) +VSX_MADD(xsnmaddadp, 1, float64, VsrD(0), NMADD_FLGS, 1, 1, 0) +VSX_MADD(xsnmaddmdp, 1, float64, VsrD(0), NMADD_FLGS, 0, 1, 0) +VSX_MADD(xsnmsubadp, 1, float64, VsrD(0), NMSUB_FLGS, 1, 1, 0) +VSX_MADD(xsnmsubmdp, 1, float64, VsrD(0), NMSUB_FLGS, 0, 1, 0) + +VSX_MADD(xsmaddasp, 1, float64, VsrD(0), MADD_FLGS, 1, 1, 1) +VSX_MADD(xsmaddmsp, 1, float64, VsrD(0), MADD_FLGS, 0, 1, 1) +VSX_MADD(xsmsubasp, 1, float64, VsrD(0), MSUB_FLGS, 1, 1, 1) +VSX_MADD(xsmsubmsp, 1, float64, VsrD(0), MSUB_FLGS, 0, 1, 1) +VSX_MADD(xsnmaddasp, 1, float64, VsrD(0), NMADD_FLGS, 1, 1, 1) +VSX_MADD(xsnmaddmsp, 1, float64, VsrD(0), NMADD_FLGS, 0, 1, 1) +VSX_MADD(xsnmsubasp, 1, float64, VsrD(0), NMSUB_FLGS, 1, 1, 1) +VSX_MADD(xsnmsubmsp, 1, float64, VsrD(0), NMSUB_FLGS, 0, 1, 1) + +VSX_MADD(xvmaddadp, 2, float64, VsrD(i), MADD_FLGS, 1, 0, 0) +VSX_MADD(xvmaddmdp, 2, float64, VsrD(i), MADD_FLGS, 0, 0, 0) +VSX_MADD(xvmsubadp, 2, float64, VsrD(i), MSUB_FLGS, 1, 0, 0) +VSX_MADD(xvmsubmdp, 2, float64, VsrD(i), MSUB_FLGS, 0, 0, 0) +VSX_MADD(xvnmaddadp, 2, float64, VsrD(i), NMADD_FLGS, 1, 0, 0) +VSX_MADD(xvnmaddmdp, 2, float64, VsrD(i), NMADD_FLGS, 0, 0, 0) +VSX_MADD(xvnmsubadp, 2, float64, VsrD(i), NMSUB_FLGS, 1, 0, 0) +VSX_MADD(xvnmsubmdp, 2, float64, VsrD(i), NMSUB_FLGS, 0, 0, 0) + +VSX_MADD(xvmaddasp, 4, float32, VsrW(i), MADD_FLGS, 1, 0, 0) +VSX_MADD(xvmaddmsp, 4, float32, VsrW(i), MADD_FLGS, 0, 0, 0) +VSX_MADD(xvmsubasp, 4, float32, VsrW(i), MSUB_FLGS, 1, 0, 0) +VSX_MADD(xvmsubmsp, 4, float32, VsrW(i), MSUB_FLGS, 0, 0, 0) +VSX_MADD(xvnmaddasp, 4, float32, VsrW(i), NMADD_FLGS, 1, 0, 0) +VSX_MADD(xvnmaddmsp, 4, float32, VsrW(i), NMADD_FLGS, 0, 0, 0) +VSX_MADD(xvnmsubasp, 4, float32, VsrW(i), NMSUB_FLGS, 1, 0, 0) +VSX_MADD(xvnmsubmsp, 4, float32, VsrW(i), NMSUB_FLGS, 0, 0, 0) #define VSX_SCALAR_CMP(op, ordered) \ void helper_##op(CPUPPCState *env, uint32_t opcode) \ @@ -2352,10 +2360,10 @@ getVSR(xA(opcode), &xa, env); \ getVSR(xB(opcode), &xb, env); \ \ - if (unlikely(float64_is_any_nan(xa.f64[0]) || \ - float64_is_any_nan(xb.f64[0]))) { \ - if (float64_is_signaling_nan(xa.f64[0]) || \ - float64_is_signaling_nan(xb.f64[0])) { \ + if (unlikely(float64_is_any_nan(xa.VsrD(0)) || \ + float64_is_any_nan(xb.VsrD(0)))) { \ + if (float64_is_signaling_nan(xa.VsrD(0)) || \ + float64_is_signaling_nan(xb.VsrD(0))) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ } \ if (ordered) { \ @@ -2363,9 +2371,10 @@ } \ cc = 1; \ } else { \ - if (float64_lt(xa.f64[0], xb.f64[0], &env->fp_status)) { \ + if (float64_lt(xa.VsrD(0), xb.VsrD(0), &env->fp_status)) { \ cc = 8; \ - } else if (!float64_le(xa.f64[0], xb.f64[0], &env->fp_status)) { \ + } else if (!float64_le(xa.VsrD(0), xb.VsrD(0), \ + &env->fp_status)) { \ cc = 4; \ } else { \ cc = 2; \ @@ -2390,7 +2399,7 @@ * op - operation (max or min) * nels - number of elements (1, 2 or 4) * tp - type (float32 or float64) - * fld - vsr_t field (f32 or f64) + * fld - vsr_t field (VsrD(*) or VsrW(*)) */ #define VSX_MAX_MIN(name, op, nels, tp, fld) \ void helper_##name(CPUPPCState *env, uint32_t opcode) \ @@ -2403,9 +2412,9 @@ getVSR(xT(opcode), &xt, env); \ \ for (i = 0; i < nels; i++) { \ - xt.fld[i] = tp##_##op(xa.fld[i], xb.fld[i], &env->fp_status); \ - if (unlikely(tp##_is_signaling_nan(xa.fld[i]) || \ - tp##_is_signaling_nan(xb.fld[i]))) { \ + xt.fld = tp##_##op(xa.fld, xb.fld, &env->fp_status); \ + if (unlikely(tp##_is_signaling_nan(xa.fld) || \ + tp##_is_signaling_nan(xb.fld))) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ } \ } \ @@ -2414,18 +2423,18 @@ helper_float_check_status(env); \ } -VSX_MAX_MIN(xsmaxdp, maxnum, 1, float64, f64) -VSX_MAX_MIN(xvmaxdp, maxnum, 2, float64, f64) -VSX_MAX_MIN(xvmaxsp, maxnum, 4, float32, f32) -VSX_MAX_MIN(xsmindp, minnum, 1, float64, f64) -VSX_MAX_MIN(xvmindp, minnum, 2, float64, f64) -VSX_MAX_MIN(xvminsp, minnum, 4, float32, f32) +VSX_MAX_MIN(xsmaxdp, maxnum, 1, float64, VsrD(0)) +VSX_MAX_MIN(xvmaxdp, maxnum, 2, float64, VsrD(i)) +VSX_MAX_MIN(xvmaxsp, maxnum, 4, float32, VsrW(i)) +VSX_MAX_MIN(xsmindp, minnum, 1, float64, VsrD(0)) +VSX_MAX_MIN(xvmindp, minnum, 2, float64, VsrD(i)) +VSX_MAX_MIN(xvminsp, minnum, 4, float32, VsrW(i)) /* VSX_CMP - VSX floating point compare * op - instruction mnemonic * nels - number of elements (1, 2 or 4) * tp - type (float32 or float64) - * fld - vsr_t field (f32 or f64) + * fld - vsr_t field (VsrD(*) or VsrW(*)) * cmp - comparison operation * svxvc - set VXVC bit */ @@ -2442,23 +2451,23 @@ getVSR(xT(opcode), &xt, env); \ \ for (i = 0; i < nels; i++) { \ - if (unlikely(tp##_is_any_nan(xa.fld[i]) || \ - tp##_is_any_nan(xb.fld[i]))) { \ - if (tp##_is_signaling_nan(xa.fld[i]) || \ - tp##_is_signaling_nan(xb.fld[i])) { \ + if (unlikely(tp##_is_any_nan(xa.fld) || \ + tp##_is_any_nan(xb.fld))) { \ + if (tp##_is_signaling_nan(xa.fld) || \ + tp##_is_signaling_nan(xb.fld)) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ } \ if (svxvc) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXVC, 0); \ } \ - xt.fld[i] = 0; \ + xt.fld = 0; \ all_true = 0; \ } else { \ - if (tp##_##cmp(xb.fld[i], xa.fld[i], &env->fp_status) == 1) { \ - xt.fld[i] = -1; \ + if (tp##_##cmp(xb.fld, xa.fld, &env->fp_status) == 1) { \ + xt.fld = -1; \ all_false = 0; \ } else { \ - xt.fld[i] = 0; \ + xt.fld = 0; \ all_true = 0; \ } \ } \ @@ -2471,18 +2480,12 @@ helper_float_check_status(env); \ } -VSX_CMP(xvcmpeqdp, 2, float64, f64, eq, 0) -VSX_CMP(xvcmpgedp, 2, float64, f64, le, 1) -VSX_CMP(xvcmpgtdp, 2, float64, f64, lt, 1) -VSX_CMP(xvcmpeqsp, 4, float32, f32, eq, 0) -VSX_CMP(xvcmpgesp, 4, float32, f32, le, 1) -VSX_CMP(xvcmpgtsp, 4, float32, f32, lt, 1) - -#if defined(HOST_WORDS_BIGENDIAN) -#define JOFFSET 0 -#else -#define JOFFSET 1 -#endif +VSX_CMP(xvcmpeqdp, 2, float64, VsrD(i), eq, 0) +VSX_CMP(xvcmpgedp, 2, float64, VsrD(i), le, 1) +VSX_CMP(xvcmpgtdp, 2, float64, VsrD(i), lt, 1) +VSX_CMP(xvcmpeqsp, 4, float32, VsrW(i), eq, 0) +VSX_CMP(xvcmpgesp, 4, float32, VsrW(i), le, 1) +VSX_CMP(xvcmpgtsp, 4, float32, VsrW(i), lt, 1) /* VSX_CVT_FP_TO_FP - VSX floating point/floating point conversion * op - instruction mnemonic @@ -2503,7 +2506,6 @@ getVSR(xT(opcode), &xt, env); \ \ for (i = 0; i < nels; i++) { \ - int j = 2*i + JOFFSET; \ xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \ if (unlikely(stp##_is_signaling_nan(xb.sfld))) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ @@ -2519,10 +2521,10 @@ helper_float_check_status(env); \ } -VSX_CVT_FP_TO_FP(xscvdpsp, 1, float64, float32, f64[i], f32[j], 1) -VSX_CVT_FP_TO_FP(xscvspdp, 1, float32, float64, f32[j], f64[i], 1) -VSX_CVT_FP_TO_FP(xvcvdpsp, 2, float64, float32, f64[i], f32[j], 0) -VSX_CVT_FP_TO_FP(xvcvspdp, 2, float32, float64, f32[j], f64[i], 0) +VSX_CVT_FP_TO_FP(xscvdpsp, 1, float64, float32, VsrD(0), VsrW(0), 1) +VSX_CVT_FP_TO_FP(xscvspdp, 1, float32, float64, VsrW(0), VsrD(0), 1) +VSX_CVT_FP_TO_FP(xvcvdpsp, 2, float64, float32, VsrD(i), VsrW(2*i), 0) +VSX_CVT_FP_TO_FP(xvcvspdp, 2, float32, float64, VsrW(2*i), VsrD(i), 0) uint64_t helper_xscvdpspn(CPUPPCState *env, uint64_t xb) { @@ -2547,10 +2549,9 @@ * ttp - target type (int32, uint32, int64 or uint64) * sfld - source vsr_t field * tfld - target vsr_t field - * jdef - definition of the j index (i or 2*i) * rnan - resulting NaN */ -#define VSX_CVT_FP_TO_INT(op, nels, stp, ttp, sfld, tfld, jdef, rnan) \ +#define VSX_CVT_FP_TO_INT(op, nels, stp, ttp, sfld, tfld, rnan) \ void helper_##op(CPUPPCState *env, uint32_t opcode) \ { \ ppc_vsr_t xt, xb; \ @@ -2560,7 +2561,6 @@ getVSR(xT(opcode), &xt, env); \ \ for (i = 0; i < nels; i++) { \ - int j = jdef; \ if (unlikely(stp##_is_any_nan(xb.sfld))) { \ if (stp##_is_signaling_nan(xb.sfld)) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ @@ -2568,7 +2568,8 @@ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0); \ xt.tfld = rnan; \ } else { \ - xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \ + xt.tfld = stp##_to_##ttp##_round_to_zero(xb.sfld, \ + &env->fp_status); \ if (env->fp_status.float_exception_flags & float_flag_invalid) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXCVI, 0); \ } \ @@ -2579,27 +2580,23 @@ helper_float_check_status(env); \ } -VSX_CVT_FP_TO_INT(xscvdpsxds, 1, float64, int64, f64[j], u64[i], i, \ +VSX_CVT_FP_TO_INT(xscvdpsxds, 1, float64, int64, VsrD(0), VsrD(0), \ 0x8000000000000000ULL) -VSX_CVT_FP_TO_INT(xscvdpsxws, 1, float64, int32, f64[i], u32[j], \ - 2*i + JOFFSET, 0x80000000U) -VSX_CVT_FP_TO_INT(xscvdpuxds, 1, float64, uint64, f64[j], u64[i], i, 0ULL) -VSX_CVT_FP_TO_INT(xscvdpuxws, 1, float64, uint32, f64[i], u32[j], \ - 2*i + JOFFSET, 0U) -VSX_CVT_FP_TO_INT(xvcvdpsxds, 2, float64, int64, f64[j], u64[i], i, \ +VSX_CVT_FP_TO_INT(xscvdpsxws, 1, float64, int32, VsrD(0), VsrW(1), \ + 0x80000000U) +VSX_CVT_FP_TO_INT(xscvdpuxds, 1, float64, uint64, VsrD(0), VsrD(0), 0ULL) +VSX_CVT_FP_TO_INT(xscvdpuxws, 1, float64, uint32, VsrD(0), VsrW(1), 0U) +VSX_CVT_FP_TO_INT(xvcvdpsxds, 2, float64, int64, VsrD(i), VsrD(i), \ 0x8000000000000000ULL) -VSX_CVT_FP_TO_INT(xvcvdpsxws, 2, float64, int32, f64[i], u32[j], \ - 2*i + JOFFSET, 0x80000000U) -VSX_CVT_FP_TO_INT(xvcvdpuxds, 2, float64, uint64, f64[j], u64[i], i, 0ULL) -VSX_CVT_FP_TO_INT(xvcvdpuxws, 2, float64, uint32, f64[i], u32[j], \ - 2*i + JOFFSET, 0U) -VSX_CVT_FP_TO_INT(xvcvspsxds, 2, float32, int64, f32[j], u64[i], \ - 2*i + JOFFSET, 0x8000000000000000ULL) -VSX_CVT_FP_TO_INT(xvcvspsxws, 4, float32, int32, f32[j], u32[j], i, \ +VSX_CVT_FP_TO_INT(xvcvdpsxws, 2, float64, int32, VsrD(i), VsrW(2*i), \ 0x80000000U) -VSX_CVT_FP_TO_INT(xvcvspuxds, 2, float32, uint64, f32[j], u64[i], \ - 2*i + JOFFSET, 0ULL) -VSX_CVT_FP_TO_INT(xvcvspuxws, 4, float32, uint32, f32[j], u32[i], i, 0U) +VSX_CVT_FP_TO_INT(xvcvdpuxds, 2, float64, uint64, VsrD(i), VsrD(i), 0ULL) +VSX_CVT_FP_TO_INT(xvcvdpuxws, 2, float64, uint32, VsrD(i), VsrW(2*i), 0U) +VSX_CVT_FP_TO_INT(xvcvspsxds, 2, float32, int64, VsrW(2*i), VsrD(i), \ + 0x8000000000000000ULL) +VSX_CVT_FP_TO_INT(xvcvspsxws, 4, float32, int32, VsrW(i), VsrW(i), 0x80000000U) +VSX_CVT_FP_TO_INT(xvcvspuxds, 2, float32, uint64, VsrW(2*i), VsrD(i), 0ULL) +VSX_CVT_FP_TO_INT(xvcvspuxws, 4, float32, uint32, VsrW(i), VsrW(i), 0U) /* VSX_CVT_INT_TO_FP - VSX integer to floating point conversion * op - instruction mnemonic @@ -2611,7 +2608,7 @@ * jdef - definition of the j index (i or 2*i) * sfprf - set FPRF */ -#define VSX_CVT_INT_TO_FP(op, nels, stp, ttp, sfld, tfld, jdef, sfprf, r2sp) \ +#define VSX_CVT_INT_TO_FP(op, nels, stp, ttp, sfld, tfld, sfprf, r2sp) \ void helper_##op(CPUPPCState *env, uint32_t opcode) \ { \ ppc_vsr_t xt, xb; \ @@ -2621,7 +2618,6 @@ getVSR(xT(opcode), &xt, env); \ \ for (i = 0; i < nels; i++) { \ - int j = jdef; \ xt.tfld = stp##_to_##ttp(xb.sfld, &env->fp_status); \ if (r2sp) { \ xt.tfld = helper_frsp(env, xt.tfld); \ @@ -2635,22 +2631,18 @@ helper_float_check_status(env); \ } -VSX_CVT_INT_TO_FP(xscvsxddp, 1, int64, float64, u64[j], f64[i], i, 1, 0) -VSX_CVT_INT_TO_FP(xscvuxddp, 1, uint64, float64, u64[j], f64[i], i, 1, 0) -VSX_CVT_INT_TO_FP(xscvsxdsp, 1, int64, float64, u64[j], f64[i], i, 1, 1) -VSX_CVT_INT_TO_FP(xscvuxdsp, 1, uint64, float64, u64[j], f64[i], i, 1, 1) -VSX_CVT_INT_TO_FP(xvcvsxddp, 2, int64, float64, u64[j], f64[i], i, 0, 0) -VSX_CVT_INT_TO_FP(xvcvuxddp, 2, uint64, float64, u64[j], f64[i], i, 0, 0) -VSX_CVT_INT_TO_FP(xvcvsxwdp, 2, int32, float64, u32[j], f64[i], \ - 2*i + JOFFSET, 0, 0) -VSX_CVT_INT_TO_FP(xvcvuxwdp, 2, uint64, float64, u32[j], f64[i], \ - 2*i + JOFFSET, 0, 0) -VSX_CVT_INT_TO_FP(xvcvsxdsp, 2, int64, float32, u64[i], f32[j], \ - 2*i + JOFFSET, 0, 0) -VSX_CVT_INT_TO_FP(xvcvuxdsp, 2, uint64, float32, u64[i], f32[j], \ - 2*i + JOFFSET, 0, 0) -VSX_CVT_INT_TO_FP(xvcvsxwsp, 4, int32, float32, u32[j], f32[i], i, 0, 0) -VSX_CVT_INT_TO_FP(xvcvuxwsp, 4, uint32, float32, u32[j], f32[i], i, 0, 0) +VSX_CVT_INT_TO_FP(xscvsxddp, 1, int64, float64, VsrD(0), VsrD(0), 1, 0) +VSX_CVT_INT_TO_FP(xscvuxddp, 1, uint64, float64, VsrD(0), VsrD(0), 1, 0) +VSX_CVT_INT_TO_FP(xscvsxdsp, 1, int64, float64, VsrD(0), VsrD(0), 1, 1) +VSX_CVT_INT_TO_FP(xscvuxdsp, 1, uint64, float64, VsrD(0), VsrD(0), 1, 1) +VSX_CVT_INT_TO_FP(xvcvsxddp, 2, int64, float64, VsrD(i), VsrD(i), 0, 0) +VSX_CVT_INT_TO_FP(xvcvuxddp, 2, uint64, float64, VsrD(i), VsrD(i), 0, 0) +VSX_CVT_INT_TO_FP(xvcvsxwdp, 2, int32, float64, VsrW(2*i), VsrD(i), 0, 0) +VSX_CVT_INT_TO_FP(xvcvuxwdp, 2, uint64, float64, VsrW(2*i), VsrD(i), 0, 0) +VSX_CVT_INT_TO_FP(xvcvsxdsp, 2, int64, float32, VsrD(i), VsrW(2*i), 0, 0) +VSX_CVT_INT_TO_FP(xvcvuxdsp, 2, uint64, float32, VsrD(i), VsrW(2*i), 0, 0) +VSX_CVT_INT_TO_FP(xvcvsxwsp, 4, int32, float32, VsrW(i), VsrW(i), 0, 0) +VSX_CVT_INT_TO_FP(xvcvuxwsp, 4, uint32, float32, VsrW(i), VsrW(i), 0, 0) /* For "use current rounding mode", define a value that will not be one of * the existing rounding model enums. @@ -2662,7 +2654,7 @@ * op - instruction mnemonic * nels - number of elements (1, 2 or 4) * tp - type (float32 or float64) - * fld - vsr_t field (f32 or f64) + * fld - vsr_t field (VsrD(*) or VsrW(*)) * rmode - rounding mode * sfprf - set FPRF */ @@ -2679,14 +2671,14 @@ } \ \ for (i = 0; i < nels; i++) { \ - if (unlikely(tp##_is_signaling_nan(xb.fld[i]))) { \ + if (unlikely(tp##_is_signaling_nan(xb.fld))) { \ fload_invalid_op_excp(env, POWERPC_EXCP_FP_VXSNAN, 0); \ - xt.fld[i] = tp##_snan_to_qnan(xb.fld[i]); \ + xt.fld = tp##_snan_to_qnan(xb.fld); \ } else { \ - xt.fld[i] = tp##_round_to_int(xb.fld[i], &env->fp_status); \ + xt.fld = tp##_round_to_int(xb.fld, &env->fp_status); \ } \ if (sfprf) { \ - helper_compute_fprf(env, xt.fld[i], sfprf); \ + helper_compute_fprf(env, xt.fld, sfprf); \ } \ } \ \ @@ -2702,23 +2694,23 @@ helper_float_check_status(env); \ } -VSX_ROUND(xsrdpi, 1, float64, f64, float_round_nearest_even, 1) -VSX_ROUND(xsrdpic, 1, float64, f64, FLOAT_ROUND_CURRENT, 1) -VSX_ROUND(xsrdpim, 1, float64, f64, float_round_down, 1) -VSX_ROUND(xsrdpip, 1, float64, f64, float_round_up, 1) -VSX_ROUND(xsrdpiz, 1, float64, f64, float_round_to_zero, 1) - -VSX_ROUND(xvrdpi, 2, float64, f64, float_round_nearest_even, 0) -VSX_ROUND(xvrdpic, 2, float64, f64, FLOAT_ROUND_CURRENT, 0) -VSX_ROUND(xvrdpim, 2, float64, f64, float_round_down, 0) -VSX_ROUND(xvrdpip, 2, float64, f64, float_round_up, 0) -VSX_ROUND(xvrdpiz, 2, float64, f64, float_round_to_zero, 0) - -VSX_ROUND(xvrspi, 4, float32, f32, float_round_nearest_even, 0) -VSX_ROUND(xvrspic, 4, float32, f32, FLOAT_ROUND_CURRENT, 0) -VSX_ROUND(xvrspim, 4, float32, f32, float_round_down, 0) -VSX_ROUND(xvrspip, 4, float32, f32, float_round_up, 0) -VSX_ROUND(xvrspiz, 4, float32, f32, float_round_to_zero, 0) +VSX_ROUND(xsrdpi, 1, float64, VsrD(0), float_round_nearest_even, 1) +VSX_ROUND(xsrdpic, 1, float64, VsrD(0), FLOAT_ROUND_CURRENT, 1) +VSX_ROUND(xsrdpim, 1, float64, VsrD(0), float_round_down, 1) +VSX_ROUND(xsrdpip, 1, float64, VsrD(0), float_round_up, 1) +VSX_ROUND(xsrdpiz, 1, float64, VsrD(0), float_round_to_zero, 1) + +VSX_ROUND(xvrdpi, 2, float64, VsrD(i), float_round_nearest_even, 0) +VSX_ROUND(xvrdpic, 2, float64, VsrD(i), FLOAT_ROUND_CURRENT, 0) +VSX_ROUND(xvrdpim, 2, float64, VsrD(i), float_round_down, 0) +VSX_ROUND(xvrdpip, 2, float64, VsrD(i), float_round_up, 0) +VSX_ROUND(xvrdpiz, 2, float64, VsrD(i), float_round_to_zero, 0) + +VSX_ROUND(xvrspi, 4, float32, VsrW(i), float_round_nearest_even, 0) +VSX_ROUND(xvrspic, 4, float32, VsrW(i), FLOAT_ROUND_CURRENT, 0) +VSX_ROUND(xvrspim, 4, float32, VsrW(i), float_round_down, 0) +VSX_ROUND(xvrspip, 4, float32, VsrW(i), float_round_up, 0) +VSX_ROUND(xvrspiz, 4, float32, VsrW(i), float_round_to_zero, 0) uint64_t helper_xsrsp(CPUPPCState *env, uint64_t xb) { diff -Nru qemu-2.0.0~rc1+dfsg/target-ppc/helper_regs.h qemu-2.0.0+dfsg/target-ppc/helper_regs.h --- qemu-2.0.0~rc1+dfsg/target-ppc/helper_regs.h 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/target-ppc/helper_regs.h 2014-04-17 14:26:44.000000000 +0000 @@ -101,7 +101,7 @@ hreg_compute_hflags(env); #if !defined(CONFIG_USER_ONLY) if (unlikely(msr_pow == 1)) { - if ((*env->check_pow)(env)) { + if (!env->pending_interrupts && (*env->check_pow)(env)) { cs->halted = 1; excp = EXCP_HALTED; } diff -Nru qemu-2.0.0~rc1+dfsg/target-ppc/translate_init.c qemu-2.0.0+dfsg/target-ppc/translate_init.c --- qemu-2.0.0~rc1+dfsg/target-ppc/translate_init.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/target-ppc/translate_init.c 2014-04-17 14:26:44.000000000 +0000 @@ -6699,6 +6699,8 @@ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; + pcc->l1_dcache_size = 0x8000; + pcc->l1_icache_size = 0x10000; } static int check_pow_970FX (CPUPPCState *env) @@ -6791,6 +6793,8 @@ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; + pcc->l1_dcache_size = 0x8000; + pcc->l1_icache_size = 0x10000; } static int check_pow_970MP (CPUPPCState *env) @@ -6877,6 +6881,8 @@ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; + pcc->l1_dcache_size = 0x8000; + pcc->l1_icache_size = 0x10000; } static void init_proc_power5plus(CPUPPCState *env) @@ -6967,6 +6973,8 @@ pcc->flags = POWERPC_FLAG_VRE | POWERPC_FLAG_SE | POWERPC_FLAG_BE | POWERPC_FLAG_PMM | POWERPC_FLAG_BUS_CLK; + pcc->l1_dcache_size = 0x8000; + pcc->l1_icache_size = 0x10000; } static void init_proc_POWER7 (CPUPPCState *env) Binary files /tmp/tmpPWqUu2/S9anMe5kFG/qemu-2.0.0~rc1+dfsg/tests/acpi-test-data/pc/DSDT and /tmp/tmpPWqUu2/q4F2QK4nxF/qemu-2.0.0+dfsg/tests/acpi-test-data/pc/DSDT differ Binary files /tmp/tmpPWqUu2/S9anMe5kFG/qemu-2.0.0~rc1+dfsg/tests/acpi-test-data/pc/SSDT and /tmp/tmpPWqUu2/q4F2QK4nxF/qemu-2.0.0+dfsg/tests/acpi-test-data/pc/SSDT differ Binary files /tmp/tmpPWqUu2/S9anMe5kFG/qemu-2.0.0~rc1+dfsg/tests/acpi-test-data/q35/DSDT and /tmp/tmpPWqUu2/q4F2QK4nxF/qemu-2.0.0+dfsg/tests/acpi-test-data/q35/DSDT differ diff -Nru qemu-2.0.0~rc1+dfsg/tests/Makefile qemu-2.0.0+dfsg/tests/Makefile --- qemu-2.0.0~rc1+dfsg/tests/Makefile 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/tests/Makefile 2014-04-17 14:26:44.000000000 +0000 @@ -394,7 +394,8 @@ check: check-qapi-schema check-unit check-qtest check-clean: $(MAKE) -C tests/tcg clean - rm -rf $(check-unit-y) $(check-qtest-i386-y) $(check-qtest-x86_64-y) $(check-qtest-sparc64-y) $(check-qtest-sparc-y) tests/*.o $(QEMU_IOTESTS_HELPERS-y) + rm -rf $(check-unit-y) tests/*.o $(QEMU_IOTESTS_HELPERS-y) + rm -rf $(sort $(foreach target,$(SYSEMU_TARGET_LIST), $(check-qtest-$(target)-y))) clean: check-clean diff -Nru qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/039 qemu-2.0.0+dfsg/tests/qemu-iotests/039 --- qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/039 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/tests/qemu-iotests/039 2014-04-17 14:26:44.000000000 +0000 @@ -131,6 +131,26 @@ ./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features _check_test_img +echo +echo "== Committing to a backing file with lazy_refcounts=on ==" + +IMGOPTS="compat=1.1,lazy_refcounts=on" +TEST_IMG="$TEST_IMG".base _make_test_img $size + +IMGOPTS="compat=1.1,lazy_refcounts=on,backing_file=$TEST_IMG.base" +_make_test_img $size + +$QEMU_IO -c "write 0 512" "$TEST_IMG" | _filter_qemu_io +$QEMU_IMG commit "$TEST_IMG" + +# The dirty bit must not be set +./qcow2.py "$TEST_IMG" dump-header | grep incompatible_features +./qcow2.py "$TEST_IMG".base dump-header | grep incompatible_features + +_check_test_img +TEST_IMG="$TEST_IMG".base _check_test_img + + # success, all done echo "*** done" rm -f $seq.full diff -Nru qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/039.out qemu-2.0.0+dfsg/tests/qemu-iotests/039.out --- qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/039.out 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/tests/qemu-iotests/039.out 2014-04-17 14:26:44.000000000 +0000 @@ -54,4 +54,15 @@ 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) incompatible_features 0x0 No errors were found on the image. + +== Committing to a backing file with lazy_refcounts=on == +Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728 +Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file='TEST_DIR/t.IMGFMT.base' +wrote 512/512 bytes at offset 0 +512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +Image committed. +incompatible_features 0x0 +incompatible_features 0x0 +No errors were found on the image. +No errors were found on the image. *** done diff -Nru qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/051 qemu-2.0.0+dfsg/tests/qemu-iotests/051 --- qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/051 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/tests/qemu-iotests/051 2014-04-17 14:26:44.000000000 +0000 @@ -204,6 +204,10 @@ run_qemu -drive file=foo:bar run_qemu -drive file.filename=foo:bar +run_qemu -hda "file:$TEST_IMG" +run_qemu -drive file="file:$TEST_IMG" +run_qemu -drive file.filename="file:$TEST_IMG" + echo echo === Snapshot mode === echo @@ -214,6 +218,14 @@ echo 'qemu-io ide0-hd0 "write -P 0x22 0 4k"' | run_qemu -drive file="$TEST_IMG",snapshot=on | _filter_qemu_io echo 'qemu-io ide0-hd0 "write -P 0x22 0 4k"' | run_qemu -drive file.filename="$TEST_IMG",driver=qcow2,snapshot=on | _filter_qemu_io echo 'qemu-io ide0-hd0 "write -P 0x22 0 4k"' | run_qemu -drive file.filename="$TEST_IMG",driver=qcow2 -snapshot | _filter_qemu_io +echo 'qemu-io ide0-hd0 "write -P 0x22 0 4k"' | run_qemu -drive file="file:$TEST_IMG" -snapshot | _filter_qemu_io +echo 'qemu-io ide0-hd0 "write -P 0x22 0 4k"' | run_qemu -drive file="file:$TEST_IMG",snapshot=on | _filter_qemu_io + +# Opening a read-only file r/w with snapshot=on +chmod u-w "$TEST_IMG" +echo 'qemu-io ide0-hd0 "write -P 0x22 0 4k"' | run_qemu -drive file="$TEST_IMG" -snapshot | _filter_qemu_io +echo 'qemu-io ide0-hd0 "write -P 0x22 0 4k"' | run_qemu -drive file="$TEST_IMG",snapshot=on | _filter_qemu_io +chmod u+w "$TEST_IMG" $QEMU_IO -c "read -P 0x11 0 4k" "$TEST_IMG" | _filter_qemu_io diff -Nru qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/051.out qemu-2.0.0+dfsg/tests/qemu-iotests/051.out --- qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/051.out 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/tests/qemu-iotests/051.out 2014-04-17 14:26:44.000000000 +0000 @@ -44,11 +44,11 @@ === Overriding backing file === Testing: -drive file=TEST_DIR/t.qcow2,driver=qcow2,backing.file.filename=TEST_DIR/t.qcow2.orig -nodefaults -QEMU X.Y.Z monitor - type 'help' for more information -(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo block -ide0-hd0: TEST_DIR/t.qcow2 (qcow2) - Backing file: TEST_DIR/t.qcow2.orig (chain depth: 1) -(qemu) qququiquit +QEMU X.Y.Z monitor - type 'help' for more information +(qemu) iininfinfoinfo info binfo blinfo bloinfo blocinfo block +ide0-hd0: TEST_DIR/t.qcow2 (qcow2) + Backing file: TEST_DIR/t.qcow2.orig (chain depth: 1) +(qemu) qququiquit === Enable and disable lazy refcounting on the command line, plus some invalid values === @@ -275,6 +275,17 @@ Testing: -drive file.filename=foo:bar QEMU_PROG: -drive file.filename=foo:bar: could not open disk image ide0-hd0: Could not open 'foo:bar': No such file or directory +Testing: -hda file:TEST_DIR/t.qcow2 +QEMU X.Y.Z monitor - type 'help' for more information +(qemu) qququiquit + +Testing: -drive file=file:TEST_DIR/t.qcow2 +QEMU X.Y.Z monitor - type 'help' for more information +(qemu) qququiquit + +Testing: -drive file.filename=file:TEST_DIR/t.qcow2 +QEMU_PROG: -drive file.filename=file:TEST_DIR/t.qcow2: could not open disk image ide0-hd0: Could not open 'file:TEST_DIR/t.qcow2': No such file or directory + === Snapshot mode === @@ -305,6 +316,34 @@ QEMU X.Y.Z monitor - type 'help' for more information (qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io iqemu-io idqemu-io ideqemu-io ide0qemu-io ide0-qemu-io ide0-hqemu-io ide0-hdqemu-io ide0-hd0qemu-io ide0-hd0 qemu-io ide0-hd0 "qemu-io ide0-hd0 "wqemu-io ide0-hd0 "wrqemu-io ide0-hd0 "wriqemu-io ide0-hd0 "writqemu-io ide0-hd0 "writeqemu-io ide0-hd0 "write qemu-io ide0-hd0 "write -qemu-io ide0-hd0 "write -Pqemu-io ide0-hd0 "write -P qemu-io ide0-hd0 "write -P 0qemu-io ide0-hd0 "write -P 0xqemu-io ide0-hd0 "write -P 0x2qemu-io ide0-hd0 "write -P 0x22qemu-io ide0-hd0 "write -P 0x22 qemu-io ide0-hd0 "write -P 0x22 0qemu-io ide0-hd0 "write -P 0x22 0 qemu-io ide0-hd0 "write -P 0x22 0 4qemu-io ide0-hd0 "write -P 0x22 0 4kqemu-io ide0-hd0 "write -P 0x22 0 4k" wrote 4096/4096 bytes at offset 0 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +(qemu) qququiquit + +Testing: -drive file=file:TEST_DIR/t.qcow2 -snapshot +QEMU X.Y.Z monitor - type 'help' for more information +(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io iqemu-io idqemu-io ideqemu-io ide0qemu-io ide0-qemu-io ide0-hqemu-io ide0-hdqemu-io ide0-hd0qemu-io ide0-hd0 qemu-io ide0-hd0 "qemu-io ide0-hd0 "wqemu-io ide0-hd0 "wrqemu-io ide0-hd0 "wriqemu-io ide0-hd0 "writqemu-io ide0-hd0 "writeqemu-io ide0-hd0 "write qemu-io ide0-hd0 "write -qemu-io ide0-hd0 "write -Pqemu-io ide0-hd0 "write -P qemu-io ide0-hd0 "write -P 0qemu-io ide0-hd0 "write -P 0xqemu-io ide0-hd0 "write -P 0x2qemu-io ide0-hd0 "write -P 0x22qemu-io ide0-hd0 "write -P 0x22 qemu-io ide0-hd0 "write -P 0x22 0qemu-io ide0-hd0 "write -P 0x22 0 qemu-io ide0-hd0 "write -P 0x22 0 4qemu-io ide0-hd0 "write -P 0x22 0 4kqemu-io ide0-hd0 "write -P 0x22 0 4k" +wrote 4096/4096 bytes at offset 0 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +(qemu) qququiquit + +Testing: -drive file=file:TEST_DIR/t.qcow2,snapshot=on +QEMU X.Y.Z monitor - type 'help' for more information +(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io iqemu-io idqemu-io ideqemu-io ide0qemu-io ide0-qemu-io ide0-hqemu-io ide0-hdqemu-io ide0-hd0qemu-io ide0-hd0 qemu-io ide0-hd0 "qemu-io ide0-hd0 "wqemu-io ide0-hd0 "wrqemu-io ide0-hd0 "wriqemu-io ide0-hd0 "writqemu-io ide0-hd0 "writeqemu-io ide0-hd0 "write qemu-io ide0-hd0 "write -qemu-io ide0-hd0 "write -Pqemu-io ide0-hd0 "write -P qemu-io ide0-hd0 "write -P 0qemu-io ide0-hd0 "write -P 0xqemu-io ide0-hd0 "write -P 0x2qemu-io ide0-hd0 "write -P 0x22qemu-io ide0-hd0 "write -P 0x22 qemu-io ide0-hd0 "write -P 0x22 0qemu-io ide0-hd0 "write -P 0x22 0 qemu-io ide0-hd0 "write -P 0x22 0 4qemu-io ide0-hd0 "write -P 0x22 0 4kqemu-io ide0-hd0 "write -P 0x22 0 4k" +wrote 4096/4096 bytes at offset 0 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +(qemu) qququiquit + +Testing: -drive file=TEST_DIR/t.qcow2 -snapshot +QEMU X.Y.Z monitor - type 'help' for more information +(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io iqemu-io idqemu-io ideqemu-io ide0qemu-io ide0-qemu-io ide0-hqemu-io ide0-hdqemu-io ide0-hd0qemu-io ide0-hd0 qemu-io ide0-hd0 "qemu-io ide0-hd0 "wqemu-io ide0-hd0 "wrqemu-io ide0-hd0 "wriqemu-io ide0-hd0 "writqemu-io ide0-hd0 "writeqemu-io ide0-hd0 "write qemu-io ide0-hd0 "write -qemu-io ide0-hd0 "write -Pqemu-io ide0-hd0 "write -P qemu-io ide0-hd0 "write -P 0qemu-io ide0-hd0 "write -P 0xqemu-io ide0-hd0 "write -P 0x2qemu-io ide0-hd0 "write -P 0x22qemu-io ide0-hd0 "write -P 0x22 qemu-io ide0-hd0 "write -P 0x22 0qemu-io ide0-hd0 "write -P 0x22 0 qemu-io ide0-hd0 "write -P 0x22 0 4qemu-io ide0-hd0 "write -P 0x22 0 4kqemu-io ide0-hd0 "write -P 0x22 0 4k" +wrote 4096/4096 bytes at offset 0 +4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +(qemu) qququiquit + +Testing: -drive file=TEST_DIR/t.qcow2,snapshot=on +QEMU X.Y.Z monitor - type 'help' for more information +(qemu) qqeqemqemuqemu-qemu-iqemu-ioqemu-io qemu-io iqemu-io idqemu-io ideqemu-io ide0qemu-io ide0-qemu-io ide0-hqemu-io ide0-hdqemu-io ide0-hd0qemu-io ide0-hd0 qemu-io ide0-hd0 "qemu-io ide0-hd0 "wqemu-io ide0-hd0 "wrqemu-io ide0-hd0 "wriqemu-io ide0-hd0 "writqemu-io ide0-hd0 "writeqemu-io ide0-hd0 "write qemu-io ide0-hd0 "write -qemu-io ide0-hd0 "write -Pqemu-io ide0-hd0 "write -P qemu-io ide0-hd0 "write -P 0qemu-io ide0-hd0 "write -P 0xqemu-io ide0-hd0 "write -P 0x2qemu-io ide0-hd0 "write -P 0x22qemu-io ide0-hd0 "write -P 0x22 qemu-io ide0-hd0 "write -P 0x22 0qemu-io ide0-hd0 "write -P 0x22 0 qemu-io ide0-hd0 "write -P 0x22 0 4qemu-io ide0-hd0 "write -P 0x22 0 4kqemu-io ide0-hd0 "write -P 0x22 0 4k" +wrote 4096/4096 bytes at offset 0 4 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) (qemu) qququiquit diff -Nru qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/078 qemu-2.0.0+dfsg/tests/qemu-iotests/078 --- qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/078 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/tests/qemu-iotests/078 2014-04-17 14:26:44.000000000 +0000 @@ -69,10 +69,14 @@ poke_file "$TEST_IMG" "$disk_size_offset" "\x00\xc0\x0f\x00\x00\x00\x00\x7f" { $QEMU_IO -c "read 2T 4k" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir +_use_sample_img empty.bochs.bz2 +poke_file "$TEST_IMG" "$catalog_size_offset" "\x10\x00\x00\x00" +{ $QEMU_IO -c "read 0xfbe00 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir + echo echo "== Negative extent size ==" _use_sample_img empty.bochs.bz2 -poke_file "$TEST_IMG" "$extent_size_offset" "\xff\xff\xff\xff" +poke_file "$TEST_IMG" "$extent_size_offset" "\x00\x00\x00\x80" { $QEMU_IO -c "read 768k 512" $TEST_IMG; } 2>&1 | _filter_qemu_io | _filter_testdir echo diff -Nru qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/078.out qemu-2.0.0+dfsg/tests/qemu-iotests/078.out --- qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/078.out 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/tests/qemu-iotests/078.out 2014-04-17 14:26:44.000000000 +0000 @@ -15,12 +15,14 @@ == Too small catalog bitmap for image size == qemu-io: can't open device TEST_DIR/empty.bochs: Catalog size is too small for this disk size no file open, try 'help open' +qemu-io: can't open device TEST_DIR/empty.bochs: Catalog size is too small for this disk size +no file open, try 'help open' == Negative extent size == -qemu-io: can't open device TEST_DIR/empty.bochs: Extent size 4294967295 is too large +qemu-io: can't open device TEST_DIR/empty.bochs: Extent size 2147483648 is too large no file open, try 'help open' == Zero extent size == -qemu-io: can't open device TEST_DIR/empty.bochs: Extent size may not be zero +qemu-io: can't open device TEST_DIR/empty.bochs: Extent size must be at least 512 no file open, try 'help open' *** done Binary files /tmp/tmpPWqUu2/S9anMe5kFG/qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/sample_images/empty.bochs.bz2 and /tmp/tmpPWqUu2/q4F2QK4nxF/qemu-2.0.0+dfsg/tests/qemu-iotests/sample_images/empty.bochs.bz2 differ Binary files /tmp/tmpPWqUu2/S9anMe5kFG/qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/sample_images/fake.parallels.bz2 and /tmp/tmpPWqUu2/q4F2QK4nxF/qemu-2.0.0+dfsg/tests/qemu-iotests/sample_images/fake.parallels.bz2 differ Binary files /tmp/tmpPWqUu2/S9anMe5kFG/qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/sample_images/simple-pattern.cloop.bz2 and /tmp/tmpPWqUu2/q4F2QK4nxF/qemu-2.0.0+dfsg/tests/qemu-iotests/sample_images/simple-pattern.cloop.bz2 differ diff -Nru qemu-2.0.0~rc1+dfsg/translate-all.c qemu-2.0.0+dfsg/translate-all.c --- qemu-2.0.0~rc1+dfsg/translate-all.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/translate-all.c 2014-04-17 14:26:44.000000000 +0000 @@ -1777,7 +1777,6 @@ return -1; } } - return 0; } } return 0; diff -Nru qemu-2.0.0~rc1+dfsg/ui/gtk.c qemu-2.0.0+dfsg/ui/gtk.c --- qemu-2.0.0~rc1+dfsg/ui/gtk.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/ui/gtk.c 2014-04-17 14:26:44.000000000 +0000 @@ -156,8 +156,11 @@ DisplayChangeListener dcl; DisplaySurface *ds; int button_mask; + gboolean last_set; int last_x; int last_y; + int grab_x_root; + int grab_y_root; double scale_x; double scale_y; @@ -473,8 +476,15 @@ static void gd_mouse_mode_change(Notifier *notify, void *data) { - gd_update_cursor(container_of(notify, GtkDisplayState, mouse_mode_notifier), - FALSE); + GtkDisplayState *s; + + s = container_of(notify, GtkDisplayState, mouse_mode_notifier); + /* release the grab at switching to absolute mode */ + if (qemu_input_is_absolute() && gd_is_grab_active(s)) { + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), + FALSE); + } + gd_update_cursor(s, FALSE); } /** GTK Events **/ @@ -616,25 +626,25 @@ x = (motion->x - mx) / s->scale_x; y = (motion->y - my) / s->scale_y; - if (x < 0 || y < 0 || - x >= surface_width(s->ds) || - y >= surface_height(s->ds)) { - return TRUE; - } - if (qemu_input_is_absolute()) { + if (x < 0 || y < 0 || + x >= surface_width(s->ds) || + y >= surface_height(s->ds)) { + return TRUE; + } qemu_input_queue_abs(s->dcl.con, INPUT_AXIS_X, x, surface_width(s->ds)); qemu_input_queue_abs(s->dcl.con, INPUT_AXIS_Y, y, surface_height(s->ds)); qemu_input_event_sync(); - } else if (s->last_x != -1 && s->last_y != -1 && gd_is_grab_active(s)) { + } else if (s->last_set && gd_is_grab_active(s)) { qemu_input_queue_rel(s->dcl.con, INPUT_AXIS_X, x - s->last_x); qemu_input_queue_rel(s->dcl.con, INPUT_AXIS_Y, y - s->last_y); qemu_input_event_sync(); } s->last_x = x; s->last_y = y; + s->last_set = TRUE; if (!qemu_input_is_absolute() && gd_is_grab_active(s)) { GdkScreen *screen = gtk_widget_get_screen(s->drawing_area); @@ -669,8 +679,7 @@ GdkDisplay *display = gtk_widget_get_display(widget); gdk_display_warp_pointer(display, screen, x, y); #endif - s->last_x = -1; - s->last_y = -1; + s->last_set = FALSE; return FALSE; } } @@ -683,6 +692,14 @@ GtkDisplayState *s = opaque; InputButton btn; + /* implicitly grab the input at the first click in the relative mode */ + if (button->button == 1 && button->type == GDK_BUTTON_PRESS && + !qemu_input_is_absolute() && !gd_is_grab_active(s)) { + gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(s->grab_item), + TRUE); + return TRUE; + } + if (button->button == 1) { btn = INPUT_BUTTON_LEFT; } else if (button->button == 2) { @@ -765,6 +782,14 @@ return TRUE; } +static gboolean gd_event(GtkWidget *widget, GdkEvent *event, void *opaque) +{ + if (event->type == GDK_MOTION_NOTIFY) { + return gd_motion_event(widget, &event->motion, opaque); + } + return FALSE; +} + /** Window Menu Actions **/ static void gd_menu_pause(GtkMenuItem *item, void *opaque) @@ -963,8 +988,8 @@ static void gd_grab_pointer(GtkDisplayState *s) { -#if GTK_CHECK_VERSION(3, 0, 0) GdkDisplay *display = gtk_widget_get_display(s->drawing_area); +#if GTK_CHECK_VERSION(3, 0, 0) GdkDeviceManager *mgr = gdk_display_get_device_manager(display); GList *devices = gdk_device_manager_list_devices(mgr, GDK_DEVICE_TYPE_MASTER); @@ -988,6 +1013,8 @@ tmp = tmp->next; } g_list_free(devices); + gdk_device_get_position(gdk_device_manager_get_client_pointer(mgr), + NULL, &s->grab_x_root, &s->grab_y_root); #else gdk_pointer_grab(gtk_widget_get_window(s->drawing_area), FALSE, /* All events to come to our window directly */ @@ -999,13 +1026,15 @@ NULL, /* Allow cursor to move over entire desktop */ s->null_cursor, GDK_CURRENT_TIME); + gdk_display_get_pointer(display, NULL, + &s->grab_x_root, &s->grab_y_root, NULL); #endif } static void gd_ungrab_pointer(GtkDisplayState *s) { -#if GTK_CHECK_VERSION(3, 0, 0) GdkDisplay *display = gtk_widget_get_display(s->drawing_area); +#if GTK_CHECK_VERSION(3, 0, 0) GdkDeviceManager *mgr = gdk_display_get_device_manager(display); GList *devices = gdk_device_manager_list_devices(mgr, GDK_DEVICE_TYPE_MASTER); @@ -1019,8 +1048,14 @@ tmp = tmp->next; } g_list_free(devices); + gdk_device_warp(gdk_device_manager_get_client_pointer(mgr), + gtk_widget_get_screen(s->drawing_area), + s->grab_x_root, s->grab_y_root); #else gdk_pointer_ungrab(GDK_CURRENT_TIME); + gdk_display_warp_pointer(display, + gtk_widget_get_screen(s->drawing_area), + s->grab_x_root, s->grab_y_root); #endif } @@ -1267,8 +1302,8 @@ g_signal_connect(s->drawing_area, "expose-event", G_CALLBACK(gd_expose_event), s); #endif - g_signal_connect(s->drawing_area, "motion-notify-event", - G_CALLBACK(gd_motion_event), s); + g_signal_connect(s->drawing_area, "event", + G_CALLBACK(gd_event), s); g_signal_connect(s->drawing_area, "button-press-event", G_CALLBACK(gd_button_event), s); g_signal_connect(s->drawing_area, "button-release-event", diff -Nru qemu-2.0.0~rc1+dfsg/ui/sdl2.c qemu-2.0.0+dfsg/ui/sdl2.c --- qemu-2.0.0~rc1+dfsg/ui/sdl2.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/ui/sdl2.c 2014-04-17 14:26:44.000000000 +0000 @@ -278,7 +278,7 @@ SDL_ShowCursor(1); SDL_SetCursor(sdl_cursor_hidden); } else { - SDL_ShowCursor(0); + SDL_SetRelativeMouseMode(SDL_TRUE); } } @@ -289,6 +289,7 @@ } if (!qemu_input_is_absolute()) { + SDL_SetRelativeMouseMode(SDL_FALSE); SDL_ShowCursor(1); if (guest_cursor && (gui_grab || qemu_input_is_absolute() || absolute_enabled)) { @@ -403,13 +404,17 @@ } qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_X, off_x + x, max_w); qemu_input_queue_abs(scon->dcl.con, INPUT_AXIS_Y, off_y + y, max_h); - } else if (guest_cursor) { - x -= guest_x; - y -= guest_y; - guest_x += x; - guest_y += y; - qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_X, x); - qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_Y, y); + } else { + if (guest_cursor) { + x -= guest_x; + y -= guest_y; + guest_x += x; + guest_y += y; + dx = x; + dy = y; + } + qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_X, dx); + qemu_input_queue_rel(scon->dcl.con, INPUT_AXIS_Y, dy); } qemu_input_event_sync(); } diff -Nru qemu-2.0.0~rc1+dfsg/ui/spice-display.c qemu-2.0.0+dfsg/ui/spice-display.c --- qemu-2.0.0~rc1+dfsg/ui/spice-display.c 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/ui/spice-display.c 2014-04-17 14:26:44.000000000 +0000 @@ -549,6 +549,10 @@ QemuUIInfo info; int rc; + if (!mc) { + return 1; + } + /* * FIXME: multihead is tricky due to the way * spice has multihead implemented. diff -Nru qemu-2.0.0~rc1+dfsg/VERSION qemu-2.0.0+dfsg/VERSION --- qemu-2.0.0~rc1+dfsg/VERSION 2014-04-03 18:56:23.000000000 +0000 +++ qemu-2.0.0+dfsg/VERSION 2014-04-17 14:26:43.000000000 +0000 @@ -1 +1 @@ -1.7.91 +2.0.0