Hello community, here is the log from the commit of package kvm for openSUSE:12.1:Update:Test checked in at 2011-12-19 18:18:21 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:12.1:Update:Test/kvm (Old) and /work/SRC/openSUSE:12.1:Update:Test/.kvm.new (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "kvm", Maintainer is "brog...@suse.com" Changes: -------- --- /work/SRC/openSUSE:12.1:Update:Test/kvm/kvm.changes 2011-12-05 15:43:23.000000000 +0100 +++ /work/SRC/openSUSE:12.1:Update:Test/.kvm.new/kvm.changes 2011-12-19 18:18:23.000000000 +0100 @@ -1,0 +2,5 @@ +Thu Dec 15 15:46:52 UTC 2011 - vci...@suse.com + +- fix for CVE-2011-3346 (bnc#728664) + +------------------------------------------------------------------- New: ---- kvm-qemu-preXX-scsi-disk-commonize-iovec-creation-between-reads-and.patch kvm-qemu-preXX-scsi-disk-lazily-allocate-bounce-buffer.patch ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ kvm.spec ++++++ --- /var/tmp/diff_new_pack.3kEF9t/_old 2011-12-19 18:18:24.000000000 +0100 +++ /var/tmp/diff_new_pack.3kEF9t/_new 2011-12-19 18:18:24.000000000 +0100 @@ -14,10 +14,9 @@ # Please submit bugfixes or comments via http://bugs.opensuse.org/ # - -# norootforbuild # icecream 0 + %bcond_with spice %define package_true_version 0.15.1 @@ -44,9 +43,21 @@ %define using_buildservice 0%{?opensuse_bs} Name: kvm -BuildRequires: SDL-devel alsa alsa-devel gnutls-devel libaio-devel -BuildRequires: libcurl-devel libpulse-devel ncurses-devel pciutils-devel perl -BuildRequires: glib2-devel libattr-devel python texinfo xfsprogs-devel +BuildRequires: SDL-devel +BuildRequires: alsa +BuildRequires: alsa-devel +BuildRequires: glib2-devel +BuildRequires: gnutls-devel +BuildRequires: libaio-devel +BuildRequires: libattr-devel +BuildRequires: libcurl-devel +BuildRequires: libpulse-devel +BuildRequires: ncurses-devel +BuildRequires: pciutils-devel +BuildRequires: perl +BuildRequires: python +BuildRequires: texinfo +BuildRequires: xfsprogs-devel %if 0%{?suse_version} >= 1130 BuildRequires: brlapi-devel %endif @@ -71,7 +82,8 @@ %if 0%{?suse_version} >= 1130 # Spice support does not currently build with -Werror on 32-bit platforms %ifnarch %ix86 -BuildRequires: libspice-server-devel spice-devel +BuildRequires: libspice-server-devel +BuildRequires: spice-devel %endif %endif %endif @@ -82,9 +94,9 @@ %if 0%{?suse_version} < 1110 Requires: kvm-kmp %endif -License: BSD3c ; GPLv2 ; GPLv2+ ; LGPLv2.1+ ; MIT -Group: System/Kernel Summary: Kernel-based Virtual Machine +License: BSD-3-Clause ; GPL-2.0 ; GPL-2.0+ ; LGPL-2.1+ ; MIT +Group: System/Kernel Url: http://www.linux-kvm.org Version: %{package_true_version} Release: 0 @@ -130,6 +142,8 @@ Patch108: kvm-qemu-preXX-block-curl-Don-t-finish-AIOCBs-too-early.patch Patch109: kvm-qemu-preXX-e1000-Don-t-set-the-Capabilities-List-bit.patch Patch110: kvm-qemu-preXX-ccid-Fix-buffer-overrun-in-handling-of-VSC_ATR-message.patch +Patch111: kvm-qemu-preXX-scsi-disk-commonize-iovec-creation-between-reads-and.patch +Patch112: kvm-qemu-preXX-scsi-disk-lazily-allocate-bounce-buffer.patch Patch150: qemu-kvm-common-code-fixes-for-s390-build.patch @@ -230,6 +244,8 @@ %patch108 -p1 %patch109 -p1 %patch110 -p1 +%patch111 -p1 +%patch112 -p1 %patch150 -p1 ++++++ kvm-qemu-preXX-scsi-disk-commonize-iovec-creation-between-reads-and.patch ++++++ >From 103b40f51e4012b3b0ad20f615562a1806d7f49a Mon Sep 17 00:00:00 2001 From: Paolo Bonzini <pbonz...@redhat.com> Date: Fri, 16 Sep 2011 16:40:03 +0200 Subject: [PATCH] scsi-disk: commonize iovec creation between reads and writes Also, consistently use qiov.size instead of iov.iov_len. Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> Signed-off-by: Kevin Wolf <kw...@redhat.com> --- hw/scsi-disk.c | 42 ++++++++++++++++++------------------------ 1 files changed, 18 insertions(+), 24 deletions(-) Index: qemu-kvm-0.15.1/hw/scsi-disk.c =================================================================== --- qemu-kvm-0.15.1.orig/hw/scsi-disk.c +++ qemu-kvm-0.15.1/hw/scsi-disk.c @@ -134,6 +134,13 @@ static void scsi_cancel_io(SCSIRequest * r->req.aiocb = NULL; } +static uint32_t scsi_init_iovec(SCSIDiskReq *r) +{ + r->iov.iov_len = MIN(r->sector_count * 512, SCSI_DMA_BUF_SIZE); + qemu_iovec_init_external(&r->qiov, &r->iov, 1); + return r->qiov.size / 512; +} + static void scsi_read_complete(void * opaque, int ret) { SCSIDiskReq *r = (SCSIDiskReq *)opaque; @@ -147,12 +154,12 @@ static void scsi_read_complete(void * op } } - DPRINTF("Data ready tag=0x%x len=%zd\n", r->req.tag, r->iov.iov_len); + DPRINTF("Data ready tag=0x%x len=%zd\n", r->req.tag, r->qiov.size); - n = r->iov.iov_len / 512; + n = r->qiov.size / 512; r->sector += n; r->sector_count -= n; - scsi_req_data(&r->req, r->iov.iov_len); + scsi_req_data(&r->req, r->qiov.size); } @@ -184,12 +191,7 @@ static void scsi_read_data(SCSIRequest * return; } - n = r->sector_count; - if (n > SCSI_DMA_BUF_SIZE / 512) - n = SCSI_DMA_BUF_SIZE / 512; - - r->iov.iov_len = n * 512; - qemu_iovec_init_external(&r->qiov, &r->iov, 1); + n = scsi_init_iovec(r); r->req.aiocb = bdrv_aio_readv(s->bs, r->sector, &r->qiov, n, scsi_read_complete, r); if (r->req.aiocb == NULL) { @@ -242,7 +244,6 @@ static int scsi_handle_rw_error(SCSIDisk static void scsi_write_complete(void * opaque, int ret) { SCSIDiskReq *r = (SCSIDiskReq *)opaque; - uint32_t len; uint32_t n; r->req.aiocb = NULL; @@ -253,19 +254,15 @@ static void scsi_write_complete(void * o } } - n = r->iov.iov_len / 512; + n = r->qiov.size / 512; r->sector += n; r->sector_count -= n; if (r->sector_count == 0) { scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE)); } else { - len = r->sector_count * 512; - if (len > SCSI_DMA_BUF_SIZE) { - len = SCSI_DMA_BUF_SIZE; - } - r->iov.iov_len = len; - DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, len); - scsi_req_data(&r->req, len); + scsi_init_iovec(r); + DPRINTF("Write complete tag=0x%x more=%d\n", r->req.tag, r->qiov.size); + scsi_req_data(&r->req, r->qiov.size); } } @@ -284,16 +281,15 @@ static void scsi_write_data(SCSIRequest return; } - n = r->iov.iov_len / 512; + n = r->qiov.size / 512; if (n) { - qemu_iovec_init_external(&r->qiov, &r->iov, 1); r->req.aiocb = bdrv_aio_writev(s->bs, r->sector, &r->qiov, n, - scsi_write_complete, r); + scsi_write_complete, r); if (r->req.aiocb == NULL) { scsi_write_complete(r, -ENOMEM); } } else { - /* Invoke completion routine to fetch data from host. */ + /* Called for the first time. Ask the driver to send us more data. */ scsi_write_complete(r, 0); } } ++++++ kvm-qemu-preXX-scsi-disk-lazily-allocate-bounce-buffer.patch ++++++ >From 7285477ab11831b1cf56e45878a89170dd06d9b9 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini <pbonz...@redhat.com> Date: Fri, 16 Sep 2011 16:40:04 +0200 Subject: [PATCH] scsi-disk: lazily allocate bounce buffer It will not be needed for reads and writes if the HBA provides a sglist. In addition, this lets scsi-disk refuse commands with an excessive allocation length, as well as limit memory on usual well-behaved guests. Signed-off-by: Paolo Bonzini <pbonz...@redhat.com> Signed-off-by: Kevin Wolf <kw...@redhat.com> --- hw/scsi-disk.c | 44 +++++++++++++++++++++++++++++++++----------- 1 files changed, 33 insertions(+), 11 deletions(-) Index: qemu-kvm-0.15.1/hw/scsi-disk.c =================================================================== --- qemu-kvm-0.15.1.orig/hw/scsi-disk.c +++ qemu-kvm-0.15.1/hw/scsi-disk.c @@ -54,6 +54,7 @@ typedef struct SCSIDiskReq { /* Both sector and sector_count are in terms of qemu 512 byte blocks. */ uint64_t sector; uint32_t sector_count; + uint32_t buflen; struct iovec iov; QEMUIOVector qiov; uint32_t status; @@ -78,18 +79,15 @@ struct SCSIDiskState }; static int scsi_handle_rw_error(SCSIDiskReq *r, int error, int type); -static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf); +static int scsi_disk_emulate_command(SCSIDiskReq *r); static SCSIRequest *scsi_new_request(SCSIDevice *d, uint32_t tag, uint32_t lun, void *hba_private) { SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, d); SCSIRequest *req; - SCSIDiskReq *r; req = scsi_req_alloc(sizeof(SCSIDiskReq), &s->qdev, tag, lun, hba_private); - r = DO_UPCAST(SCSIDiskReq, req, req); - r->iov.iov_base = qemu_blockalign(s->bs, SCSI_DMA_BUF_SIZE); return req; } @@ -97,7 +95,9 @@ static void scsi_free_request(SCSIReques { SCSIDiskReq *r = DO_UPCAST(SCSIDiskReq, req, req); - qemu_vfree(r->iov.iov_base); + if (r->iov.iov_base) { + qemu_vfree(r->iov.iov_base); + } } static void scsi_disk_clear_sense(SCSIDiskState *s) @@ -136,7 +136,13 @@ static void scsi_cancel_io(SCSIRequest * static uint32_t scsi_init_iovec(SCSIDiskReq *r) { - r->iov.iov_len = MIN(r->sector_count * 512, SCSI_DMA_BUF_SIZE); + SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, r->req.dev); + + if (!r->iov.iov_base) { + r->buflen = SCSI_DMA_BUF_SIZE; + r->iov.iov_base = qemu_blockalign(s->bs, r->buflen); + } + r->iov.iov_len = MIN(r->sector_count * 512, r->buflen); qemu_iovec_init_external(&r->qiov, &r->iov, 1); return r->qiov.size / 512; } @@ -320,7 +326,7 @@ static void scsi_dma_restart_bh(void *op scsi_write_data(&r->req); break; case SCSI_REQ_STATUS_RETRY_FLUSH: - ret = scsi_disk_emulate_command(r, r->iov.iov_base); + ret = scsi_disk_emulate_command(r); if (ret == 0) { scsi_command_complete(r, GOOD, SENSE_CODE(NO_SENSE)); } @@ -820,14 +826,32 @@ static int scsi_disk_emulate_read_toc(SC return toclen; } -static int scsi_disk_emulate_command(SCSIDiskReq *r, uint8_t *outbuf) +static int scsi_disk_emulate_command(SCSIDiskReq *r) { SCSIRequest *req = &r->req; SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); uint64_t nb_sectors; + uint8_t *outbuf; int buflen = 0; int ret; + if (!r->iov.iov_base) { + /* + * FIXME: we shouldn't return anything bigger than 4k, but the code + * requires the buffer to be as big as req->cmd.xfer in several + * places. So, do not allow CDBs with a very large ALLOCATION + * LENGTH. The real fix would be to modify scsi_read_data and + * dma_buf_read, so that they return data beyond the buflen + * as all zeros. + */ + if (req->cmd.xfer > 65536) { + goto illegal_request; + } + r->buflen = MAX(4096, req->cmd.xfer); + r->iov.iov_base = qemu_blockalign(s->bs, r->buflen); + } + + outbuf = r->iov.iov_base; switch (req->cmd.buf[0]) { case TEST_UNIT_READY: if (!bdrv_is_inserted(s->bs)) @@ -1005,11 +1029,9 @@ static int32_t scsi_send_command(SCSIReq SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, req->dev); int32_t len; uint8_t command; - uint8_t *outbuf; int rc; command = buf[0]; - outbuf = (uint8_t *)r->iov.iov_base; DPRINTF("Command: lun=%d tag=0x%x data=0x%02x", req->lun, req->tag, buf[0]); if (scsi_req_parse(&r->req, buf) != 0) { @@ -1056,7 +1078,7 @@ static int32_t scsi_send_command(SCSIReq case REPORT_LUNS: case VERIFY: case REZERO_UNIT: - rc = scsi_disk_emulate_command(r, outbuf); + rc = scsi_disk_emulate_command(r); if (rc < 0) { return 0; } -- To unsubscribe, e-mail: opensuse-commit+unsubscr...@opensuse.org For additional commands, e-mail: opensuse-commit+h...@opensuse.org