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 2016-07-01 19:26:09.000000000 +0000 @@ -1,3 +1,532 @@ +qemu (2.0.0+dfsg-2ubuntu1.25~ppa1) 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/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/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-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/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/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/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 2016-07-01 19:25:16.000000000 +0000 @@ -2,6 +2,108 @@ 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 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 2014-10-06 22:47:06.000000000 +0000 @@ -0,0 +1,251 @@ +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 +--- + 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(-) + +Index: qemu-2.0.0+dfsg/hw/acpi/piix4.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/acpi/piix4.c ++++ qemu-2.0.0+dfsg/hw/acpi/piix4.c +@@ -247,8 +247,9 @@ static bool vmstate_test_no_use_acpi_pci + } + + /* 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_ + } + }; + ++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 @@ static void piix4_pm_class_init(ObjectCl + 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, +Index: qemu-2.0.0+dfsg/hw/i386/pc_piix.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/i386/pc_piix.c ++++ qemu-2.0.0+dfsg/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 @@ static void pc_init_pci_1_2(QEMUMachineI + 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) + { +@@ -581,6 +592,39 @@ static QEMUMachine pc_machine_v1_0 = { + { /* end of list */ } + }, + .hw_version = "1.0", ++ .alias = "pc-1.0-qemu-kvm", ++}; ++ ++#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 \ +@@ -824,6 +868,7 @@ static void pc_machine_init(void) + 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); +Index: qemu-2.0.0+dfsg/hw/timer/i8254_common.c +=================================================================== +--- qemu-2.0.0+dfsg.orig/hw/timer/i8254_common.c ++++ qemu-2.0.0+dfsg/hw/timer/i8254_common.c +@@ -276,6 +276,29 @@ static const VMStateDescription vmstate_ + } + }; + ++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 @@ static void pit_common_class_init(Object + 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, +Index: qemu-2.0.0+dfsg/include/hw/acpi/piix4.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/include/hw/acpi/piix4.h ++++ qemu-2.0.0+dfsg/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 +Index: qemu-2.0.0+dfsg/include/hw/timer/i8254.h +=================================================================== +--- qemu-2.0.0+dfsg.orig/include/hw/timer/i8254.h ++++ qemu-2.0.0+dfsg/include/hw/timer/i8254.h +@@ -72,4 +72,6 @@ static inline ISADevice *kvm_pit_init(IS + 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/tmp3GDO5G/pC5Q3cYgNw/qemu-2.0.0~rc1+dfsg/tests/acpi-test-data/pc/DSDT and /tmp/tmp3GDO5G/Im8N2dPLa1/qemu-2.0.0+dfsg/tests/acpi-test-data/pc/DSDT differ Binary files /tmp/tmp3GDO5G/pC5Q3cYgNw/qemu-2.0.0~rc1+dfsg/tests/acpi-test-data/pc/SSDT and /tmp/tmp3GDO5G/Im8N2dPLa1/qemu-2.0.0+dfsg/tests/acpi-test-data/pc/SSDT differ Binary files /tmp/tmp3GDO5G/pC5Q3cYgNw/qemu-2.0.0~rc1+dfsg/tests/acpi-test-data/q35/DSDT and /tmp/tmp3GDO5G/Im8N2dPLa1/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/tmp3GDO5G/pC5Q3cYgNw/qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/sample_images/empty.bochs.bz2 and /tmp/tmp3GDO5G/Im8N2dPLa1/qemu-2.0.0+dfsg/tests/qemu-iotests/sample_images/empty.bochs.bz2 differ Binary files /tmp/tmp3GDO5G/pC5Q3cYgNw/qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/sample_images/fake.parallels.bz2 and /tmp/tmp3GDO5G/Im8N2dPLa1/qemu-2.0.0+dfsg/tests/qemu-iotests/sample_images/fake.parallels.bz2 differ Binary files /tmp/tmp3GDO5G/pC5Q3cYgNw/qemu-2.0.0~rc1+dfsg/tests/qemu-iotests/sample_images/simple-pattern.cloop.bz2 and /tmp/tmp3GDO5G/Im8N2dPLa1/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