Rebased to version 2.4.0.1
CVE-2015-7295: virtio-net possible remote DoS (bz #1264393) drive-mirror: Fix coroutine reentrance (bz #1266936)
This commit is contained in:
parent
628515809f
commit
37b11e133b
@ -1,79 +0,0 @@
|
||||
From: Gerd Hoffmann <kraxel@redhat.com>
|
||||
Date: Mon, 17 Aug 2015 19:56:53 +0200
|
||||
Subject: [PATCH] vnc: fix memory corruption (CVE-2015-5225)
|
||||
MIME-Version: 1.0
|
||||
Content-Type: text/plain; charset=UTF-8
|
||||
Content-Transfer-Encoding: 8bit
|
||||
|
||||
The _cmp_bytes variable added by commit "bea60dd ui/vnc: fix potential
|
||||
memory corruption issues" can become negative. Result is (possibly
|
||||
exploitable) memory corruption. Reason for that is it uses the stride
|
||||
instead of bytes per scanline to apply limits.
|
||||
|
||||
For the server surface is is actually fine. vnc creates that itself,
|
||||
there is never any padding and thus scanline length always equals stride.
|
||||
|
||||
For the guest surface scanline length and stride are typically identical
|
||||
too, but it doesn't has to be that way. So add and use a new variable
|
||||
(guest_ll) for the guest scanline length. Also rename min_stride to
|
||||
line_bytes to make more clear what it actually is. Finally sprinkle
|
||||
in an assert() to make sure we never use a negative _cmp_bytes again.
|
||||
|
||||
Reported-by: 范祚至(库特) <zuozhi.fzz@alibaba-inc.com>
|
||||
Reviewed-by: P J P <ppandit@redhat.com>
|
||||
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||
(cherry picked from commit eb8934b0418b3b1d125edddc4fc334a54334a49b)
|
||||
---
|
||||
ui/vnc.c | 15 ++++++++++-----
|
||||
1 file changed, 10 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/ui/vnc.c b/ui/vnc.c
|
||||
index e26973a..caf82f5 100644
|
||||
--- a/ui/vnc.c
|
||||
+++ b/ui/vnc.c
|
||||
@@ -2872,7 +2872,7 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
|
||||
pixman_image_get_width(vd->server));
|
||||
int height = MIN(pixman_image_get_height(vd->guest.fb),
|
||||
pixman_image_get_height(vd->server));
|
||||
- int cmp_bytes, server_stride, min_stride, guest_stride, y = 0;
|
||||
+ int cmp_bytes, server_stride, line_bytes, guest_ll, guest_stride, y = 0;
|
||||
uint8_t *guest_row0 = NULL, *server_row0;
|
||||
VncState *vs;
|
||||
int has_dirty = 0;
|
||||
@@ -2891,17 +2891,21 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
|
||||
* Update server dirty map.
|
||||
*/
|
||||
server_row0 = (uint8_t *)pixman_image_get_data(vd->server);
|
||||
- server_stride = guest_stride = pixman_image_get_stride(vd->server);
|
||||
+ server_stride = guest_stride = guest_ll =
|
||||
+ pixman_image_get_stride(vd->server);
|
||||
cmp_bytes = MIN(VNC_DIRTY_PIXELS_PER_BIT * VNC_SERVER_FB_BYTES,
|
||||
server_stride);
|
||||
if (vd->guest.format != VNC_SERVER_FB_FORMAT) {
|
||||
int width = pixman_image_get_width(vd->server);
|
||||
tmpbuf = qemu_pixman_linebuf_create(VNC_SERVER_FB_FORMAT, width);
|
||||
} else {
|
||||
+ int guest_bpp =
|
||||
+ PIXMAN_FORMAT_BPP(pixman_image_get_format(vd->guest.fb));
|
||||
guest_row0 = (uint8_t *)pixman_image_get_data(vd->guest.fb);
|
||||
guest_stride = pixman_image_get_stride(vd->guest.fb);
|
||||
+ guest_ll = pixman_image_get_width(vd->guest.fb) * ((guest_bpp + 7) / 8);
|
||||
}
|
||||
- min_stride = MIN(server_stride, guest_stride);
|
||||
+ line_bytes = MIN(server_stride, guest_ll);
|
||||
|
||||
for (;;) {
|
||||
int x;
|
||||
@@ -2932,9 +2936,10 @@ static int vnc_refresh_server_surface(VncDisplay *vd)
|
||||
if (!test_and_clear_bit(x, vd->guest.dirty[y])) {
|
||||
continue;
|
||||
}
|
||||
- if ((x + 1) * cmp_bytes > min_stride) {
|
||||
- _cmp_bytes = min_stride - x * cmp_bytes;
|
||||
+ if ((x + 1) * cmp_bytes > line_bytes) {
|
||||
+ _cmp_bytes = line_bytes - x * cmp_bytes;
|
||||
}
|
||||
+ assert(_cmp_bytes >= 0);
|
||||
if (memcmp(server_ptr, guest_ptr, _cmp_bytes) == 0) {
|
||||
continue;
|
||||
}
|
@ -1,35 +0,0 @@
|
||||
From: P J P <pjp@fedoraproject.org>
|
||||
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 <pjp@fedoraproject.org>
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Thomas Huth <thuth@redhat.com>
|
||||
Message-id: 1441383666-6590-1-git-send-email-stefanha@redhat.com
|
||||
(cherry picked from commit b947ac2bf26479e710489739c465c8af336599e7)
|
||||
---
|
||||
hw/net/e1000.c | 3 ++-
|
||||
1 file changed, 2 insertions(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
|
||||
index 5c6bcd0..09c9e9d 100644
|
||||
--- a/hw/net/e1000.c
|
||||
+++ b/hw/net/e1000.c
|
||||
@@ -740,7 +740,8 @@ process_tx_desc(E1000State *s, struct e1000_tx_desc *dp)
|
||||
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");
|
54
0004-virtio-introduce-virtqueue_unmap_sg.patch
Normal file
54
0004-virtio-introduce-virtqueue_unmap_sg.patch
Normal file
@ -0,0 +1,54 @@
|
||||
From: Jason Wang <jasowang@redhat.com>
|
||||
Date: Fri, 25 Sep 2015 13:21:28 +0800
|
||||
Subject: [PATCH] virtio: introduce virtqueue_unmap_sg()
|
||||
|
||||
Factor out sg unmapping logic. This will be reused by the patch that
|
||||
can discard descriptor.
|
||||
|
||||
Cc: Michael S. Tsirkin <mst@redhat.com>
|
||||
Cc: Andrew James <andrew.james@hpe.com>
|
||||
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
|
||||
(cherry picked from commit ce317461573bac12b10d67699b4ddf1f97cf066c)
|
||||
---
|
||||
hw/virtio/virtio.c | 14 ++++++++++----
|
||||
1 file changed, 10 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
|
||||
index 788b556..242aecb 100644
|
||||
--- a/hw/virtio/virtio.c
|
||||
+++ b/hw/virtio/virtio.c
|
||||
@@ -243,14 +243,12 @@ int virtio_queue_empty(VirtQueue *vq)
|
||||
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);
|
||||
@@ -266,6 +264,14 @@ void virtqueue_fill(VirtQueue *vq, const VirtQueueElement *elem,
|
||||
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_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;
|
||||
|
50
0005-virtio-introduce-virtqueue_discard.patch
Normal file
50
0005-virtio-introduce-virtqueue_discard.patch
Normal file
@ -0,0 +1,50 @@
|
||||
From: Jason Wang <jasowang@redhat.com>
|
||||
Date: Fri, 25 Sep 2015 13:21:29 +0800
|
||||
Subject: [PATCH] virtio: introduce virtqueue_discard()
|
||||
|
||||
This patch introduces virtqueue_discard() to discard a descriptor and
|
||||
unmap the sgs. This will be used by the patch that will discard
|
||||
descriptor when packet is truncated.
|
||||
|
||||
Cc: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
|
||||
(cherry picked from commit 29b9f5efd78ae0f9cc02dd169b6e80d2c404bade)
|
||||
---
|
||||
hw/virtio/virtio.c | 7 +++++++
|
||||
include/hw/virtio/virtio.h | 2 ++
|
||||
2 files changed, 9 insertions(+)
|
||||
|
||||
diff --git a/hw/virtio/virtio.c b/hw/virtio/virtio.c
|
||||
index 242aecb..b1f4e16 100644
|
||||
--- a/hw/virtio/virtio.c
|
||||
+++ b/hw/virtio/virtio.c
|
||||
@@ -266,6 +266,13 @@ static void virtqueue_unmap_sg(VirtQueue *vq, const VirtQueueElement *elem,
|
||||
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)
|
||||
{
|
||||
diff --git a/include/hw/virtio/virtio.h b/include/hw/virtio/virtio.h
|
||||
index cccae89..8023bde 100644
|
||||
--- a/include/hw/virtio/virtio.h
|
||||
+++ b/include/hw/virtio/virtio.h
|
||||
@@ -146,6 +146,8 @@ void virtio_del_queue(VirtIODevice *vdev, int n);
|
||||
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);
|
||||
|
@ -1,32 +0,0 @@
|
||||
From: P J P <pjp@fedoraproject.org>
|
||||
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 <luodalongde@gmail.com>
|
||||
Signed-off-by: P J P <pjp@fedoraproject.org>
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
(cherry picked from commit 737d2b3c41d59eb8f94ab7eb419b957938f24943)
|
||||
---
|
||||
hw/net/ne2000.c | 2 +-
|
||||
1 file changed, 1 insertion(+), 1 deletion(-)
|
||||
|
||||
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
|
||||
index 3492db3..44a4264 100644
|
||||
--- a/hw/net/ne2000.c
|
||||
+++ b/hw/net/ne2000.c
|
||||
@@ -253,7 +253,7 @@ ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
|
||||
if (index <= s->stop)
|
||||
avail = s->stop - index;
|
||||
else
|
||||
- avail = 0;
|
||||
+ break;
|
||||
len = size;
|
||||
if (len > avail)
|
||||
len = avail;
|
43
0006-virtio-net-correctly-drop-truncated-packets.patch
Normal file
43
0006-virtio-net-correctly-drop-truncated-packets.patch
Normal file
@ -0,0 +1,43 @@
|
||||
From: Jason Wang <jasowang@redhat.com>
|
||||
Date: Fri, 25 Sep 2015 13:21:30 +0800
|
||||
Subject: [PATCH] virtio-net: correctly drop truncated packets
|
||||
|
||||
When packet is truncated during receiving, we drop the packets but
|
||||
neither discard the descriptor nor add and signal used
|
||||
descriptor. This will lead several issues:
|
||||
|
||||
- sg mappings are leaked
|
||||
- rx will be stalled if a lots of packets were truncated
|
||||
|
||||
In order to be consistent with vhost, fix by discarding the descriptor
|
||||
in this case.
|
||||
|
||||
Cc: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
||||
Reviewed-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
|
||||
|
||||
(cherry picked from commit 0cf33fb6b49a19de32859e2cdc6021334f448fb3)
|
||||
---
|
||||
hw/net/virtio-net.c | 8 +-------
|
||||
1 file changed, 1 insertion(+), 7 deletions(-)
|
||||
|
||||
diff --git a/hw/net/virtio-net.c b/hw/net/virtio-net.c
|
||||
index 1510839..775389b 100644
|
||||
--- a/hw/net/virtio-net.c
|
||||
+++ b/hw/net/virtio-net.c
|
||||
@@ -1086,13 +1086,7 @@ static ssize_t virtio_net_receive(NetClientState *nc, const uint8_t *buf, size_t
|
||||
* 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;
|
||||
}
|
||||
|
117
0007-mirror-Fix-coroutine-reentrance.patch
Normal file
117
0007-mirror-Fix-coroutine-reentrance.patch
Normal file
@ -0,0 +1,117 @@
|
||||
From: Kevin Wolf <kwolf@redhat.com>
|
||||
Date: Thu, 13 Aug 2015 10:41:50 +0200
|
||||
Subject: [PATCH] mirror: Fix coroutine reentrance
|
||||
|
||||
This fixes a regression introduced by commit dcfb3beb ("mirror: Do zero
|
||||
write on target if sectors not allocated"), which was reported to cause
|
||||
aborts with the message "Co-routine re-entered recursively".
|
||||
|
||||
The cause for this bug is the following code in mirror_iteration_done():
|
||||
|
||||
if (s->common.busy) {
|
||||
qemu_coroutine_enter(s->common.co, NULL);
|
||||
}
|
||||
|
||||
This has always been ugly because - unlike most places that reenter - it
|
||||
doesn't have a specific yield that it pairs with, but is more
|
||||
uncontrolled. What we really mean here is "reenter the coroutine if
|
||||
it's in one of the four explicit yields in mirror.c".
|
||||
|
||||
This used to be equivalent with s->common.busy because neither
|
||||
mirror_run() nor mirror_iteration() call any function that could yield.
|
||||
However since commit dcfb3beb this doesn't hold true any more:
|
||||
bdrv_get_block_status_above() can yield.
|
||||
|
||||
So what happens is that bdrv_get_block_status_above() wants to take a
|
||||
lock that is already held, so it adds itself to the queue of waiting
|
||||
coroutines and yields. Instead of being woken up by the unlock function,
|
||||
however, it gets woken up by mirror_iteration_done(), which is obviously
|
||||
wrong.
|
||||
|
||||
In most cases the code actually happens to cope fairly well with such
|
||||
cases, but in this specific case, the unlock must already have scheduled
|
||||
the coroutine for wakeup when mirror_iteration_done() reentered it. And
|
||||
then the coroutine happened to process the scheduled restarts and tried
|
||||
to reenter itself recursively.
|
||||
|
||||
This patch fixes the problem by pairing the reenter in
|
||||
mirror_iteration_done() with specific yields instead of abusing
|
||||
s->common.busy.
|
||||
|
||||
Cc: qemu-stable@nongnu.org
|
||||
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||||
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
|
||||
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
Reviewed-by: Jeff Cody <jcody@redhat.com>
|
||||
Message-id: 1439455310-11263-1-git-send-email-kwolf@redhat.com
|
||||
Signed-off-by: Jeff Cody <jcody@redhat.com>
|
||||
(cherry picked from commit e424aff5f307227b1c2512bbb8ece891bb895cef)
|
||||
---
|
||||
block/mirror.c | 15 ++++++++++-----
|
||||
1 file changed, 10 insertions(+), 5 deletions(-)
|
||||
|
||||
diff --git a/block/mirror.c b/block/mirror.c
|
||||
index fc4d8f5..b2fb4b9 100644
|
||||
--- a/block/mirror.c
|
||||
+++ b/block/mirror.c
|
||||
@@ -60,6 +60,7 @@ typedef struct MirrorBlockJob {
|
||||
int sectors_in_flight;
|
||||
int ret;
|
||||
bool unmap;
|
||||
+ bool waiting_for_io;
|
||||
} MirrorBlockJob;
|
||||
|
||||
typedef struct MirrorOp {
|
||||
@@ -114,11 +115,7 @@ static void mirror_iteration_done(MirrorOp *op, int ret)
|
||||
qemu_iovec_destroy(&op->qiov);
|
||||
g_slice_free(MirrorOp, op);
|
||||
|
||||
- /* Enter coroutine when it is not sleeping. The coroutine sleeps to
|
||||
- * rate-limit itself. The coroutine will eventually resume since there is
|
||||
- * a sleep timeout so don't wake it early.
|
||||
- */
|
||||
- if (s->common.busy) {
|
||||
+ if (s->waiting_for_io) {
|
||||
qemu_coroutine_enter(s->common.co, NULL);
|
||||
}
|
||||
}
|
||||
@@ -203,7 +200,9 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
|
||||
/* Wait for I/O to this cluster (from a previous iteration) to be done. */
|
||||
while (test_bit(next_chunk, s->in_flight_bitmap)) {
|
||||
trace_mirror_yield_in_flight(s, sector_num, s->in_flight);
|
||||
+ s->waiting_for_io = true;
|
||||
qemu_coroutine_yield();
|
||||
+ s->waiting_for_io = false;
|
||||
}
|
||||
|
||||
do {
|
||||
@@ -239,7 +238,9 @@ static uint64_t coroutine_fn mirror_iteration(MirrorBlockJob *s)
|
||||
*/
|
||||
while (nb_chunks == 0 && s->buf_free_count < added_chunks) {
|
||||
trace_mirror_yield_buf_busy(s, nb_chunks, s->in_flight);
|
||||
+ s->waiting_for_io = true;
|
||||
qemu_coroutine_yield();
|
||||
+ s->waiting_for_io = false;
|
||||
}
|
||||
if (s->buf_free_count < nb_chunks + added_chunks) {
|
||||
trace_mirror_break_buf_busy(s, nb_chunks, s->in_flight);
|
||||
@@ -333,7 +334,9 @@ static void mirror_free_init(MirrorBlockJob *s)
|
||||
static void mirror_drain(MirrorBlockJob *s)
|
||||
{
|
||||
while (s->in_flight > 0) {
|
||||
+ s->waiting_for_io = true;
|
||||
qemu_coroutine_yield();
|
||||
+ s->waiting_for_io = false;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -506,7 +509,9 @@ static void coroutine_fn mirror_run(void *opaque)
|
||||
if (s->in_flight == MAX_IN_FLIGHT || s->buf_free_count == 0 ||
|
||||
(cnt == 0 && s->in_flight > 0)) {
|
||||
trace_mirror_yield(s, s->in_flight, s->buf_free_count, cnt);
|
||||
+ s->waiting_for_io = true;
|
||||
qemu_coroutine_yield();
|
||||
+ s->waiting_for_io = false;
|
||||
continue;
|
||||
} else if (cnt != 0) {
|
||||
delay_ns = mirror_iteration(s);
|
@ -1,67 +0,0 @@
|
||||
From: P J P <pjp@fedoraproject.org>
|
||||
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 <luodalongde@gmail.com>
|
||||
Signed-off-by: P J P <pjp@fedoraproject.org>
|
||||
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||||
(cherry picked from commit 9bbdbc66e5765068dce76e9269dce4547afd8ad4)
|
||||
---
|
||||
hw/net/ne2000.c | 19 +++++++++++++++----
|
||||
1 file changed, 15 insertions(+), 4 deletions(-)
|
||||
|
||||
diff --git a/hw/net/ne2000.c b/hw/net/ne2000.c
|
||||
index 44a4264..2bdb4c9 100644
|
||||
--- a/hw/net/ne2000.c
|
||||
+++ b/hw/net/ne2000.c
|
||||
@@ -230,6 +230,9 @@ ssize_t ne2000_receive(NetClientState *nc, const uint8_t *buf, size_t size_)
|
||||
}
|
||||
|
||||
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 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||
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 @@ static void ne2000_ioport_write(void *opaque, uint32_t addr, uint32_t val)
|
||||
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;
|
31
qemu.spec
31
qemu.spec
@ -39,8 +39,8 @@
|
||||
|
||||
Summary: QEMU is a FAST! processor emulator
|
||||
Name: qemu
|
||||
Version: 2.4.0
|
||||
Release: 4%{?dist}
|
||||
Version: 2.4.0.1
|
||||
Release: 1%{?dist}
|
||||
Epoch: 2
|
||||
License: GPLv2+ and LGPLv2+ and BSD
|
||||
Group: Development/Tools
|
||||
@ -68,22 +68,18 @@ Source12: bridge.conf
|
||||
# qemu-kvm back compat wrapper
|
||||
Source13: qemu-kvm.sh
|
||||
|
||||
# CVE-2015-5255: heap memory corruption in vnc_refresh_server_surface
|
||||
# (bz #1255899)
|
||||
Patch0001: 0001-vnc-fix-memory-corruption-CVE-2015-5225.patch
|
||||
# Fix emulation of various instructions, required by libm in F22 ppc64
|
||||
# guests.
|
||||
Patch0002: 0002-target-ppc-fix-vcipher-vcipherlast-vncipherlast-and-.patch
|
||||
Patch0003: 0003-target-ppc-fix-xscmpodp-and-xscmpudp-decoding.patch
|
||||
# CVE-2015-6815: net: e1000: infinite loop issue (bz #1260225)
|
||||
Patch0004: 0004-e1000-Avoid-infinite-loop-in-processing-transmit-des.patch
|
||||
Patch0001: 0001-target-ppc-fix-vcipher-vcipherlast-vncipherlast-and-.patch
|
||||
Patch0002: 0002-target-ppc-fix-xscmpodp-and-xscmpudp-decoding.patch
|
||||
# CVE-2015-6855: ide: divide by zero issue (bz #1261793)
|
||||
Patch0005: 0005-ide-fix-ATAPI-command-permissions.patch
|
||||
# CVE-2015-5278: Infinite loop in ne2000_receive() (bz #1263284)
|
||||
Patch0006: 0006-net-avoid-infinite-loop-when-receiving-packets-CVE-2.patch
|
||||
# CVE-2015-5279: Heap overflow vulnerability in ne2000_receive() (bz
|
||||
# #1263287)
|
||||
Patch0007: 0007-net-add-checks-to-validate-ring-buffer-pointers-CVE-.patch
|
||||
Patch0003: 0003-ide-fix-ATAPI-command-permissions.patch
|
||||
# CVE-2015-7295: virtio-net possible remote DoS (bz #1264393)
|
||||
Patch0004: 0004-virtio-introduce-virtqueue_unmap_sg.patch
|
||||
Patch0005: 0005-virtio-introduce-virtqueue_discard.patch
|
||||
Patch0006: 0006-virtio-net-correctly-drop-truncated-packets.patch
|
||||
# drive-mirror: Fix coroutine reentrance (bz #1266936)
|
||||
Patch0007: 0007-mirror-Fix-coroutine-reentrance.patch
|
||||
|
||||
BuildRequires: SDL2-devel
|
||||
BuildRequires: zlib-devel
|
||||
@ -1216,6 +1212,11 @@ getent passwd qemu >/dev/null || \
|
||||
|
||||
|
||||
%changelog
|
||||
* Thu Oct 08 2015 Cole Robinson <crobinso@redhat.com> - 2:2.4.0.1-1
|
||||
- Rebased to version 2.4.0.1
|
||||
- CVE-2015-7295: virtio-net possible remote DoS (bz #1264393)
|
||||
- drive-mirror: Fix coroutine reentrance (bz #1266936)
|
||||
|
||||
* Mon Sep 21 2015 Cole Robinson <crobinso@redhat.com> - 2:2.4.0-4
|
||||
- CVE-2015-6815: net: e1000: infinite loop issue (bz #1260225)
|
||||
- CVE-2015-6855: ide: divide by zero issue (bz #1261793)
|
||||
|
Loading…
Reference in New Issue
Block a user