From dfb84783bcf41ff69fe0cba9b94e168eb4dcacc0 Mon Sep 17 00:00:00 2001 From: Cole Robinson Date: Wed, 15 Mar 2017 08:06:09 -0400 Subject: [PATCH] CVE-2017-5525: audio: memory leakage in ac97 (bz #1414110) CVE-2017-5526: audio: memory leakage in es1370 (bz #1414210) CVE-2016-10155 watchdog: memory leakage in i6300esb (bz #1415200) CVE-2017-5552: virtio-gpu-3d: memory leakage (bz #1415283) CVE-2017-5667: sd: sdhci OOB access during multi block transfer (bz #1417560) CVE-2017-5857: virtio-gpu-3d: host memory leakage in virgl_cmd_resource_unref (bz #1418383) CVE-2017-5856: scsi: megasas: memory leakage (bz #1418344) CVE-2017-5898: usb: integer overflow in emulated_apdu_from_guest (bz #1419700) CVE-2017-5987: sd: infinite loop issue in multi block transfers (bz #1422001) CVE-2017-6505: usb: an infinite loop issue in ohci_service_ed_list (bz #1429434) CVE-2017-2615: cirrus: oob access while doing bitblt copy backward (bz #1418206) CVE-2017-2620: cirrus: potential arbitrary code execution (bz #1425419) --- 0047-audio-ac97-add-exit-function.patch | 49 +++++++++ 0048-audio-es1370-add-exit-function.patch | 52 +++++++++ 0049-watchdog-6300esb-add-exit-function.patch | 43 ++++++++ ...x-memory-leak-in-resource-attach-bac.patch | 38 +++++++ ...k-data-length-during-dma_memory_read.patch | 34 ++++++ ...asas-fix-guest-triggered-memory-leak.patch | 61 +++++++++++ ...esource-leak-in-virgl_cmd_resource_u.patch | 45 ++++++++ 0054-usb-ccid-check-ccid-apdu-length.patch | 32 ++++++ ...ransfer-mode-register-in-multi-block.patch | 51 +++++++++ ...sb-ohci-limit-the-number-of-link-eds.patch | 49 +++++++++ ...gnore-source-pitch-value-as-needed-i.patch | 69 ++++++++++++ ...gative-pitch-in-cirrus_invalidate_re.patch | 47 ++++++++ ...ro-source-pitch-in-pattern-fill-rops.patch | 99 +++++++++++++++++ ...irrus-fix-blit-address-mask-handling.patch | 101 ++++++++++++++++++ ...s-fix-oob-access-issue-CVE-2017-2615.patch | 45 ++++++++ 0062-cirrus-fix-patterncopy-checks.patch | 101 ++++++++++++++++++ ...low-zero-source-pitch-in-pattern-fil.patch | 100 +++++++++++++++++ ...is_unsafe-call-to-cirrus_bitblt_cput.patch | 46 ++++++++ qemu.spec | 59 +++++++++- 19 files changed, 1119 insertions(+), 2 deletions(-) create mode 100644 0047-audio-ac97-add-exit-function.patch create mode 100644 0048-audio-es1370-add-exit-function.patch create mode 100644 0049-watchdog-6300esb-add-exit-function.patch create mode 100644 0050-virtio-gpu-3d-fix-memory-leak-in-resource-attach-bac.patch create mode 100644 0051-sd-sdhci-check-data-length-during-dma_memory_read.patch create mode 100644 0052-megasas-fix-guest-triggered-memory-leak.patch create mode 100644 0053-virtio-gpu-fix-resource-leak-in-virgl_cmd_resource_u.patch create mode 100644 0054-usb-ccid-check-ccid-apdu-length.patch create mode 100644 0055-sd-sdhci-check-transfer-mode-register-in-multi-block.patch create mode 100644 0056-usb-ohci-limit-the-number-of-link-eds.patch create mode 100644 0057-display-cirrus-ignore-source-pitch-value-as-needed-i.patch create mode 100644 0058-cirrus-handle-negative-pitch-in-cirrus_invalidate_re.patch create mode 100644 0059-cirrus-allow-zero-source-pitch-in-pattern-fill-rops.patch create mode 100644 0060-cirrus-fix-blit-address-mask-handling.patch create mode 100644 0061-cirrus-fix-oob-access-issue-CVE-2017-2615.patch create mode 100644 0062-cirrus-fix-patterncopy-checks.patch create mode 100644 0063-Revert-cirrus-allow-zero-source-pitch-in-pattern-fil.patch create mode 100644 0064-cirrus-add-blit_is_unsafe-call-to-cirrus_bitblt_cput.patch diff --git a/0047-audio-ac97-add-exit-function.patch b/0047-audio-ac97-add-exit-function.patch new file mode 100644 index 0000000..4402949 --- /dev/null +++ b/0047-audio-ac97-add-exit-function.patch @@ -0,0 +1,49 @@ +From: Li Qiang +Date: Wed, 14 Dec 2016 18:30:21 -0800 +Subject: [PATCH] audio: ac97: add exit function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently the ac97 device emulation doesn't have a exit function, +hot unplug this device will leak some memory. Add a exit function to +avoid this. + +Signed-off-by: Li Qiang +Reviewed-by: Marc-André Lureau +Message-id: 58520052.4825ed0a.27a71.6cae@mx.google.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 12351a91da97b414eec8cdb09f1d9f41e535a401) +--- + hw/audio/ac97.c | 11 +++++++++++ + 1 file changed, 11 insertions(+) + +diff --git a/hw/audio/ac97.c b/hw/audio/ac97.c +index cbd959e..c306575 100644 +--- a/hw/audio/ac97.c ++++ b/hw/audio/ac97.c +@@ -1387,6 +1387,16 @@ static void ac97_realize(PCIDevice *dev, Error **errp) + ac97_on_reset (&s->dev.qdev); + } + ++static void ac97_exit(PCIDevice *dev) ++{ ++ AC97LinkState *s = DO_UPCAST(AC97LinkState, dev, dev); ++ ++ AUD_close_in(&s->card, s->voice_pi); ++ AUD_close_out(&s->card, s->voice_po); ++ AUD_close_in(&s->card, s->voice_mc); ++ AUD_remove_card(&s->card); ++} ++ + static int ac97_init (PCIBus *bus) + { + pci_create_simple (bus, -1, "AC97"); +@@ -1404,6 +1414,7 @@ static void ac97_class_init (ObjectClass *klass, void *data) + PCIDeviceClass *k = PCI_DEVICE_CLASS (klass); + + k->realize = ac97_realize; ++ k->exit = ac97_exit; + k->vendor_id = PCI_VENDOR_ID_INTEL; + k->device_id = PCI_DEVICE_ID_INTEL_82801AA_5; + k->revision = 0x01; diff --git a/0048-audio-es1370-add-exit-function.patch b/0048-audio-es1370-add-exit-function.patch new file mode 100644 index 0000000..e289745 --- /dev/null +++ b/0048-audio-es1370-add-exit-function.patch @@ -0,0 +1,52 @@ +From: Li Qiang +Date: Wed, 14 Dec 2016 18:32:22 -0800 +Subject: [PATCH] audio: es1370: add exit function +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Currently the es1370 device emulation doesn't have a exit function, +hot unplug this device will leak some memory. Add a exit function to +avoid this. + +Signed-off-by: Li Qiang +Reviewed-by: Marc-André Lureau +Message-id: 585200c9.a968ca0a.1ab80.4c98@mx.google.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 069eb7b2b8fc47c7cb52e5a4af23ea98d939e3da) +--- + hw/audio/es1370.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/hw/audio/es1370.c b/hw/audio/es1370.c +index 8449b5f..883ec69 100644 +--- a/hw/audio/es1370.c ++++ b/hw/audio/es1370.c +@@ -1041,6 +1041,19 @@ static void es1370_realize(PCIDevice *dev, Error **errp) + es1370_reset (s); + } + ++static void es1370_exit(PCIDevice *dev) ++{ ++ ES1370State *s = ES1370(dev); ++ int i; ++ ++ for (i = 0; i < 2; ++i) { ++ AUD_close_out(&s->card, s->dac_voice[i]); ++ } ++ ++ AUD_close_in(&s->card, s->adc_voice); ++ AUD_remove_card(&s->card); ++} ++ + static int es1370_init (PCIBus *bus) + { + pci_create_simple (bus, -1, TYPE_ES1370); +@@ -1053,6 +1066,7 @@ static void es1370_class_init (ObjectClass *klass, void *data) + PCIDeviceClass *k = PCI_DEVICE_CLASS (klass); + + k->realize = es1370_realize; ++ k->exit = es1370_exit; + k->vendor_id = PCI_VENDOR_ID_ENSONIQ; + k->device_id = PCI_DEVICE_ID_ENSONIQ_ES1370; + k->class_id = PCI_CLASS_MULTIMEDIA_AUDIO; diff --git a/0049-watchdog-6300esb-add-exit-function.patch b/0049-watchdog-6300esb-add-exit-function.patch new file mode 100644 index 0000000..6c7404b --- /dev/null +++ b/0049-watchdog-6300esb-add-exit-function.patch @@ -0,0 +1,43 @@ +From: Li Qiang +Date: Mon, 28 Nov 2016 17:49:04 -0800 +Subject: [PATCH] watchdog: 6300esb: add exit function + +When the Intel 6300ESB watchdog is hot unplug. The timer allocated +in realize isn't freed thus leaking memory leak. This patch avoid +this through adding the exit function. + +Signed-off-by: Li Qiang +Message-Id: <583cde9c.3223ed0a.7f0c2.886e@mx.google.com> +Signed-off-by: Paolo Bonzini +(cherry picked from commit eb7a20a3616085d46aa6b4b4224e15587ec67e6e) +--- + hw/watchdog/wdt_i6300esb.c | 9 +++++++++ + 1 file changed, 9 insertions(+) + +diff --git a/hw/watchdog/wdt_i6300esb.c b/hw/watchdog/wdt_i6300esb.c +index a83d951..49b3cd1 100644 +--- a/hw/watchdog/wdt_i6300esb.c ++++ b/hw/watchdog/wdt_i6300esb.c +@@ -428,6 +428,14 @@ static void i6300esb_realize(PCIDevice *dev, Error **errp) + /* qemu_register_coalesced_mmio (addr, 0x10); ? */ + } + ++static void i6300esb_exit(PCIDevice *dev) ++{ ++ I6300State *d = WATCHDOG_I6300ESB_DEVICE(dev); ++ ++ timer_del(d->timer); ++ timer_free(d->timer); ++} ++ + static WatchdogTimerModel model = { + .wdt_name = "i6300esb", + .wdt_description = "Intel 6300ESB", +@@ -441,6 +449,7 @@ static void i6300esb_class_init(ObjectClass *klass, void *data) + k->config_read = i6300esb_config_read; + k->config_write = i6300esb_config_write; + k->realize = i6300esb_realize; ++ k->exit = i6300esb_exit; + k->vendor_id = PCI_VENDOR_ID_INTEL; + k->device_id = PCI_DEVICE_ID_INTEL_ESB_9; + k->class_id = PCI_CLASS_SYSTEM_OTHER; diff --git a/0050-virtio-gpu-3d-fix-memory-leak-in-resource-attach-bac.patch b/0050-virtio-gpu-3d-fix-memory-leak-in-resource-attach-bac.patch new file mode 100644 index 0000000..e667e8f --- /dev/null +++ b/0050-virtio-gpu-3d-fix-memory-leak-in-resource-attach-bac.patch @@ -0,0 +1,38 @@ +From: Li Qiang +Date: Thu, 29 Dec 2016 03:11:26 -0500 +Subject: [PATCH] virtio-gpu-3d: fix memory leak in resource attach backing +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +If the virgl_renderer_resource_attach_iov function fails the +'res_iovs' will be leaked. Add check of the return value to +free the 'res_iovs' when failing. + +Signed-off-by: Li Qiang +Reviewed-by: Marc-André Lureau +Message-id: 1482999086-59795-1-git-send-email-liq3ea@gmail.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 33243031dad02d161225ba99d782616da133f689) +--- + hw/display/virtio-gpu-3d.c | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +diff --git a/hw/display/virtio-gpu-3d.c b/hw/display/virtio-gpu-3d.c +index 420187e..4cffab5 100644 +--- a/hw/display/virtio-gpu-3d.c ++++ b/hw/display/virtio-gpu-3d.c +@@ -289,8 +289,11 @@ static void virgl_resource_attach_backing(VirtIOGPU *g, + return; + } + +- virgl_renderer_resource_attach_iov(att_rb.resource_id, +- res_iovs, att_rb.nr_entries); ++ ret = virgl_renderer_resource_attach_iov(att_rb.resource_id, ++ res_iovs, att_rb.nr_entries); ++ ++ if (ret != 0) ++ virtio_gpu_cleanup_mapping_iov(res_iovs, att_rb.nr_entries); + } + + static void virgl_resource_detach_backing(VirtIOGPU *g, diff --git a/0051-sd-sdhci-check-data-length-during-dma_memory_read.patch b/0051-sd-sdhci-check-data-length-during-dma_memory_read.patch new file mode 100644 index 0000000..34b0070 --- /dev/null +++ b/0051-sd-sdhci-check-data-length-during-dma_memory_read.patch @@ -0,0 +1,34 @@ +From: Prasad J Pandit +Date: Tue, 7 Feb 2017 18:29:59 +0000 +Subject: [PATCH] sd: sdhci: check data length during dma_memory_read + +While doing multi block SDMA transfer in routine +'sdhci_sdma_transfer_multi_blocks', the 's->fifo_buffer' starting +index 'begin' and data length 's->data_count' could end up to be same. +This could lead to an OOB access issue. Correct transfer data length +to avoid it. + +Cc: qemu-stable@nongnu.org +Reported-by: Jiang Xin +Signed-off-by: Prasad J Pandit +Reviewed-by: Peter Maydell +Message-id: 20170130064736.9236-1-ppandit@redhat.com +Signed-off-by: Peter Maydell +(cherry picked from commit 42922105beb14c2fc58185ea022b9f72fb5465e9) +--- + hw/sd/sdhci.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c +index d28b587..f4cf5c7 100644 +--- a/hw/sd/sdhci.c ++++ b/hw/sd/sdhci.c +@@ -535,7 +535,7 @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s) + boundary_count -= block_size - begin; + } + dma_memory_read(&address_space_memory, s->sdmasysad, +- &s->fifo_buffer[begin], s->data_count); ++ &s->fifo_buffer[begin], s->data_count - begin); + s->sdmasysad += s->data_count - begin; + if (s->data_count == block_size) { + for (n = 0; n < block_size; n++) { diff --git a/0052-megasas-fix-guest-triggered-memory-leak.patch b/0052-megasas-fix-guest-triggered-memory-leak.patch new file mode 100644 index 0000000..99c2182 --- /dev/null +++ b/0052-megasas-fix-guest-triggered-memory-leak.patch @@ -0,0 +1,61 @@ +From: Paolo Bonzini +Date: Mon, 2 Jan 2017 11:03:33 +0100 +Subject: [PATCH] megasas: fix guest-triggered memory leak + +If the guest sets the sglist size to a value >=2GB, megasas_handle_dcmd +will return MFI_STAT_MEMORY_NOT_AVAILABLE without freeing the memory. +Avoid this by returning only the status from map_dcmd, and loading +cmd->iov_size in the caller. + +Reported-by: Li Qiang +Signed-off-by: Paolo Bonzini +(cherry picked from commit 765a707000e838c30b18d712fe6cb3dd8e0435f3) +--- + hw/scsi/megasas.c | 11 ++++++----- + 1 file changed, 6 insertions(+), 5 deletions(-) + +diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c +index a9ffc32..d42d34b 100644 +--- a/hw/scsi/megasas.c ++++ b/hw/scsi/megasas.c +@@ -682,14 +682,14 @@ static int megasas_map_dcmd(MegasasState *s, MegasasCmd *cmd) + trace_megasas_dcmd_invalid_sge(cmd->index, + cmd->frame->header.sge_count); + cmd->iov_size = 0; +- return -1; ++ return -EINVAL; + } + iov_pa = megasas_sgl_get_addr(cmd, &cmd->frame->dcmd.sgl); + iov_size = megasas_sgl_get_len(cmd, &cmd->frame->dcmd.sgl); + pci_dma_sglist_init(&cmd->qsg, PCI_DEVICE(s), 1); + qemu_sglist_add(&cmd->qsg, iov_pa, iov_size); + cmd->iov_size = iov_size; +- return cmd->iov_size; ++ return 0; + } + + static void megasas_finish_dcmd(MegasasCmd *cmd, uint32_t iov_size) +@@ -1562,19 +1562,20 @@ static const struct dcmd_cmd_tbl_t { + + static int megasas_handle_dcmd(MegasasState *s, MegasasCmd *cmd) + { +- int opcode, len; ++ int opcode; + int retval = 0; ++ size_t len; + const struct dcmd_cmd_tbl_t *cmdptr = dcmd_cmd_tbl; + + opcode = le32_to_cpu(cmd->frame->dcmd.opcode); + trace_megasas_handle_dcmd(cmd->index, opcode); +- len = megasas_map_dcmd(s, cmd); +- if (len < 0) { ++ if (megasas_map_dcmd(s, cmd) < 0) { + return MFI_STAT_MEMORY_NOT_AVAILABLE; + } + while (cmdptr->opcode != -1 && cmdptr->opcode != opcode) { + cmdptr++; + } ++ len = cmd->iov_size; + if (cmdptr->opcode == -1) { + trace_megasas_dcmd_unhandled(cmd->index, opcode, len); + retval = megasas_dcmd_dummy(s, cmd); diff --git a/0053-virtio-gpu-fix-resource-leak-in-virgl_cmd_resource_u.patch b/0053-virtio-gpu-fix-resource-leak-in-virgl_cmd_resource_u.patch new file mode 100644 index 0000000..dea94b9 --- /dev/null +++ b/0053-virtio-gpu-fix-resource-leak-in-virgl_cmd_resource_u.patch @@ -0,0 +1,45 @@ +From: Gerd Hoffmann +Date: Mon, 23 Jan 2017 11:26:50 +0100 +Subject: [PATCH] virtio-gpu: fix resource leak in virgl_cmd_resource_unref +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +When the guest sends VIRTIO_GPU_CMD_RESOURCE_UNREF without detaching the +backing storage beforehand (VIRTIO_GPU_CMD_RESOURCE_DETACH_BACKING) +we'll leak memory. + +This patch fixes it for 3d mode, simliar to the 2d mode fix in commit +"b8e2392 virtio-gpu: call cleanup mapping function in resource destroy". + +Reported-by: 李强 +Signed-off-by: Gerd Hoffmann +Message-id: 1485167210-4757-1-git-send-email-kraxel@redhat.com +(cherry picked from commit 5e8e3c4c75c199aa1017db816fca02be2a9f8798) +--- + hw/display/virtio-gpu-3d.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/hw/display/virtio-gpu-3d.c b/hw/display/virtio-gpu-3d.c +index 4cffab5..e78b3c8 100644 +--- a/hw/display/virtio-gpu-3d.c ++++ b/hw/display/virtio-gpu-3d.c +@@ -76,10 +76,18 @@ static void virgl_cmd_resource_unref(VirtIOGPU *g, + struct virtio_gpu_ctrl_command *cmd) + { + struct virtio_gpu_resource_unref unref; ++ struct iovec *res_iovs = NULL; ++ int num_iovs = 0; + + VIRTIO_GPU_FILL_CMD(unref); + trace_virtio_gpu_cmd_res_unref(unref.resource_id); + ++ virgl_renderer_resource_detach_iov(unref.resource_id, ++ &res_iovs, ++ &num_iovs); ++ if (res_iovs != NULL && num_iovs != 0) { ++ virtio_gpu_cleanup_mapping_iov(res_iovs, num_iovs); ++ } + virgl_renderer_resource_unref(unref.resource_id); + } + diff --git a/0054-usb-ccid-check-ccid-apdu-length.patch b/0054-usb-ccid-check-ccid-apdu-length.patch new file mode 100644 index 0000000..5c35157 --- /dev/null +++ b/0054-usb-ccid-check-ccid-apdu-length.patch @@ -0,0 +1,32 @@ +From: Prasad J Pandit +Date: Fri, 3 Feb 2017 00:52:28 +0530 +Subject: [PATCH] usb: ccid: check ccid apdu length + +CCID device emulator uses Application Protocol Data Units(APDU) +to exchange command and responses to and from the host. +The length in these units couldn't be greater than 65536. Add +check to ensure the same. It'd also avoid potential integer +overflow in emulated_apdu_from_guest. + +Reported-by: Li Qiang +Signed-off-by: Prasad J Pandit +Message-id: 20170202192228.10847-1-ppandit@redhat.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit c7dfbf322595ded4e70b626bf83158a9f3807c6a) +--- + hw/usb/dev-smartcard-reader.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/hw/usb/dev-smartcard-reader.c b/hw/usb/dev-smartcard-reader.c +index af4b851..fc32b00 100644 +--- a/hw/usb/dev-smartcard-reader.c ++++ b/hw/usb/dev-smartcard-reader.c +@@ -967,7 +967,7 @@ static void ccid_on_apdu_from_guest(USBCCIDState *s, CCID_XferBlock *recv) + DPRINTF(s, 1, "%s: seq %d, len %d\n", __func__, + recv->hdr.bSeq, len); + ccid_add_pending_answer(s, (CCID_Header *)recv); +- if (s->card) { ++ if (s->card && len <= BULK_OUT_DATA_SIZE) { + ccid_card_apdu_from_guest(s->card, recv->abData, len); + } else { + DPRINTF(s, D_WARN, "warning: discarded apdu\n"); diff --git a/0055-sd-sdhci-check-transfer-mode-register-in-multi-block.patch b/0055-sd-sdhci-check-transfer-mode-register-in-multi-block.patch new file mode 100644 index 0000000..74b06e5 --- /dev/null +++ b/0055-sd-sdhci-check-transfer-mode-register-in-multi-block.patch @@ -0,0 +1,51 @@ +From: Prasad J Pandit +Date: Tue, 28 Feb 2017 12:08:14 +0000 +Subject: [PATCH] sd: sdhci: check transfer mode register in multi block + transfer + +In the SDHCI protocol, the transfer mode register value +is used during multi block transfer to check if block count +register is enabled and should be updated. Transfer mode +register could be set such that, block count register would +not be updated, thus leading to an infinite loop. Add check +to avoid it. + +Reported-by: Wjjzhang +Reported-by: Jiang Xin +Signed-off-by: Prasad J Pandit +Message-id: 20170214185225.7994-3-ppandit@redhat.com +Reviewed-by: Alistair Francis +Signed-off-by: Peter Maydell +(cherry picked from commit 6e86d90352adf6cb08295255220295cf23c4286e) +--- + hw/sd/sdhci.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/hw/sd/sdhci.c b/hw/sd/sdhci.c +index f4cf5c7..fedc786 100644 +--- a/hw/sd/sdhci.c ++++ b/hw/sd/sdhci.c +@@ -485,6 +485,11 @@ static void sdhci_sdma_transfer_multi_blocks(SDHCIState *s) + uint32_t boundary_chk = 1 << (((s->blksize & 0xf000) >> 12) + 12); + uint32_t boundary_count = boundary_chk - (s->sdmasysad % boundary_chk); + ++ if (!(s->trnmod & SDHC_TRNS_BLK_CNT_EN) || !s->blkcnt) { ++ qemu_log_mask(LOG_UNIMP, "infinite transfer is not supported\n"); ++ return; ++ } ++ + /* XXX: Some sd/mmc drivers (for example, u-boot-slp) do not account for + * possible stop at page boundary if initial address is not page aligned, + * allow them to work properly */ +@@ -796,11 +801,6 @@ static void sdhci_data_transfer(void *opaque) + if (s->trnmod & SDHC_TRNS_DMA) { + switch (SDHC_DMA_TYPE(s->hostctl)) { + case SDHC_CTRL_SDMA: +- if ((s->trnmod & SDHC_TRNS_MULTI) && +- (!(s->trnmod & SDHC_TRNS_BLK_CNT_EN) || s->blkcnt == 0)) { +- break; +- } +- + if ((s->blkcnt == 1) || !(s->trnmod & SDHC_TRNS_MULTI)) { + sdhci_sdma_transfer_single_block(s); + } else { diff --git a/0056-usb-ohci-limit-the-number-of-link-eds.patch b/0056-usb-ohci-limit-the-number-of-link-eds.patch new file mode 100644 index 0000000..29761d7 --- /dev/null +++ b/0056-usb-ohci-limit-the-number-of-link-eds.patch @@ -0,0 +1,49 @@ +From: Li Qiang +Date: Tue, 7 Feb 2017 02:23:33 -0800 +Subject: [PATCH] usb: ohci: limit the number of link eds + +The guest may builds an infinite loop with link eds. This patch +limit the number of linked ed to avoid this. + +Signed-off-by: Li Qiang +Message-id: 5899a02e.45ca240a.6c373.93c1@mx.google.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 95ed56939eb2eaa4e2f349fe6dcd13ca4edfd8fb) +--- + hw/usb/hcd-ohci.c | 9 ++++++++- + 1 file changed, 8 insertions(+), 1 deletion(-) + +diff --git a/hw/usb/hcd-ohci.c b/hw/usb/hcd-ohci.c +index 16d9ff7..1af518d 100644 +--- a/hw/usb/hcd-ohci.c ++++ b/hw/usb/hcd-ohci.c +@@ -42,6 +42,8 @@ + + #define OHCI_MAX_PORTS 15 + ++#define ED_LINK_LIMIT 4 ++ + static int64_t usb_frame_time; + static int64_t usb_bit_time; + +@@ -1184,7 +1186,7 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion) + uint32_t next_ed; + uint32_t cur; + int active; +- ++ uint32_t link_cnt = 0; + active = 0; + + if (head == 0) +@@ -1199,6 +1201,11 @@ static int ohci_service_ed_list(OHCIState *ohci, uint32_t head, int completion) + + next_ed = ed.next & OHCI_DPTR_MASK; + ++ if (++link_cnt > ED_LINK_LIMIT) { ++ ohci_die(ohci); ++ return 0; ++ } ++ + if ((ed.head & OHCI_ED_H) || (ed.flags & OHCI_ED_K)) { + uint32_t addr; + /* Cancel pending packets for ED that have been paused. */ diff --git a/0057-display-cirrus-ignore-source-pitch-value-as-needed-i.patch b/0057-display-cirrus-ignore-source-pitch-value-as-needed-i.patch new file mode 100644 index 0000000..a28cb02 --- /dev/null +++ b/0057-display-cirrus-ignore-source-pitch-value-as-needed-i.patch @@ -0,0 +1,69 @@ +From: Bruce Rogers +Date: Mon, 9 Jan 2017 13:35:20 -0700 +Subject: [PATCH] display: cirrus: ignore source pitch value as needed in + blit_is_unsafe + +Commit 4299b90 added a check which is too broad, given that the source +pitch value is not required to be initialized for solid fill operations. +This patch refines the blit_is_unsafe() check to ignore source pitch in +that case. After applying the above commit as a security patch, we +noticed the SLES 11 SP4 guest gui failed to initialize properly. + +Signed-off-by: Bruce Rogers +Message-id: 20170109203520.5619-1-brogers@suse.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 913a87885f589d263e682c2eb6637c6e14538061) +--- + hw/display/cirrus_vga.c | 11 +++++++---- + 1 file changed, 7 insertions(+), 4 deletions(-) + +diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c +index bdb092e..379910d 100644 +--- a/hw/display/cirrus_vga.c ++++ b/hw/display/cirrus_vga.c +@@ -294,7 +294,7 @@ static bool blit_region_is_unsafe(struct CirrusVGAState *s, + return false; + } + +-static bool blit_is_unsafe(struct CirrusVGAState *s) ++static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only) + { + /* should be the case, see cirrus_bitblt_start */ + assert(s->cirrus_blt_width > 0); +@@ -308,6 +308,9 @@ static bool blit_is_unsafe(struct CirrusVGAState *s) + s->cirrus_blt_dstaddr & s->cirrus_addr_mask)) { + return true; + } ++ if (dst_only) { ++ return false; ++ } + if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch, + s->cirrus_blt_srcaddr & s->cirrus_addr_mask)) { + return true; +@@ -673,7 +676,7 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, + + dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask); + +- if (blit_is_unsafe(s)) ++ if (blit_is_unsafe(s, false)) + return 0; + + (*s->cirrus_rop) (s, dst, src, +@@ -691,7 +694,7 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop) + { + cirrus_fill_t rop_func; + +- if (blit_is_unsafe(s)) { ++ if (blit_is_unsafe(s, true)) { + return 0; + } + rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; +@@ -795,7 +798,7 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) + + static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) + { +- if (blit_is_unsafe(s)) ++ if (blit_is_unsafe(s, false)) + return 0; + + return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr, diff --git a/0058-cirrus-handle-negative-pitch-in-cirrus_invalidate_re.patch b/0058-cirrus-handle-negative-pitch-in-cirrus_invalidate_re.patch new file mode 100644 index 0000000..d69a28b --- /dev/null +++ b/0058-cirrus-handle-negative-pitch-in-cirrus_invalidate_re.patch @@ -0,0 +1,47 @@ +From: Wolfgang Bumiller +Date: Wed, 25 Jan 2017 14:48:57 +0100 +Subject: [PATCH] cirrus: handle negative pitch in cirrus_invalidate_region() + +cirrus_invalidate_region() calls memory_region_set_dirty() +on a per-line basis, always ranging from off_begin to +off_begin+bytesperline. With a negative pitch off_begin +marks the top most used address and thus we need to do an +initial shift backwards by a line for negative pitches of +backward blits, otherwise the first iteration covers the +line going from the start offset forwards instead of +backwards. +Additionally since the start address is inclusive, if we +shift by a full `bytesperline` we move to the first address +*not* included in the blit, so we only shift by one less +than bytesperline. + +Signed-off-by: Wolfgang Bumiller +Message-id: 1485352137-29367-1-git-send-email-w.bumiller@proxmox.com + +[ kraxel: codestyle fixes ] + +Signed-off-by: Gerd Hoffmann +(cherry picked from commit f153b563f8cf121aebf5a2fff5f0110faf58ccb3) +--- + hw/display/cirrus_vga.c | 5 +++++ + 1 file changed, 5 insertions(+) + +diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c +index 379910d..0f05e45 100644 +--- a/hw/display/cirrus_vga.c ++++ b/hw/display/cirrus_vga.c +@@ -661,9 +661,14 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin, + int off_cur; + int off_cur_end; + ++ if (off_pitch < 0) { ++ off_begin -= bytesperline - 1; ++ } ++ + for (y = 0; y < lines; y++) { + off_cur = off_begin; + off_cur_end = (off_cur + bytesperline) & s->cirrus_addr_mask; ++ assert(off_cur_end >= off_cur); + memory_region_set_dirty(&s->vga.vram, off_cur, off_cur_end - off_cur); + off_begin += off_pitch; + } diff --git a/0059-cirrus-allow-zero-source-pitch-in-pattern-fill-rops.patch b/0059-cirrus-allow-zero-source-pitch-in-pattern-fill-rops.patch new file mode 100644 index 0000000..63e32a1 --- /dev/null +++ b/0059-cirrus-allow-zero-source-pitch-in-pattern-fill-rops.patch @@ -0,0 +1,99 @@ +From: Wolfgang Bumiller +Date: Tue, 24 Jan 2017 16:35:38 +0100 +Subject: [PATCH] cirrus: allow zero source pitch in pattern fill rops + +The rops used by cirrus_bitblt_common_patterncopy only use +the destination pitch, so the source pitch shoul allowed to +be zero and the blit with used for the range check around the +source address. + +Signed-off-by: Wolfgang Bumiller +Message-id: 1485272138-23249-1-git-send-email-w.bumiller@proxmox.com +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 5858dd1801883309bdd208d72ddb81c4e9fee30c) +--- + hw/display/cirrus_vga.c | 27 +++++++++++++++++++-------- + 1 file changed, 19 insertions(+), 8 deletions(-) + +diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c +index 0f05e45..98f089e 100644 +--- a/hw/display/cirrus_vga.c ++++ b/hw/display/cirrus_vga.c +@@ -272,9 +272,6 @@ static void cirrus_update_memory_access(CirrusVGAState *s); + static bool blit_region_is_unsafe(struct CirrusVGAState *s, + int32_t pitch, int32_t addr) + { +- if (!pitch) { +- return true; +- } + if (pitch < 0) { + int64_t min = addr + + ((int64_t)s->cirrus_blt_height-1) * pitch; +@@ -294,8 +291,11 @@ static bool blit_region_is_unsafe(struct CirrusVGAState *s, + return false; + } + +-static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only) ++static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only, ++ bool zero_src_pitch_ok) + { ++ int32_t check_pitch; ++ + /* should be the case, see cirrus_bitblt_start */ + assert(s->cirrus_blt_width > 0); + assert(s->cirrus_blt_height > 0); +@@ -304,6 +304,10 @@ static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only) + return true; + } + ++ if (!s->cirrus_blt_dstpitch) { ++ return true; ++ } ++ + if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch, + s->cirrus_blt_dstaddr & s->cirrus_addr_mask)) { + return true; +@@ -311,7 +315,13 @@ static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only) + if (dst_only) { + return false; + } +- if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch, ++ ++ check_pitch = s->cirrus_blt_srcpitch; ++ if (!zero_src_pitch_ok && !check_pitch) { ++ check_pitch = s->cirrus_blt_width; ++ } ++ ++ if (blit_region_is_unsafe(s, check_pitch, + s->cirrus_blt_srcaddr & s->cirrus_addr_mask)) { + return true; + } +@@ -681,8 +691,9 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, + + dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask); + +- if (blit_is_unsafe(s, false)) ++ if (blit_is_unsafe(s, false, true)) { + return 0; ++ } + + (*s->cirrus_rop) (s, dst, src, + s->cirrus_blt_dstpitch, 0, +@@ -699,7 +710,7 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop) + { + cirrus_fill_t rop_func; + +- if (blit_is_unsafe(s, true)) { ++ if (blit_is_unsafe(s, true, true)) { + return 0; + } + rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; +@@ -803,7 +814,7 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) + + static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) + { +- if (blit_is_unsafe(s, false)) ++ if (blit_is_unsafe(s, false, false)) + return 0; + + return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr, diff --git a/0060-cirrus-fix-blit-address-mask-handling.patch b/0060-cirrus-fix-blit-address-mask-handling.patch new file mode 100644 index 0000000..9acb06c --- /dev/null +++ b/0060-cirrus-fix-blit-address-mask-handling.patch @@ -0,0 +1,101 @@ +From: Gerd Hoffmann +Date: Wed, 25 Jan 2017 11:09:56 +0100 +Subject: [PATCH] cirrus: fix blit address mask handling + +Apply the cirrus_addr_mask to cirrus_blt_dstaddr and cirrus_blt_srcaddr +right after assigning them, in cirrus_bitblt_start(), instead of having +this all over the place in the cirrus code, and missing a few places. + +Reported-by: Wolfgang Bumiller +Signed-off-by: Gerd Hoffmann +Message-id: 1485338996-17095-1-git-send-email-kraxel@redhat.com +(cherry picked from commit 60cd23e85151525ab26591394c4e7e06fa07d216) +--- + hw/display/cirrus_vga.c | 25 ++++++++++++------------- + 1 file changed, 12 insertions(+), 13 deletions(-) + +diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c +index 98f089e..7db6409 100644 +--- a/hw/display/cirrus_vga.c ++++ b/hw/display/cirrus_vga.c +@@ -309,7 +309,7 @@ static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only, + } + + if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch, +- s->cirrus_blt_dstaddr & s->cirrus_addr_mask)) { ++ s->cirrus_blt_dstaddr)) { + return true; + } + if (dst_only) { +@@ -322,7 +322,7 @@ static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only, + } + + if (blit_region_is_unsafe(s, check_pitch, +- s->cirrus_blt_srcaddr & s->cirrus_addr_mask)) { ++ s->cirrus_blt_srcaddr)) { + return true; + } + +@@ -689,7 +689,7 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, + { + uint8_t *dst; + +- dst = s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask); ++ dst = s->vga.vram_ptr + s->cirrus_blt_dstaddr; + + if (blit_is_unsafe(s, false, true)) { + return 0; +@@ -714,7 +714,7 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop) + return 0; + } + rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; +- rop_func(s, s->vga.vram_ptr + (s->cirrus_blt_dstaddr & s->cirrus_addr_mask), ++ rop_func(s, s->vga.vram_ptr + s->cirrus_blt_dstaddr, + s->cirrus_blt_dstpitch, + s->cirrus_blt_width, s->cirrus_blt_height); + cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, +@@ -732,9 +732,8 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop) + + static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s) + { +- return cirrus_bitblt_common_patterncopy(s, +- s->vga.vram_ptr + ((s->cirrus_blt_srcaddr & ~7) & +- s->cirrus_addr_mask)); ++ return cirrus_bitblt_common_patterncopy(s, s->vga.vram_ptr + ++ (s->cirrus_blt_srcaddr & ~7)); + } + + static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) +@@ -788,10 +787,8 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) + if (notify) + graphic_hw_update(s->vga.con); + +- (*s->cirrus_rop) (s, s->vga.vram_ptr + +- (s->cirrus_blt_dstaddr & s->cirrus_addr_mask), +- s->vga.vram_ptr + +- (s->cirrus_blt_srcaddr & s->cirrus_addr_mask), ++ (*s->cirrus_rop) (s, s->vga.vram_ptr + s->cirrus_blt_dstaddr, ++ s->vga.vram_ptr + s->cirrus_blt_srcaddr, + s->cirrus_blt_dstpitch, s->cirrus_blt_srcpitch, + s->cirrus_blt_width, s->cirrus_blt_height); + +@@ -842,8 +839,7 @@ static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s) + } else { + /* at least one scan line */ + do { +- (*s->cirrus_rop)(s, s->vga.vram_ptr + +- (s->cirrus_blt_dstaddr & s->cirrus_addr_mask), ++ (*s->cirrus_rop)(s, s->vga.vram_ptr + s->cirrus_blt_dstaddr, + s->cirrus_bltbuf, 0, 0, s->cirrus_blt_width, 1); + cirrus_invalidate_region(s, s->cirrus_blt_dstaddr, 0, + s->cirrus_blt_width, 1); +@@ -962,6 +958,9 @@ static void cirrus_bitblt_start(CirrusVGAState * s) + s->cirrus_blt_modeext = s->vga.gr[0x33]; + blt_rop = s->vga.gr[0x32]; + ++ s->cirrus_blt_dstaddr &= s->cirrus_addr_mask; ++ s->cirrus_blt_srcaddr &= s->cirrus_addr_mask; ++ + #ifdef DEBUG_BITBLT + printf("rop=0x%02x mode=0x%02x modeext=0x%02x w=%d h=%d dpitch=%d spitch=%d daddr=0x%08x saddr=0x%08x writemask=0x%02x\n", + blt_rop, diff --git a/0061-cirrus-fix-oob-access-issue-CVE-2017-2615.patch b/0061-cirrus-fix-oob-access-issue-CVE-2017-2615.patch new file mode 100644 index 0000000..1bc7215 --- /dev/null +++ b/0061-cirrus-fix-oob-access-issue-CVE-2017-2615.patch @@ -0,0 +1,45 @@ +From: Li Qiang +Date: Wed, 1 Feb 2017 09:35:01 +0100 +Subject: [PATCH] cirrus: fix oob access issue (CVE-2017-2615) + +When doing bitblt copy in backward mode, we should minus the +blt width first just like the adding in the forward mode. This +can avoid the oob access of the front of vga's vram. + +Signed-off-by: Li Qiang + +{ kraxel: with backward blits (negative pitch) addr is the topmost + address, so check it as-is against vram size ] + +Cc: qemu-stable@nongnu.org +Cc: P J P +Cc: Laszlo Ersek +Cc: Paolo Bonzini +Cc: Wolfgang Bumiller +Fixes: d3532a0db02296e687711b8cdc7791924efccea0 (CVE-2014-8106) +Signed-off-by: Gerd Hoffmann +Message-id: 1485938101-26602-1-git-send-email-kraxel@redhat.com +Reviewed-by: Laszlo Ersek +(cherry picked from commit 62d4c6bd5263bb8413a06c80144fc678df6dfb64) +--- + hw/display/cirrus_vga.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c +index 7db6409..16f27e8 100644 +--- a/hw/display/cirrus_vga.c ++++ b/hw/display/cirrus_vga.c +@@ -274,10 +274,9 @@ static bool blit_region_is_unsafe(struct CirrusVGAState *s, + { + if (pitch < 0) { + int64_t min = addr +- + ((int64_t)s->cirrus_blt_height-1) * pitch; +- int32_t max = addr +- + s->cirrus_blt_width; +- if (min < 0 || max > s->vga.vram_size) { ++ + ((int64_t)s->cirrus_blt_height - 1) * pitch ++ - s->cirrus_blt_width; ++ if (min < -1 || addr >= s->vga.vram_size) { + return true; + } + } else { diff --git a/0062-cirrus-fix-patterncopy-checks.patch b/0062-cirrus-fix-patterncopy-checks.patch new file mode 100644 index 0000000..9c9f151 --- /dev/null +++ b/0062-cirrus-fix-patterncopy-checks.patch @@ -0,0 +1,101 @@ +From: Gerd Hoffmann +Date: Thu, 9 Feb 2017 14:02:20 +0100 +Subject: [PATCH] cirrus: fix patterncopy checks + +The blit_region_is_unsafe checks don't work correctly for the +patterncopy source. It's a fixed-sized region, which doesn't +depend on cirrus_blt_{width,height}. So go do the check in +cirrus_bitblt_common_patterncopy instead, then tell blit_is_unsafe that +it doesn't need to verify the source. Also handle the case where we +blit from cirrus_bitbuf correctly. + +This patch replaces 5858dd1801883309bdd208d72ddb81c4e9fee30c. + +Security impact: I think for the most part error on the safe side this +time, refusing blits which should have been allowed. + +Only exception is placing the blit source at the end of the video ram, +so cirrus_blt_srcaddr + 256 goes beyond the end of video memory. But +even in that case I'm not fully sure this actually allows read access to +host memory. To trick the commit 5858dd18 security checks one has to +pick very small cirrus_blt_{width,height} values, which in turn implies +only a fraction of the blit source will actually be used. + +Cc: Wolfgang Bumiller +Cc: Dr. David Alan Gilbert +Signed-off-by: Gerd Hoffmann +Reviewed-by: Dr. David Alan Gilbert +Reviewed-by: Wolfgang Bumiller +Reviewed-by: Laurent Vivier +Message-id: 1486645341-5010-1-git-send-email-kraxel@redhat.com +(cherry picked from commit 95280c31cda79bb1d0968afc7b19a220b3a9d986) +--- + hw/display/cirrus_vga.c | 36 ++++++++++++++++++++++++++++++------ + 1 file changed, 30 insertions(+), 6 deletions(-) + +diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c +index 16f27e8..6bd13fc 100644 +--- a/hw/display/cirrus_vga.c ++++ b/hw/display/cirrus_vga.c +@@ -683,14 +683,39 @@ static void cirrus_invalidate_region(CirrusVGAState * s, int off_begin, + } + } + +-static int cirrus_bitblt_common_patterncopy(CirrusVGAState * s, +- const uint8_t * src) ++static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videosrc) + { ++ uint32_t patternsize; + uint8_t *dst; ++ uint8_t *src; + + dst = s->vga.vram_ptr + s->cirrus_blt_dstaddr; + +- if (blit_is_unsafe(s, false, true)) { ++ if (videosrc) { ++ switch (s->vga.get_bpp(&s->vga)) { ++ case 8: ++ patternsize = 64; ++ break; ++ case 15: ++ case 16: ++ patternsize = 128; ++ break; ++ case 24: ++ case 32: ++ default: ++ patternsize = 256; ++ break; ++ } ++ s->cirrus_blt_srcaddr &= ~(patternsize - 1); ++ if (s->cirrus_blt_srcaddr + patternsize > s->vga.vram_size) { ++ return 0; ++ } ++ src = s->vga.vram_ptr + s->cirrus_blt_srcaddr; ++ } else { ++ src = s->cirrus_bltbuf; ++ } ++ ++ if (blit_is_unsafe(s, true, true)) { + return 0; + } + +@@ -731,8 +756,7 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop) + + static int cirrus_bitblt_videotovideo_patterncopy(CirrusVGAState * s) + { +- return cirrus_bitblt_common_patterncopy(s, s->vga.vram_ptr + +- (s->cirrus_blt_srcaddr & ~7)); ++ return cirrus_bitblt_common_patterncopy(s, true); + } + + static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) +@@ -831,7 +855,7 @@ static void cirrus_bitblt_cputovideo_next(CirrusVGAState * s) + + if (s->cirrus_srccounter > 0) { + if (s->cirrus_blt_mode & CIRRUS_BLTMODE_PATTERNCOPY) { +- cirrus_bitblt_common_patterncopy(s, s->cirrus_bltbuf); ++ cirrus_bitblt_common_patterncopy(s, false); + the_end: + s->cirrus_srccounter = 0; + cirrus_bitblt_reset(s); diff --git a/0063-Revert-cirrus-allow-zero-source-pitch-in-pattern-fil.patch b/0063-Revert-cirrus-allow-zero-source-pitch-in-pattern-fil.patch new file mode 100644 index 0000000..70d1439 --- /dev/null +++ b/0063-Revert-cirrus-allow-zero-source-pitch-in-pattern-fil.patch @@ -0,0 +1,100 @@ +From: Gerd Hoffmann +Date: Thu, 9 Feb 2017 14:02:21 +0100 +Subject: [PATCH] Revert "cirrus: allow zero source pitch in pattern fill rops" + +This reverts commit 5858dd1801883309bdd208d72ddb81c4e9fee30c. + +Conflicts: + hw/display/cirrus_vga.c + +Cc: Wolfgang Bumiller +Cc: Dr. David Alan Gilbert +Signed-off-by: Gerd Hoffmann +Reviewed-by: Dr. David Alan Gilbert +Reviewed-by: Laurent Vivier +Message-id: 1486645341-5010-2-git-send-email-kraxel@redhat.com +(cherry picked from commit 12e97ec39931e5321645fd483ab761319d48bf16) +--- + hw/display/cirrus_vga.c | 26 ++++++++------------------ + 1 file changed, 8 insertions(+), 18 deletions(-) + +diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c +index 6bd13fc..0e47cf8 100644 +--- a/hw/display/cirrus_vga.c ++++ b/hw/display/cirrus_vga.c +@@ -272,6 +272,9 @@ static void cirrus_update_memory_access(CirrusVGAState *s); + static bool blit_region_is_unsafe(struct CirrusVGAState *s, + int32_t pitch, int32_t addr) + { ++ if (!pitch) { ++ return true; ++ } + if (pitch < 0) { + int64_t min = addr + + ((int64_t)s->cirrus_blt_height - 1) * pitch +@@ -290,11 +293,8 @@ static bool blit_region_is_unsafe(struct CirrusVGAState *s, + return false; + } + +-static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only, +- bool zero_src_pitch_ok) ++static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only) + { +- int32_t check_pitch; +- + /* should be the case, see cirrus_bitblt_start */ + assert(s->cirrus_blt_width > 0); + assert(s->cirrus_blt_height > 0); +@@ -303,10 +303,6 @@ static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only, + return true; + } + +- if (!s->cirrus_blt_dstpitch) { +- return true; +- } +- + if (blit_region_is_unsafe(s, s->cirrus_blt_dstpitch, + s->cirrus_blt_dstaddr)) { + return true; +@@ -314,13 +310,7 @@ static bool blit_is_unsafe(struct CirrusVGAState *s, bool dst_only, + if (dst_only) { + return false; + } +- +- check_pitch = s->cirrus_blt_srcpitch; +- if (!zero_src_pitch_ok && !check_pitch) { +- check_pitch = s->cirrus_blt_width; +- } +- +- if (blit_region_is_unsafe(s, check_pitch, ++ if (blit_region_is_unsafe(s, s->cirrus_blt_srcpitch, + s->cirrus_blt_srcaddr)) { + return true; + } +@@ -715,7 +705,7 @@ static int cirrus_bitblt_common_patterncopy(CirrusVGAState *s, bool videosrc) + src = s->cirrus_bltbuf; + } + +- if (blit_is_unsafe(s, true, true)) { ++ if (blit_is_unsafe(s, true)) { + return 0; + } + +@@ -734,7 +724,7 @@ static int cirrus_bitblt_solidfill(CirrusVGAState *s, int blt_rop) + { + cirrus_fill_t rop_func; + +- if (blit_is_unsafe(s, true, true)) { ++ if (blit_is_unsafe(s, true)) { + return 0; + } + rop_func = cirrus_fill[rop_to_index[blt_rop]][s->cirrus_blt_pixelwidth - 1]; +@@ -834,7 +824,7 @@ static int cirrus_do_copy(CirrusVGAState *s, int dst, int src, int w, int h) + + static int cirrus_bitblt_videotovideo_copy(CirrusVGAState * s) + { +- if (blit_is_unsafe(s, false, false)) ++ if (blit_is_unsafe(s, false)) + return 0; + + return cirrus_do_copy(s, s->cirrus_blt_dstaddr - s->vga.start_addr, diff --git a/0064-cirrus-add-blit_is_unsafe-call-to-cirrus_bitblt_cput.patch b/0064-cirrus-add-blit_is_unsafe-call-to-cirrus_bitblt_cput.patch new file mode 100644 index 0000000..96766e6 --- /dev/null +++ b/0064-cirrus-add-blit_is_unsafe-call-to-cirrus_bitblt_cput.patch @@ -0,0 +1,46 @@ +From: Gerd Hoffmann +Date: Wed, 8 Feb 2017 11:18:36 +0100 +Subject: [PATCH] cirrus: add blit_is_unsafe call to cirrus_bitblt_cputovideo + (CVE-2017-2620) + +CIRRUS_BLTMODE_MEMSYSSRC blits do NOT check blit destination +and blit width, at all. Oops. Fix it. + +Security impact: high. + +The missing blit destination check allows to write to host memory. +Basically same as CVE-2014-8106 for the other blit variants. + +Cc: qemu-stable@nongnu.org +Signed-off-by: Gerd Hoffmann +(cherry picked from commit 92f2b88cea48c6aeba8de568a45f2ed958f3c298) +--- + hw/display/cirrus_vga.c | 8 ++++++++ + 1 file changed, 8 insertions(+) + +diff --git a/hw/display/cirrus_vga.c b/hw/display/cirrus_vga.c +index 0e47cf8..a093dc8 100644 +--- a/hw/display/cirrus_vga.c ++++ b/hw/display/cirrus_vga.c +@@ -899,6 +899,10 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s) + { + int w; + ++ if (blit_is_unsafe(s, true)) { ++ return 0; ++ } ++ + s->cirrus_blt_mode &= ~CIRRUS_BLTMODE_MEMSYSSRC; + s->cirrus_srcptr = &s->cirrus_bltbuf[0]; + s->cirrus_srcptr_end = &s->cirrus_bltbuf[0]; +@@ -924,6 +928,10 @@ static int cirrus_bitblt_cputovideo(CirrusVGAState * s) + } + s->cirrus_srccounter = s->cirrus_blt_srcpitch * s->cirrus_blt_height; + } ++ ++ /* the blit_is_unsafe call above should catch this */ ++ assert(s->cirrus_blt_srcpitch <= CIRRUS_BLTBUFSIZE); ++ + s->cirrus_srcptr = s->cirrus_bltbuf; + s->cirrus_srcptr_end = s->cirrus_bltbuf + s->cirrus_blt_srcpitch; + cirrus_update_memory_access(s); diff --git a/qemu.spec b/qemu.spec index e5594a3..f0a94e2 100644 --- a/qemu.spec +++ b/qemu.spec @@ -65,7 +65,7 @@ Summary: QEMU is a FAST! processor emulator Name: qemu Version: 2.6.2 -Release: 6%{?rcrel}%{?dist} +Release: 7%{?rcrel}%{?dist} Epoch: 2 License: GPLv2+ and LGPLv2+ and BSD Group: Development/Tools @@ -201,10 +201,45 @@ Patch0045: 0045-virtio-gpu-fix-information-leak-in-capset-get-dispat.patch # CVE-2016-9912: virtio-gpu: memory leakage when destroying gpu resource (bz # #1402285) Patch0046: 0046-virtio-gpu-call-cleanup-mapping-function-in-resource.patch +# CVE-2017-5525: audio: memory leakage in ac97 (bz #1414110) +Patch0047: 0047-audio-ac97-add-exit-function.patch +# CVE-2017-5526: audio: memory leakage in es1370 (bz #1414210) +Patch0048: 0048-audio-es1370-add-exit-function.patch +# CVE-2016-10155 watchdog: memory leakage in i6300esb (bz #1415200) +Patch0049: 0049-watchdog-6300esb-add-exit-function.patch +# CVE-2017-5552: virtio-gpu-3d: memory leakage (bz #1415283) +Patch0050: 0050-virtio-gpu-3d-fix-memory-leak-in-resource-attach-bac.patch +# CVE-2017-5667: sd: sdhci OOB access during multi block transfer (bz +# #1417560) +Patch0051: 0051-sd-sdhci-check-data-length-during-dma_memory_read.patch +# CVE-2017-5857: virtio-gpu-3d: host memory leakage in +# virgl_cmd_resource_unref (bz #1418383) +Patch0052: 0052-megasas-fix-guest-triggered-memory-leak.patch +# CVE-2017-5856: scsi: megasas: memory leakage (bz #1418344) +Patch0053: 0053-virtio-gpu-fix-resource-leak-in-virgl_cmd_resource_u.patch +# CVE-2017-5898: usb: integer overflow in emulated_apdu_from_guest (bz +# #1419700) +Patch0054: 0054-usb-ccid-check-ccid-apdu-length.patch +# CVE-2017-5987: sd: infinite loop issue in multi block transfers (bz +# #1422001) +Patch0055: 0055-sd-sdhci-check-transfer-mode-register-in-multi-block.patch +# CVE-2017-6505: usb: an infinite loop issue in ohci_service_ed_list (bz +# #1429434) +Patch0056: 0056-usb-ohci-limit-the-number-of-link-eds.patch +# CVE-2017-2615: cirrus: oob access while doing bitblt copy backward (bz +# #1418206) +Patch0057: 0057-display-cirrus-ignore-source-pitch-value-as-needed-i.patch +Patch0058: 0058-cirrus-handle-negative-pitch-in-cirrus_invalidate_re.patch +Patch0059: 0059-cirrus-allow-zero-source-pitch-in-pattern-fill-rops.patch +Patch0060: 0060-cirrus-fix-blit-address-mask-handling.patch +Patch0061: 0061-cirrus-fix-oob-access-issue-CVE-2017-2615.patch +# CVE-2017-2620: cirrus: potential arbitrary code execution (bz #1425419) +Patch0062: 0062-cirrus-fix-patterncopy-checks.patch +Patch0063: 0063-Revert-cirrus-allow-zero-source-pitch-in-pattern-fil.patch +Patch0064: 0064-cirrus-add-blit_is_unsafe-call-to-cirrus_bitblt_cput.patch # documentation deps -BuildRequires: texi2html BuildRequires: texinfo # For /usr/bin/pod2man BuildRequires: perl-podlators @@ -1663,6 +1698,26 @@ getent passwd qemu >/dev/null || \ %changelog +* Wed Mar 15 2017 Cole Robinson - 2:2.6.2-7 +- CVE-2017-5525: audio: memory leakage in ac97 (bz #1414110) +- CVE-2017-5526: audio: memory leakage in es1370 (bz #1414210) +- CVE-2016-10155 watchdog: memory leakage in i6300esb (bz #1415200) +- CVE-2017-5552: virtio-gpu-3d: memory leakage (bz #1415283) +- CVE-2017-5667: sd: sdhci OOB access during multi block transfer (bz + #1417560) +- CVE-2017-5857: virtio-gpu-3d: host memory leakage in + virgl_cmd_resource_unref (bz #1418383) +- CVE-2017-5856: scsi: megasas: memory leakage (bz #1418344) +- CVE-2017-5898: usb: integer overflow in emulated_apdu_from_guest (bz + #1419700) +- CVE-2017-5987: sd: infinite loop issue in multi block transfers (bz + #1422001) +- CVE-2017-6505: usb: an infinite loop issue in ohci_service_ed_list (bz + #1429434) +- CVE-2017-2615: cirrus: oob access while doing bitblt copy backward (bz + #1418206) +- CVE-2017-2620: cirrus: potential arbitrary code execution (bz #1425419) + * Mon Jan 16 2017 Cole Robinson - 2:2.6.2-6 - CVE-2016-6836: vmxnet: Information leakage in vmxnet3_complete_packet (bz #1366370)