Merge branch 'master' into f24

This commit is contained in:
Cole Robinson 2016-06-22 10:33:54 -04:00
commit 9ddf6d447d
18 changed files with 907 additions and 1 deletions

View File

@ -0,0 +1,32 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Thu, 7 Apr 2016 15:56:02 +0530
Subject: [PATCH] net: mipsnet: check packet length against buffer
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 <oleksandr.bazhaniuk@intel.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Jason Wang <jasowang@redhat.com>
(cherry picked from commit 3af9187fc6caaf415ab9c0c6d92c9678f65cb17f)
---
hw/net/mipsnet.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/hw/net/mipsnet.c b/hw/net/mipsnet.c
index 740cd98..cf8b823 100644
--- a/hw/net/mipsnet.c
+++ b/hw/net/mipsnet.c
@@ -83,6 +83,9 @@ static ssize_t mipsnet_receive(NetClientState *nc, const uint8_t *buf, size_t si
if (!mipsnet_can_receive(nc))
return 0;
+ if (size >= sizeof(s->rx_buffer)) {
+ return 0;
+ }
s->busy = 1;
/* Just accept everything. */

View File

@ -0,0 +1,100 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Mon, 23 May 2016 16:18:05 +0530
Subject: [PATCH] scsi: pvscsi: check command descriptor ring buffer size
(CVE-2016-4952)
Vmware Paravirtual SCSI emulation uses command descriptors to
process SCSI commands. These descriptors come with their ring
buffers. A guest could set the ring buffer size to an arbitrary
value leading to OOB access issue. Add check to avoid it.
Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Cc: qemu-stable@nongnu.org
Message-Id: <1464000485-27041-1-git-send-email-ppandit@redhat.com>
Reviewed-by: Shmulik Ladkani <shmulik.ladkani@ravellosystems.com>
Reviewed-by: Dmitry Fleytman <dmitry@daynix.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 3e831b40e015ba34dfb55ff11f767001839425ff)
---
hw/scsi/vmw_pvscsi.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
diff --git a/hw/scsi/vmw_pvscsi.c b/hw/scsi/vmw_pvscsi.c
index e690b4e..e1d6d06 100644
--- a/hw/scsi/vmw_pvscsi.c
+++ b/hw/scsi/vmw_pvscsi.c
@@ -153,7 +153,7 @@ pvscsi_log2(uint32_t input)
return log;
}
-static void
+static int
pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri)
{
int i;
@@ -161,6 +161,10 @@ pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri)
uint32_t req_ring_size, cmp_ring_size;
m->rs_pa = ri->ringsStatePPN << VMW_PAGE_SHIFT;
+ if ((ri->reqRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES)
+ || (ri->cmpRingNumPages > PVSCSI_SETUP_RINGS_MAX_NUM_PAGES)) {
+ return -1;
+ }
req_ring_size = ri->reqRingNumPages * PVSCSI_MAX_NUM_REQ_ENTRIES_PER_PAGE;
cmp_ring_size = ri->cmpRingNumPages * PVSCSI_MAX_NUM_CMP_ENTRIES_PER_PAGE;
txr_len_log2 = pvscsi_log2(req_ring_size - 1);
@@ -192,15 +196,20 @@ pvscsi_ring_init_data(PVSCSIRingInfo *m, PVSCSICmdDescSetupRings *ri)
/* Flush ring state page changes */
smp_wmb();
+
+ return 0;
}
-static void
+static int
pvscsi_ring_init_msg(PVSCSIRingInfo *m, PVSCSICmdDescSetupMsgRing *ri)
{
int i;
uint32_t len_log2;
uint32_t ring_size;
+ if (ri->numPages > PVSCSI_SETUP_MSG_RING_MAX_NUM_PAGES) {
+ return -1;
+ }
ring_size = ri->numPages * PVSCSI_MAX_NUM_MSG_ENTRIES_PER_PAGE;
len_log2 = pvscsi_log2(ring_size - 1);
@@ -220,6 +229,8 @@ pvscsi_ring_init_msg(PVSCSIRingInfo *m, PVSCSICmdDescSetupMsgRing *ri)
/* Flush ring state page changes */
smp_wmb();
+
+ return 0;
}
static void
@@ -770,7 +781,10 @@ pvscsi_on_cmd_setup_rings(PVSCSIState *s)
trace_pvscsi_on_cmd_arrived("PVSCSI_CMD_SETUP_RINGS");
pvscsi_dbg_dump_tx_rings_config(rc);
- pvscsi_ring_init_data(&s->rings, rc);
+ if (pvscsi_ring_init_data(&s->rings, rc) < 0) {
+ return PVSCSI_COMMAND_PROCESSING_FAILED;
+ }
+
s->rings_info_valid = TRUE;
return PVSCSI_COMMAND_PROCESSING_SUCCEEDED;
}
@@ -850,7 +864,9 @@ pvscsi_on_cmd_setup_msg_ring(PVSCSIState *s)
}
if (s->rings_info_valid) {
- pvscsi_ring_init_msg(&s->rings, rc);
+ if (pvscsi_ring_init_msg(&s->rings, rc) < 0) {
+ return PVSCSI_COMMAND_PROCESSING_FAILED;
+ }
s->msg_ring_info_valid = TRUE;
}
return sizeof(PVSCSICmdDescSetupMsgRing) / sizeof(uint32_t);

View File

@ -0,0 +1,46 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Tue, 24 May 2016 13:37:44 +0530
Subject: [PATCH] scsi: mptsas: infinite loop while fetching requests
The LSI SAS1068 Host Bus Adapter emulator in Qemu, periodically
looks for requests and fetches them. A loop doing that in
mptsas_fetch_requests() could run infinitely if 's->state' was
not operational. Move check to avoid such a loop.
Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Cc: qemu-stable@nongnu.org
Message-Id: <1464077264-25473-1-git-send-email-ppandit@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 06630554ccbdd25780aa03c3548aaff1eb56dffd)
---
hw/scsi/mptsas.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
diff --git a/hw/scsi/mptsas.c b/hw/scsi/mptsas.c
index 499c146..be88e16 100644
--- a/hw/scsi/mptsas.c
+++ b/hw/scsi/mptsas.c
@@ -754,11 +754,6 @@ static void mptsas_fetch_request(MPTSASState *s)
hwaddr addr;
int size;
- if (s->state != MPI_IOC_STATE_OPERATIONAL) {
- mptsas_set_fault(s, MPI_IOCSTATUS_INVALID_STATE);
- return;
- }
-
/* Read the message header from the guest first. */
addr = s->host_mfa_high_addr | MPTSAS_FIFO_GET(s, request_post);
pci_dma_read(pci, addr, req, sizeof(hdr));
@@ -789,6 +784,10 @@ static void mptsas_fetch_requests(void *opaque)
{
MPTSASState *s = opaque;
+ if (s->state != MPI_IOC_STATE_OPERATIONAL) {
+ mptsas_set_fault(s, MPI_IOCSTATUS_INVALID_STATE);
+ return;
+ }
while (!MPTSAS_FIFO_EMPTY(s, request_post)) {
mptsas_fetch_request(s);
}

View File

@ -0,0 +1,31 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Wed, 25 May 2016 16:01:29 +0530
Subject: [PATCH] scsi: megasas: use appropriate property buffer size
When setting MegaRAID SAS controller properties via MegaRAID
Firmware Interface(MFI) commands, a user supplied size parameter
is used to set property value. Use appropriate size value to avoid
OOB access issues.
Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <1464172291-2856-2-git-send-email-ppandit@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 1b85898025c4cd95dce673d15e67e60e98e91731)
---
hw/scsi/megasas.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index a63a581..dcbd3e1 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -1446,7 +1446,7 @@ static int megasas_dcmd_set_properties(MegasasState *s, MegasasCmd *cmd)
dcmd_size);
return MFI_STAT_INVALID_PARAMETER;
}
- dma_buf_write((uint8_t *)&info, cmd->iov_size, &cmd->qsg);
+ dma_buf_write((uint8_t *)&info, dcmd_size, &cmd->qsg);
trace_megasas_dcmd_unsupported(cmd->index, cmd->iov_size);
return MFI_STAT_OK;
}

View File

@ -0,0 +1,31 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Wed, 25 May 2016 17:41:44 +0530
Subject: [PATCH] scsi: megasas: initialise local configuration data buffer
When reading MegaRAID SAS controller configuration via MegaRAID
Firmware Interface(MFI) commands, routine megasas_dcmd_cfg_read
uses an uninitialised local data buffer. Initialise this buffer
to avoid stack information leakage.
Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <1464178304-12831-1-git-send-email-ppandit@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit d37af740730dbbb93960cd318e040372d04d6dcf)
---
hw/scsi/megasas.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index dcbd3e1..bf642d4 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -1293,7 +1293,7 @@ static int megasas_dcmd_ld_get_info(MegasasState *s, MegasasCmd *cmd)
static int megasas_dcmd_cfg_read(MegasasState *s, MegasasCmd *cmd)
{
- uint8_t data[4096];
+ uint8_t data[4096] = { 0 };
struct mfi_config_data *info;
int num_pd_disks = 0, array_offset, ld_offset;
BusChild *kid;

View File

@ -0,0 +1,33 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Wed, 25 May 2016 17:55:10 +0530
Subject: [PATCH] scsi: megasas: check 'read_queue_head' index value
While doing MegaRAID SAS controller command frame lookup, routine
'megasas_lookup_frame' uses 'read_queue_head' value as an index
into 'frames[MEGASAS_MAX_FRAMES=2048]' array. Limit its value
within array bounds to avoid any OOB access.
Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <1464179110-18593-1-git-send-email-ppandit@redhat.com>
Reviewed-by: Alexander Graf <agraf@suse.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit b60bdd1f1ee1616b7a9aeeffb4088e1ce2710fb2)
---
hw/scsi/megasas.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index bf642d4..cc66d36 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -650,7 +650,9 @@ static int megasas_init_firmware(MegasasState *s, MegasasCmd *cmd)
pa_hi = le32_to_cpu(initq->pi_addr_hi);
s->producer_pa = ((uint64_t) pa_hi << 32) | pa_lo;
s->reply_queue_head = ldl_le_pci_dma(pcid, s->producer_pa);
+ s->reply_queue_head %= MEGASAS_MAX_FRAMES;
s->reply_queue_tail = ldl_le_pci_dma(pcid, s->consumer_pa);
+ s->reply_queue_tail %= MEGASAS_MAX_FRAMES;
flags = le32_to_cpu(initq->flags);
if (flags & MFI_QUEUE_FLAG_CONTEXT64) {
s->flags |= MEGASAS_MASK_USE_QUEUE64;

View File

@ -0,0 +1,70 @@
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Mon, 30 May 2016 09:09:18 +0200
Subject: [PATCH] vmsvga: move fifo sanity checks to vmsvga_fifo_length
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Sanity checks are applied when the fifo is enabled by the guest
(SVGA_REG_CONFIG_DONE write). Which doesn't help much if the guest
changes the fifo registers afterwards. Move the checks to
vmsvga_fifo_length so they are done each time qemu is about to read
from the fifo.
Fixes: CVE-2016-4454
Cc: qemu-stable@nongnu.org
Cc: P J P <ppandit@redhat.com>
Reported-by: 李强 <liqiang6-s@360.cn>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 1464592161-18348-2-git-send-email-kraxel@redhat.com
(cherry picked from commit 521360267876d3b6518b328051a2e56bca55bef8)
---
hw/display/vmware_vga.c | 28 +++++++++++++++-------------
1 file changed, 15 insertions(+), 13 deletions(-)
diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c
index 0c63fa8..63a7c05 100644
--- a/hw/display/vmware_vga.c
+++ b/hw/display/vmware_vga.c
@@ -555,6 +555,21 @@ static inline int vmsvga_fifo_length(struct vmsvga_state_s *s)
if (!s->config || !s->enable) {
return 0;
}
+
+ /* Check range and alignment. */
+ if ((CMD(min) | CMD(max) | CMD(next_cmd) | CMD(stop)) & 3) {
+ return 0;
+ }
+ if (CMD(min) < (uint8_t *) s->cmd->fifo - (uint8_t *) s->fifo) {
+ return 0;
+ }
+ if (CMD(max) > SVGA_FIFO_SIZE) {
+ return 0;
+ }
+ if (CMD(max) < CMD(min) + 10 * 1024) {
+ return 0;
+ }
+
num = CMD(next_cmd) - CMD(stop);
if (num < 0) {
num += CMD(max) - CMD(min);
@@ -1005,19 +1020,6 @@ static void vmsvga_value_write(void *opaque, uint32_t address, uint32_t value)
case SVGA_REG_CONFIG_DONE:
if (value) {
s->fifo = (uint32_t *) s->fifo_ptr;
- /* Check range and alignment. */
- if ((CMD(min) | CMD(max) | CMD(next_cmd) | CMD(stop)) & 3) {
- break;
- }
- if (CMD(min) < (uint8_t *) s->cmd->fifo - (uint8_t *) s->fifo) {
- break;
- }
- if (CMD(max) > SVGA_FIFO_SIZE) {
- break;
- }
- if (CMD(max) < CMD(min) + 10 * 1024) {
- break;
- }
vga_dirty_log_stop(&s->vga);
}
s->config = !!value;

View File

@ -0,0 +1,36 @@
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Mon, 30 May 2016 09:09:19 +0200
Subject: [PATCH] vmsvga: add more fifo checks
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Make sure all fifo ptrs are within range.
Fixes: CVE-2016-4454
Cc: qemu-stable@nongnu.org
Cc: P J P <ppandit@redhat.com>
Reported-by: 李强 <liqiang6-s@360.cn>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 1464592161-18348-3-git-send-email-kraxel@redhat.com
(cherry picked from commit c2e3c54d3960bc53bfa3a5ce7ea7a050b9be267e)
---
hw/display/vmware_vga.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c
index 63a7c05..a26e62e 100644
--- a/hw/display/vmware_vga.c
+++ b/hw/display/vmware_vga.c
@@ -563,7 +563,10 @@ static inline int vmsvga_fifo_length(struct vmsvga_state_s *s)
if (CMD(min) < (uint8_t *) s->cmd->fifo - (uint8_t *) s->fifo) {
return 0;
}
- if (CMD(max) > SVGA_FIFO_SIZE) {
+ if (CMD(max) > SVGA_FIFO_SIZE ||
+ CMD(min) >= SVGA_FIFO_SIZE ||
+ CMD(stop) >= SVGA_FIFO_SIZE ||
+ CMD(next_cmd) >= SVGA_FIFO_SIZE) {
return 0;
}
if (CMD(max) < CMD(min) + 10 * 1024) {

View File

@ -0,0 +1,143 @@
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Mon, 30 May 2016 09:09:20 +0200
Subject: [PATCH] vmsvga: shadow fifo registers
The fifo is normal ram. So kvm vcpu threads and qemu iothread can
access the fifo in parallel without syncronization. Which in turn
implies we can't use the fifo pointers in-place because the guest
can try changing them underneath us. So add shadows for them, to
make sure the guest can't modify them after we've applied sanity
checks.
Fixes: CVE-2016-4454
Cc: qemu-stable@nongnu.org
Cc: P J P <ppandit@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 1464592161-18348-4-git-send-email-kraxel@redhat.com
(cherry picked from commit 7e486f7577764a07aa35588e119903c80a5c30a2)
---
hw/display/vmware_vga.c | 57 ++++++++++++++++++++++++-------------------------
1 file changed, 28 insertions(+), 29 deletions(-)
diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c
index a26e62e..de2567b 100644
--- a/hw/display/vmware_vga.c
+++ b/hw/display/vmware_vga.c
@@ -66,17 +66,11 @@ struct vmsvga_state_s {
uint8_t *fifo_ptr;
unsigned int fifo_size;
- union {
- uint32_t *fifo;
- struct QEMU_PACKED {
- uint32_t min;
- uint32_t max;
- uint32_t next_cmd;
- uint32_t stop;
- /* Add registers here when adding capabilities. */
- uint32_t fifo[0];
- } *cmd;
- };
+ uint32_t *fifo;
+ uint32_t fifo_min;
+ uint32_t fifo_max;
+ uint32_t fifo_next;
+ uint32_t fifo_stop;
#define REDRAW_FIFO_LEN 512
struct vmsvga_rect_s {
@@ -198,7 +192,7 @@ enum {
*/
SVGA_FIFO_MIN = 0,
SVGA_FIFO_MAX, /* The distance from MIN to MAX must be at least 10K */
- SVGA_FIFO_NEXT_CMD,
+ SVGA_FIFO_NEXT,
SVGA_FIFO_STOP,
/*
@@ -546,8 +540,6 @@ static inline void vmsvga_cursor_define(struct vmsvga_state_s *s,
}
#endif
-#define CMD(f) le32_to_cpu(s->cmd->f)
-
static inline int vmsvga_fifo_length(struct vmsvga_state_s *s)
{
int num;
@@ -556,38 +548,44 @@ static inline int vmsvga_fifo_length(struct vmsvga_state_s *s)
return 0;
}
+ s->fifo_min = le32_to_cpu(s->fifo[SVGA_FIFO_MIN]);
+ s->fifo_max = le32_to_cpu(s->fifo[SVGA_FIFO_MAX]);
+ s->fifo_next = le32_to_cpu(s->fifo[SVGA_FIFO_NEXT]);
+ s->fifo_stop = le32_to_cpu(s->fifo[SVGA_FIFO_STOP]);
+
/* Check range and alignment. */
- if ((CMD(min) | CMD(max) | CMD(next_cmd) | CMD(stop)) & 3) {
+ if ((s->fifo_min | s->fifo_max | s->fifo_next | s->fifo_stop) & 3) {
return 0;
}
- if (CMD(min) < (uint8_t *) s->cmd->fifo - (uint8_t *) s->fifo) {
+ if (s->fifo_min < sizeof(uint32_t) * 4) {
return 0;
}
- if (CMD(max) > SVGA_FIFO_SIZE ||
- CMD(min) >= SVGA_FIFO_SIZE ||
- CMD(stop) >= SVGA_FIFO_SIZE ||
- CMD(next_cmd) >= SVGA_FIFO_SIZE) {
+ if (s->fifo_max > SVGA_FIFO_SIZE ||
+ s->fifo_min >= SVGA_FIFO_SIZE ||
+ s->fifo_stop >= SVGA_FIFO_SIZE ||
+ s->fifo_next >= SVGA_FIFO_SIZE) {
return 0;
}
- if (CMD(max) < CMD(min) + 10 * 1024) {
+ if (s->fifo_max < s->fifo_min + 10 * 1024) {
return 0;
}
- num = CMD(next_cmd) - CMD(stop);
+ num = s->fifo_next - s->fifo_stop;
if (num < 0) {
- num += CMD(max) - CMD(min);
+ num += s->fifo_max - s->fifo_min;
}
return num >> 2;
}
static inline uint32_t vmsvga_fifo_read_raw(struct vmsvga_state_s *s)
{
- uint32_t cmd = s->fifo[CMD(stop) >> 2];
+ uint32_t cmd = s->fifo[s->fifo_stop >> 2];
- s->cmd->stop = cpu_to_le32(CMD(stop) + 4);
- if (CMD(stop) >= CMD(max)) {
- s->cmd->stop = s->cmd->min;
+ s->fifo_stop += 4;
+ if (s->fifo_stop >= s->fifo_max) {
+ s->fifo_stop = s->fifo_min;
}
+ s->fifo[SVGA_FIFO_STOP] = cpu_to_le32(s->fifo_stop);
return cmd;
}
@@ -607,7 +605,7 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
len = vmsvga_fifo_length(s);
while (len > 0) {
/* May need to go back to the start of the command if incomplete */
- cmd_start = s->cmd->stop;
+ cmd_start = s->fifo_stop;
switch (cmd = vmsvga_fifo_read(s)) {
case SVGA_CMD_UPDATE:
@@ -766,7 +764,8 @@ static void vmsvga_fifo_run(struct vmsvga_state_s *s)
break;
rewind:
- s->cmd->stop = cmd_start;
+ s->fifo_stop = cmd_start;
+ s->fifo[SVGA_FIFO_STOP] = cpu_to_le32(s->fifo_stop);
break;
}
}

View File

@ -0,0 +1,42 @@
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Mon, 30 May 2016 09:09:21 +0200
Subject: [PATCH] vmsvga: don't process more than 1024 fifo commands at once
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
vmsvga_fifo_run is called in regular intervals (on each display update)
and will resume where it left off. So we can simply exit the loop,
without having to worry about how processing will continue.
Fixes: CVE-2016-4453
Cc: qemu-stable@nongnu.org
Cc: P J P <ppandit@redhat.com>
Reported-by: 李强 <liqiang6-s@360.cn>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Message-id: 1464592161-18348-5-git-send-email-kraxel@redhat.com
(cherry picked from commit 4e68a0ee17dad7b8d870df0081d4ab2e079016c2)
---
hw/display/vmware_vga.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/hw/display/vmware_vga.c b/hw/display/vmware_vga.c
index de2567b..e51a05e 100644
--- a/hw/display/vmware_vga.c
+++ b/hw/display/vmware_vga.c
@@ -597,13 +597,13 @@ static inline uint32_t vmsvga_fifo_read(struct vmsvga_state_s *s)
static void vmsvga_fifo_run(struct vmsvga_state_s *s)
{
uint32_t cmd, colour;
- int args, len;
+ int args, len, maxloop = 1024;
int x, y, dx, dy, width, height;
struct vmsvga_cursor_definition_s cursor;
uint32_t cmd_start;
len = vmsvga_fifo_length(s);
- while (len > 0) {
+ while (len > 0 && --maxloop > 0) {
/* May need to go back to the start of the command if incomplete */
cmd_start = s->fifo_stop;

View File

@ -0,0 +1,34 @@
From: Peter Lieven <pl@kamp.de>
Date: Tue, 24 May 2016 10:59:28 +0200
Subject: [PATCH] block/iscsi: avoid potential overflow of acb->task->cdb
at least in the path via virtio-blk the maximum size is not
restricted.
Cc: qemu-stable@nongnu.org
Signed-off-by: Peter Lieven <pl@kamp.de>
Message-Id: <1464080368-29584-1-git-send-email-pl@kamp.de>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit a6b3167fa0e825aebb5a7cd8b437b6d41584a196)
---
block/iscsi.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/block/iscsi.c b/block/iscsi.c
index 302baf8..172e6cf 100644
--- a/block/iscsi.c
+++ b/block/iscsi.c
@@ -837,6 +837,13 @@ static BlockAIOCB *iscsi_aio_ioctl(BlockDriverState *bs,
return &acb->common;
}
+ if (acb->ioh->cmd_len > SCSI_CDB_MAX_SIZE) {
+ error_report("iSCSI: ioctl error CDB exceeds max size (%d > %d)",
+ acb->ioh->cmd_len, SCSI_CDB_MAX_SIZE);
+ qemu_aio_unref(acb);
+ return NULL;
+ }
+
acb->task = malloc(sizeof(struct scsi_task));
if (acb->task == NULL) {
error_report("iSCSI: Failed to allocate task for scsi command. %s",

View File

@ -0,0 +1,33 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Tue, 31 May 2016 23:23:27 +0530
Subject: [PATCH] scsi: esp: check buffer length before reading scsi command
The 53C9X Fast SCSI Controller(FSC) comes with an internal 16-byte
FIFO buffer. It is used to handle command and data transfer.
Routine get_cmd() in non-DMA mode, uses 'ti_size' to read scsi
command into a buffer. Add check to validate command length against
buffer size to avoid any overrun.
Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Message-Id: <1464717207-7549-1-git-send-email-ppandit@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit d3cdc49138c30be1d3c2f83d18f85d9fdee95f1a)
---
hw/scsi/esp.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 591c817..c2f6f8f 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -98,6 +98,9 @@ static uint32_t get_cmd(ESPState *s, uint8_t *buf, uint8_t buflen)
s->dma_memory_read(s->dma_opaque, buf, dmalen);
} else {
dmalen = s->ti_size;
+ if (dmalen > TI_BUFSZ) {
+ return 0;
+ }
memcpy(buf, s->ti_buf, dmalen);
buf[0] = buf[2] >> 5;
}

View File

@ -0,0 +1,26 @@
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Tue, 14 Jun 2016 15:10:24 +0200
Subject: [PATCH] scsi: esp: respect FIFO invariant after message phase
The FIFO contains two bytes; hence the write ptr should be two bytes ahead
of the read pointer.
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit d020aa504cec8f525b55ba2ef982c09dc847c72e)
---
hw/scsi/esp.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index c2f6f8f..6407844 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -222,7 +222,7 @@ static void write_response(ESPState *s)
} else {
s->ti_size = 2;
s->ti_rptr = 0;
- s->ti_wptr = 0;
+ s->ti_wptr = 2;
s->rregs[ESP_RFLAGS] = 2;
}
esp_raise_irq(s);

View File

@ -0,0 +1,76 @@
From: Paolo Bonzini <pbonzini@redhat.com>
Date: Wed, 15 Jun 2016 14:29:33 +0200
Subject: [PATCH] scsi: esp: clean up handle_ti/esp_do_dma if s->do_cmd
Avoid duplicated code between esp_do_dma and handle_ti. esp_do_dma
has the same code that handle_ti contains after the call to esp_do_dma;
but the code in handle_ti is never reached because it is in an "else if".
Remove the else and also the pointless return.
esp_do_dma also has a partially dead assignment of the to_device
variable. Sink it to the point where it's actually used.
Finally, assert that the other caller of esp_do_dma (esp_transfer_data)
only transfers data and not a command. This is true because get_cmd
cancels the old request synchronously before its caller handle_satn_stop
sets do_cmd to 1.
Reviewed-by: Laszlo Ersek <lersek@redhat.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 7f0b6e114ae4e142e2b3dfc9fac138f4a30edc4f)
---
hw/scsi/esp.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 6407844..68d3e4d 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -245,15 +245,10 @@ static void esp_do_dma(ESPState *s)
uint32_t len;
int to_device;
- to_device = (s->ti_size < 0);
len = s->dma_left;
if (s->do_cmd) {
trace_esp_do_dma(s->cmdlen, len);
s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
- s->ti_size = 0;
- s->cmdlen = 0;
- s->do_cmd = 0;
- do_cmd(s, s->cmdbuf);
return;
}
if (s->async_len == 0) {
@@ -263,6 +258,7 @@ static void esp_do_dma(ESPState *s)
if (len > s->async_len) {
len = s->async_len;
}
+ to_device = (s->ti_size < 0);
if (to_device) {
s->dma_memory_read(s->dma_opaque, s->async_buf, len);
} else {
@@ -318,6 +314,7 @@ void esp_transfer_data(SCSIRequest *req, uint32_t len)
{
ESPState *s = req->hba_private;
+ assert(!s->do_cmd);
trace_esp_transfer_data(s->dma_left, s->ti_size);
s->async_len = len;
s->async_buf = scsi_req_get_buf(req);
@@ -358,13 +355,13 @@ static void handle_ti(ESPState *s)
s->dma_left = minlen;
s->rregs[ESP_RSTAT] &= ~STAT_TC;
esp_do_dma(s);
- } else if (s->do_cmd) {
+ }
+ if (s->do_cmd) {
trace_esp_handle_ti_cmd(s->cmdlen);
s->ti_size = 0;
s->cmdlen = 0;
s->do_cmd = 0;
do_cmd(s, s->cmdbuf);
- return;
}
}

View File

@ -0,0 +1,70 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Thu, 16 Jun 2016 00:22:35 +0200
Subject: [PATCH] scsi: esp: make cmdbuf big enough for maximum CDB size
While doing DMA read into ESP command buffer 's->cmdbuf', it could
write past the 's->cmdbuf' area, if it was transferring more than 16
bytes. Increase the command buffer size to 32, which is maximum when
's->do_cmd' is set, and add a check on 'len' to avoid OOB access.
Reported-by: Li Qiang <liqiang6-s@360.cn>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 926cde5f3e4d2504ed161ed0cb771ac7cad6fd11)
---
hw/scsi/esp.c | 6 ++++--
include/hw/scsi/esp.h | 3 ++-
2 files changed, 6 insertions(+), 3 deletions(-)
diff --git a/hw/scsi/esp.c b/hw/scsi/esp.c
index 68d3e4d..b4601ad 100644
--- a/hw/scsi/esp.c
+++ b/hw/scsi/esp.c
@@ -248,6 +248,8 @@ static void esp_do_dma(ESPState *s)
len = s->dma_left;
if (s->do_cmd) {
trace_esp_do_dma(s->cmdlen, len);
+ assert (s->cmdlen <= sizeof(s->cmdbuf) &&
+ len <= sizeof(s->cmdbuf) - s->cmdlen);
s->dma_memory_read(s->dma_opaque, &s->cmdbuf[s->cmdlen], len);
return;
}
@@ -345,7 +347,7 @@ static void handle_ti(ESPState *s)
s->dma_counter = dmalen;
if (s->do_cmd)
- minlen = (dmalen < 32) ? dmalen : 32;
+ minlen = (dmalen < ESP_CMDBUF_SZ) ? dmalen : ESP_CMDBUF_SZ;
else if (s->ti_size < 0)
minlen = (dmalen < -s->ti_size) ? dmalen : -s->ti_size;
else
@@ -451,7 +453,7 @@ void esp_reg_write(ESPState *s, uint32_t saddr, uint64_t val)
break;
case ESP_FIFO:
if (s->do_cmd) {
- if (s->cmdlen < TI_BUFSZ) {
+ if (s->cmdlen < ESP_CMDBUF_SZ) {
s->cmdbuf[s->cmdlen++] = val & 0xff;
} else {
trace_esp_error_fifo_overrun();
diff --git a/include/hw/scsi/esp.h b/include/hw/scsi/esp.h
index 6c79527..d2c4886 100644
--- a/include/hw/scsi/esp.h
+++ b/include/hw/scsi/esp.h
@@ -14,6 +14,7 @@ void esp_init(hwaddr espaddr, int it_shift,
#define ESP_REGS 16
#define TI_BUFSZ 16
+#define ESP_CMDBUF_SZ 32
typedef struct ESPState ESPState;
@@ -31,7 +32,7 @@ struct ESPState {
SCSIBus bus;
SCSIDevice *current_dev;
SCSIRequest *current_req;
- uint8_t cmdbuf[TI_BUFSZ];
+ uint8_t cmdbuf[ESP_CMDBUF_SZ];
uint32_t cmdlen;
uint32_t do_cmd;

View File

@ -0,0 +1,29 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Tue, 7 Jun 2016 16:44:03 +0530
Subject: [PATCH] scsi: megasas: null terminate bios version buffer
While reading information via 'megasas_ctrl_get_info' routine,
a local bios version buffer isn't null terminated. Add the
terminating null byte to avoid any OOB access.
Reported-by: Li Qiang <liqiang6-s@360.cn>
Reviewed-by: Peter Maydell <peter.maydell@linaro.org>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 844864fbae66935951529408831c2f22367a57b6)
---
hw/scsi/megasas.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/hw/scsi/megasas.c b/hw/scsi/megasas.c
index cc66d36..a9ffc32 100644
--- a/hw/scsi/megasas.c
+++ b/hw/scsi/megasas.c
@@ -773,6 +773,7 @@ static int megasas_ctrl_get_info(MegasasState *s, MegasasCmd *cmd)
ptr = memory_region_get_ram_ptr(&pci_dev->rom);
memcpy(biosver, ptr + 0x41, 31);
+ biosver[31] = 0;
memcpy(info.image_component[1].name, "BIOS", 4);
memcpy(info.image_component[1].version, biosver,
strlen((const char *)biosver));

View File

@ -0,0 +1,26 @@
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Wed, 1 Jun 2016 16:08:36 +0200
Subject: [PATCH] sdl2: skip init without outputs
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Tested-by: Cole Robinson <crobinso@redhat.com>
Message-id: 1464790116-32405-1-git-send-email-kraxel@redhat.com
(cherry picked from commit 8efa5f29f83816ae34f428143de49acbaacccb24)
---
ui/sdl2.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/ui/sdl2.c b/ui/sdl2.c
index 909038f..30d2a3c 100644
--- a/ui/sdl2.c
+++ b/ui/sdl2.c
@@ -794,6 +794,9 @@ void sdl_display_init(DisplayState *ds, int full_screen, int no_frame)
}
}
sdl2_num_outputs = i;
+ if (sdl2_num_outputs == 0) {
+ return;
+ }
sdl2_console = g_new0(struct sdl2_console, sdl2_num_outputs);
for (i = 0; i < sdl2_num_outputs; i++) {
QemuConsole *con = qemu_console_lookup_by_index(i);

View File

@ -49,7 +49,7 @@
Summary: QEMU is a FAST! processor emulator
Name: qemu
Version: 2.6.0
Release: 3%{?rcrel}%{?dist}
Release: 4%{?rcrel}%{?dist}
Epoch: 2
License: GPLv2+ and LGPLv2+ and BSD
Group: Development/Tools
@ -102,6 +102,36 @@ Patch0008: 0008-esp-check-dma-length-before-reading-scsi-command-CVE.patch
Patch0009: 0009-vga-add-sr_vbe-register-set.patch
# Fix crash with aarch64 gic-version=host and accel=tcg (bz #1339977)
Patch0010: 0010-hw-arm-virt-Reject-gic-version-host-for-non-KVM.patch
# CVE-2016-4002: net: buffer overflow in MIPSnet (bz #1326083)
Patch0011: 0011-net-mipsnet-check-packet-length-against-buffer.patch
# CVE-2016-4952 scsi: pvscsi: out-of-bounds access issue
Patch0012: 0012-scsi-pvscsi-check-command-descriptor-ring-buffer-siz.patch
# CVE-2016-4964: scsi: mptsas infinite loop (bz #1339157)
Patch0013: 0013-scsi-mptsas-infinite-loop-while-fetching-requests.patch
# CVE-2016-5106: scsi: megasas: out-of-bounds write (bz #1339581)
Patch0014: 0014-scsi-megasas-use-appropriate-property-buffer-size.patch
# CVE-2016-5105: scsi: megasas: stack information leakage (bz #1339585)
Patch0015: 0015-scsi-megasas-initialise-local-configuration-data-buf.patch
# CVE-2016-5107: scsi: megasas: out-of-bounds read (bz #1339573)
Patch0016: 0016-scsi-megasas-check-read_queue_head-index-value.patch
# CVE-2016-4454: display: vmsvga: out-of-bounds read (bz #1340740)
Patch0017: 0017-vmsvga-move-fifo-sanity-checks-to-vmsvga_fifo_length.patch
Patch0018: 0018-vmsvga-add-more-fifo-checks.patch
Patch0019: 0019-vmsvga-shadow-fifo-registers.patch
# CVE-2016-4453: display: vmsvga: infinite loop (bz #1340744)
Patch0020: 0020-vmsvga-don-t-process-more-than-1024-fifo-commands-at.patch
# CVE-2016-5126: block: iscsi: buffer overflow (bz #1340925)
Patch0021: 0021-block-iscsi-avoid-potential-overflow-of-acb-task-cdb.patch
# CVE-2016-5238: scsi: esp: OOB write (bz #1341932)
Patch0022: 0022-scsi-esp-check-buffer-length-before-reading-scsi-com.patch
Patch0023: 0023-scsi-esp-respect-FIFO-invariant-after-message-phase.patch
Patch0024: 0024-scsi-esp-clean-up-handle_ti-esp_do_dma-if-s-do_cmd.patch
# CVE-2016-5338: scsi: esp: OOB r/w access (bz #1343325)
Patch0025: 0025-scsi-esp-make-cmdbuf-big-enough-for-maximum-CDB-size.patch
# CVE-2016-5337: scsi: megasas: information leakage (bz #1343910)
Patch0026: 0026-scsi-megasas-null-terminate-bios-version-buffer.patch
# Fix crash with -nodefaults -sdl (bz #1340931)
Patch0027: 0027-sdl2-skip-init-without-outputs.patch
# documentation deps
@ -363,6 +393,7 @@ Requires: seavgabios-bin
Requires: seabios-bin >= 1.7.5
Requires: sgabios-bin
Requires: ipxe-roms-qemu
Requires: edk2-ovmf
%if 0%{?have_seccomp:1}
Requires: libseccomp >= 1.0.0
%endif
@ -549,6 +580,7 @@ This package provides the system emulator for Moxie boards.
Summary: QEMU system emulator for AArch64
Group: Development/Tools
Requires: %{name}-common = %{epoch}:%{version}-%{release}
Requires: edk2-aarch64
%description system-aarch64
QEMU is a generic and open source processor emulator which achieves a good
emulation speed by using dynamic translation.
@ -1225,6 +1257,22 @@ getent passwd qemu >/dev/null || \
%changelog
* Wed Jun 22 2016 Cole Robinson <crobinso@redhat.com> - 2:2.6.0-4
- CVE-2016-4002: net: buffer overflow in MIPSnet (bz #1326083)
- CVE-2016-4952 scsi: pvscsi: out-of-bounds access issue
- CVE-2016-4964: scsi: mptsas infinite loop (bz #1339157)
- CVE-2016-5106: scsi: megasas: out-of-bounds write (bz #1339581)
- CVE-2016-5105: scsi: megasas: stack information leakage (bz #1339585)
- CVE-2016-5107: scsi: megasas: out-of-bounds read (bz #1339573)
- CVE-2016-4454: display: vmsvga: out-of-bounds read (bz #1340740)
- CVE-2016-4453: display: vmsvga: infinite loop (bz #1340744)
- CVE-2016-5126: block: iscsi: buffer overflow (bz #1340925)
- CVE-2016-5238: scsi: esp: OOB write (bz #1341932)
- CVE-2016-5338: scsi: esp: OOB r/w access (bz #1343325)
- CVE-2016-5337: scsi: megasas: information leakage (bz #1343910)
- Fix crash with -nodefaults -sdl (bz #1340931)
- Add deps on edk2-ovmf and edk2-aarch64
* Thu May 26 2016 Cole Robinson <crobinso@redhat.com> - 2:2.6.0-3
- CVE-2016-4020: memory leak in kvmvapic.c (bz #1326904)
- CVE-2016-4439: scsi: esb: OOB write #1 (bz #1337503)