mirror of
https://git.in.rschanz.org/ryan77627/guix.git
synced 2024-12-24 21:38:07 -05:00
gnu: qemu: Add fixes for CVE-2015-8619, CVE-2016-1981, CVE-2016-2197.
* gnu/packages/patches/qemu-CVE-2015-8619.patch, gnu/packages/patches/qemu-CVE-2016-1981.patch, gnu/packages/patches/qemu-CVE-2016-2197.patch, gnu/packages/patches/qemu-usb-ehci-oob-read.patch: New files. * gnu-system.am (dist_patch_DATA): Add them. * gnu/packages/qemu.scm (qemu)[source]: Add patches.
This commit is contained in:
parent
b784b1a9ea
commit
5879f0d649
6 changed files with 312 additions and 1 deletions
|
@ -684,10 +684,14 @@ dist_patch_DATA = \
|
||||||
gnu/packages/patches/qemu-CVE-2015-8558.patch \
|
gnu/packages/patches/qemu-CVE-2015-8558.patch \
|
||||||
gnu/packages/patches/qemu-CVE-2015-8567.patch \
|
gnu/packages/patches/qemu-CVE-2015-8567.patch \
|
||||||
gnu/packages/patches/qemu-CVE-2015-8613.patch \
|
gnu/packages/patches/qemu-CVE-2015-8613.patch \
|
||||||
|
gnu/packages/patches/qemu-CVE-2015-8619.patch \
|
||||||
gnu/packages/patches/qemu-CVE-2015-8701.patch \
|
gnu/packages/patches/qemu-CVE-2015-8701.patch \
|
||||||
gnu/packages/patches/qemu-CVE-2015-8743.patch \
|
gnu/packages/patches/qemu-CVE-2015-8743.patch \
|
||||||
gnu/packages/patches/qemu-CVE-2016-1568.patch \
|
gnu/packages/patches/qemu-CVE-2016-1568.patch \
|
||||||
gnu/packages/patches/qemu-CVE-2016-1922.patch \
|
gnu/packages/patches/qemu-CVE-2016-1922.patch \
|
||||||
|
gnu/packages/patches/qemu-CVE-2016-1981.patch \
|
||||||
|
gnu/packages/patches/qemu-CVE-2016-2197.patch \
|
||||||
|
gnu/packages/patches/qemu-usb-ehci-oob-read.patch \
|
||||||
gnu/packages/patches/qemu-virtio-9p-use-accessor-to-get-thread-pool.patch \
|
gnu/packages/patches/qemu-virtio-9p-use-accessor-to-get-thread-pool.patch \
|
||||||
gnu/packages/patches/qt4-ldflags.patch \
|
gnu/packages/patches/qt4-ldflags.patch \
|
||||||
gnu/packages/patches/ratpoison-shell.patch \
|
gnu/packages/patches/ratpoison-shell.patch \
|
||||||
|
|
119
gnu/packages/patches/qemu-CVE-2015-8619.patch
Normal file
119
gnu/packages/patches/qemu-CVE-2015-8619.patch
Normal file
|
@ -0,0 +1,119 @@
|
||||||
|
From: Wolfgang Bumiller <w.bumiller@proxmox.com>
|
||||||
|
Date: Wed, 13 Jan 2016 09:09:58 +0100
|
||||||
|
Subject: [PATCH] hmp: fix sendkey out of bounds write (CVE-2015-8619)
|
||||||
|
|
||||||
|
When processing 'sendkey' command, hmp_sendkey routine null
|
||||||
|
terminates the 'keyname_buf' array. This results in an OOB
|
||||||
|
write issue, if 'keyname_len' was to fall outside of
|
||||||
|
'keyname_buf' array.
|
||||||
|
|
||||||
|
Since the keyname's length is known the keyname_buf can be
|
||||||
|
removed altogether by adding a length parameter to
|
||||||
|
index_from_key() and using it for the error output as well.
|
||||||
|
|
||||||
|
Reported-by: Ling Liu <liuling-it@360.cn>
|
||||||
|
Signed-off-by: Wolfgang Bumiller <w.bumiller@proxmox.com>
|
||||||
|
Message-Id: <20160113080958.GA18934@olga>
|
||||||
|
[Comparison with "<" dumbed down, test for junk after strtoul()
|
||||||
|
tweaked]
|
||||||
|
Signed-off-by: Markus Armbruster <armbru@redhat.com>
|
||||||
|
|
||||||
|
(cherry picked from commit 64ffbe04eaafebf4045a3ace52a360c14959d196)
|
||||||
|
---
|
||||||
|
hmp.c | 18 ++++++++----------
|
||||||
|
include/ui/console.h | 2 +-
|
||||||
|
ui/input-legacy.c | 5 +++--
|
||||||
|
3 files changed, 12 insertions(+), 13 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hmp.c b/hmp.c
|
||||||
|
index 2140605..1904203 100644
|
||||||
|
--- a/hmp.c
|
||||||
|
+++ b/hmp.c
|
||||||
|
@@ -1734,21 +1734,18 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict)
|
||||||
|
int has_hold_time = qdict_haskey(qdict, "hold-time");
|
||||||
|
int hold_time = qdict_get_try_int(qdict, "hold-time", -1);
|
||||||
|
Error *err = NULL;
|
||||||
|
- char keyname_buf[16];
|
||||||
|
char *separator;
|
||||||
|
int keyname_len;
|
||||||
|
|
||||||
|
while (1) {
|
||||||
|
separator = strchr(keys, '-');
|
||||||
|
keyname_len = separator ? separator - keys : strlen(keys);
|
||||||
|
- pstrcpy(keyname_buf, sizeof(keyname_buf), keys);
|
||||||
|
|
||||||
|
/* Be compatible with old interface, convert user inputted "<" */
|
||||||
|
- if (!strncmp(keyname_buf, "<", 1) && keyname_len == 1) {
|
||||||
|
- pstrcpy(keyname_buf, sizeof(keyname_buf), "less");
|
||||||
|
+ if (keys[0] == '<' && keyname_len == 1) {
|
||||||
|
+ keys = "less";
|
||||||
|
keyname_len = 4;
|
||||||
|
}
|
||||||
|
- keyname_buf[keyname_len] = 0;
|
||||||
|
|
||||||
|
keylist = g_malloc0(sizeof(*keylist));
|
||||||
|
keylist->value = g_malloc0(sizeof(*keylist->value));
|
||||||
|
@@ -1761,16 +1758,17 @@ void hmp_sendkey(Monitor *mon, const QDict *qdict)
|
||||||
|
}
|
||||||
|
tmp = keylist;
|
||||||
|
|
||||||
|
- if (strstart(keyname_buf, "0x", NULL)) {
|
||||||
|
+ if (strstart(keys, "0x", NULL)) {
|
||||||
|
char *endp;
|
||||||
|
- int value = strtoul(keyname_buf, &endp, 0);
|
||||||
|
- if (*endp != '\0') {
|
||||||
|
+ int value = strtoul(keys, &endp, 0);
|
||||||
|
+ assert(endp <= keys + keyname_len);
|
||||||
|
+ if (endp != keys + keyname_len) {
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
keylist->value->type = KEY_VALUE_KIND_NUMBER;
|
||||||
|
keylist->value->u.number = value;
|
||||||
|
} else {
|
||||||
|
- int idx = index_from_key(keyname_buf);
|
||||||
|
+ int idx = index_from_key(keys, keyname_len);
|
||||||
|
if (idx == Q_KEY_CODE_MAX) {
|
||||||
|
goto err_out;
|
||||||
|
}
|
||||||
|
@@ -1792,7 +1790,7 @@ out:
|
||||||
|
return;
|
||||||
|
|
||||||
|
err_out:
|
||||||
|
- monitor_printf(mon, "invalid parameter: %s\n", keyname_buf);
|
||||||
|
+ monitor_printf(mon, "invalid parameter: %.*s\n", keyname_len, keys);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
diff --git a/include/ui/console.h b/include/ui/console.h
|
||||||
|
index c249db4..5739bdd 100644
|
||||||
|
--- a/include/ui/console.h
|
||||||
|
+++ b/include/ui/console.h
|
||||||
|
@@ -433,7 +433,7 @@ static inline int vnc_display_pw_expire(const char *id, time_t expires)
|
||||||
|
void curses_display_init(DisplayState *ds, int full_screen);
|
||||||
|
|
||||||
|
/* input.c */
|
||||||
|
-int index_from_key(const char *key);
|
||||||
|
+int index_from_key(const char *key, size_t key_length);
|
||||||
|
|
||||||
|
/* gtk.c */
|
||||||
|
void early_gtk_display_init(int opengl);
|
||||||
|
diff --git a/ui/input-legacy.c b/ui/input-legacy.c
|
||||||
|
index e0a39f0..3f28bbc 100644
|
||||||
|
--- a/ui/input-legacy.c
|
||||||
|
+++ b/ui/input-legacy.c
|
||||||
|
@@ -57,12 +57,13 @@ struct QEMUPutLEDEntry {
|
||||||
|
static QTAILQ_HEAD(, QEMUPutLEDEntry) led_handlers =
|
||||||
|
QTAILQ_HEAD_INITIALIZER(led_handlers);
|
||||||
|
|
||||||
|
-int index_from_key(const char *key)
|
||||||
|
+int index_from_key(const char *key, size_t key_length)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; QKeyCode_lookup[i] != NULL; i++) {
|
||||||
|
- if (!strcmp(key, QKeyCode_lookup[i])) {
|
||||||
|
+ if (!strncmp(key, QKeyCode_lookup[i], key_length) &&
|
||||||
|
+ !QKeyCode_lookup[i][key_length]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
95
gnu/packages/patches/qemu-CVE-2016-1981.patch
Normal file
95
gnu/packages/patches/qemu-CVE-2016-1981.patch
Normal file
|
@ -0,0 +1,95 @@
|
||||||
|
From: Laszlo Ersek <lersek@redhat.com>
|
||||||
|
Date: Tue, 19 Jan 2016 14:17:20 +0100
|
||||||
|
Subject: [PATCH] e1000: eliminate infinite loops on out-of-bounds transfer
|
||||||
|
start
|
||||||
|
|
||||||
|
The start_xmit() and e1000_receive_iov() functions implement DMA transfers
|
||||||
|
iterating over a set of descriptors that the guest's e1000 driver
|
||||||
|
prepares:
|
||||||
|
|
||||||
|
- the TDLEN and RDLEN registers store the total size of the descriptor
|
||||||
|
area,
|
||||||
|
|
||||||
|
- while the TDH and RDH registers store the offset (in whole tx / rx
|
||||||
|
descriptors) into the area where the transfer is supposed to start.
|
||||||
|
|
||||||
|
Each time a descriptor is processed, the TDH and RDH register is bumped
|
||||||
|
(as appropriate for the transfer direction).
|
||||||
|
|
||||||
|
QEMU already contains logic to deal with bogus transfers submitted by the
|
||||||
|
guest:
|
||||||
|
|
||||||
|
- Normally, the transmit case wants to increase TDH from its initial value
|
||||||
|
to TDT. (TDT is allowed to be numerically smaller than the initial TDH
|
||||||
|
value; wrapping at or above TDLEN bytes to zero is normal.) The failsafe
|
||||||
|
that QEMU currently has here is a check against reaching the original
|
||||||
|
TDH value again -- a complete wraparound, which should never happen.
|
||||||
|
|
||||||
|
- In the receive case RDH is increased from its initial value until
|
||||||
|
"total_size" bytes have been received; preferably in a single step, or
|
||||||
|
in "s->rxbuf_size" byte steps, if the latter is smaller. However, null
|
||||||
|
RX descriptors are skipped without receiving data, while RDH is
|
||||||
|
incremented just the same. QEMU tries to prevent an infinite loop
|
||||||
|
(processing only null RX descriptors) by detecting whether RDH assumes
|
||||||
|
its original value during the loop. (Again, wrapping from RDLEN to 0 is
|
||||||
|
normal.)
|
||||||
|
|
||||||
|
What both directions miss is that the guest could program TDLEN and RDLEN
|
||||||
|
so low, and the initial TDH and RDH so high, that these registers will
|
||||||
|
immediately be truncated to zero, and then never reassume their initial
|
||||||
|
values in the loop -- a full wraparound will never occur.
|
||||||
|
|
||||||
|
The condition that expresses this is:
|
||||||
|
|
||||||
|
xdh_start >= s->mac_reg[XDLEN] / sizeof(desc)
|
||||||
|
|
||||||
|
i.e., TDH or RDH start out after the last whole rx or tx descriptor that
|
||||||
|
fits into the TDLEN or RDLEN sized area.
|
||||||
|
|
||||||
|
This condition could be checked before we enter the loops, but
|
||||||
|
pci_dma_read() / pci_dma_write() knows how to fill in buffers safely for
|
||||||
|
bogus DMA addresses, so we just extend the existing failsafes with the
|
||||||
|
above condition.
|
||||||
|
|
||||||
|
This is CVE-2016-1981.
|
||||||
|
|
||||||
|
Cc: "Michael S. Tsirkin" <mst@redhat.com>
|
||||||
|
Cc: Petr Matousek <pmatouse@redhat.com>
|
||||||
|
Cc: Stefano Stabellini <stefano.stabellini@eu.citrix.com>
|
||||||
|
Cc: Prasad Pandit <ppandit@redhat.com>
|
||||||
|
Cc: Michael Roth <mdroth@linux.vnet.ibm.com>
|
||||||
|
Cc: Jason Wang <jasowang@redhat.com>
|
||||||
|
Cc: qemu-stable@nongnu.org
|
||||||
|
RHBZ: https://bugzilla.redhat.com/show_bug.cgi?id=1296044
|
||||||
|
Signed-off-by: Laszlo Ersek <lersek@redhat.com>
|
||||||
|
Reviewed-by: Jason Wang <jasowang@redhat.com>
|
||||||
|
Signed-off-by: Jason Wang <jasowang@redhat.com>
|
||||||
|
(cherry picked from commit dd793a74882477ca38d49e191110c17dfee51dcc)
|
||||||
|
---
|
||||||
|
hw/net/e1000.c | 6 ++++--
|
||||||
|
1 file changed, 4 insertions(+), 2 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/net/e1000.c b/hw/net/e1000.c
|
||||||
|
index bec06e9..34d0823 100644
|
||||||
|
--- a/hw/net/e1000.c
|
||||||
|
+++ b/hw/net/e1000.c
|
||||||
|
@@ -908,7 +908,8 @@ start_xmit(E1000State *s)
|
||||||
|
* bogus values to TDT/TDLEN.
|
||||||
|
* there's nothing too intelligent we could do about this.
|
||||||
|
*/
|
||||||
|
- if (s->mac_reg[TDH] == tdh_start) {
|
||||||
|
+ if (s->mac_reg[TDH] == tdh_start ||
|
||||||
|
+ tdh_start >= s->mac_reg[TDLEN] / sizeof(desc)) {
|
||||||
|
DBGOUT(TXERR, "TDH wraparound @%x, TDT %x, TDLEN %x\n",
|
||||||
|
tdh_start, s->mac_reg[TDT], s->mac_reg[TDLEN]);
|
||||||
|
break;
|
||||||
|
@@ -1165,7 +1166,8 @@ e1000_receive_iov(NetClientState *nc, const struct iovec *iov, int iovcnt)
|
||||||
|
if (++s->mac_reg[RDH] * sizeof(desc) >= s->mac_reg[RDLEN])
|
||||||
|
s->mac_reg[RDH] = 0;
|
||||||
|
/* see comment in start_xmit; same here */
|
||||||
|
- if (s->mac_reg[RDH] == rdh_start) {
|
||||||
|
+ if (s->mac_reg[RDH] == rdh_start ||
|
||||||
|
+ rdh_start >= s->mac_reg[RDLEN] / sizeof(desc)) {
|
||||||
|
DBGOUT(RXERR, "RDH wraparound @%x, RDT %x, RDLEN %x\n",
|
||||||
|
rdh_start, s->mac_reg[RDT], s->mac_reg[RDLEN]);
|
||||||
|
set_ics(s, 0, E1000_ICS_RXO);
|
40
gnu/packages/patches/qemu-CVE-2016-2197.patch
Normal file
40
gnu/packages/patches/qemu-CVE-2016-2197.patch
Normal file
|
@ -0,0 +1,40 @@
|
||||||
|
From: John Snow <jsnow@redhat.com>
|
||||||
|
Date: Wed, 10 Feb 2016 13:29:40 -0500
|
||||||
|
Subject: [PATCH] ahci: Do not unmap NULL addresses
|
||||||
|
|
||||||
|
Definitely don't try to unmap a garbage address.
|
||||||
|
|
||||||
|
Reported-by: Zuozhi fzz <zuozhi.fzz@alibaba-inc.com>
|
||||||
|
Signed-off-by: John Snow <jsnow@redhat.com>
|
||||||
|
Message-id: 1454103689-13042-2-git-send-email-jsnow@redhat.com
|
||||||
|
(cherry picked from commit 99b4cb71069f109b79b27bc629fc0cf0886dbc4b)
|
||||||
|
---
|
||||||
|
hw/ide/ahci.c | 8 ++++++++
|
||||||
|
1 file changed, 8 insertions(+)
|
||||||
|
|
||||||
|
diff --git a/hw/ide/ahci.c b/hw/ide/ahci.c
|
||||||
|
index 17f1cbd..cdc9299 100644
|
||||||
|
--- a/hw/ide/ahci.c
|
||||||
|
+++ b/hw/ide/ahci.c
|
||||||
|
@@ -661,6 +661,10 @@ static bool ahci_map_fis_address(AHCIDevice *ad)
|
||||||
|
|
||||||
|
static void ahci_unmap_fis_address(AHCIDevice *ad)
|
||||||
|
{
|
||||||
|
+ if (ad->res_fis == NULL) {
|
||||||
|
+ DPRINTF(ad->port_no, "Attempt to unmap NULL FIS address\n");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
dma_memory_unmap(ad->hba->as, ad->res_fis, 256,
|
||||||
|
DMA_DIRECTION_FROM_DEVICE, 256);
|
||||||
|
ad->res_fis = NULL;
|
||||||
|
@@ -677,6 +681,10 @@ static bool ahci_map_clb_address(AHCIDevice *ad)
|
||||||
|
|
||||||
|
static void ahci_unmap_clb_address(AHCIDevice *ad)
|
||||||
|
{
|
||||||
|
+ if (ad->lst == NULL) {
|
||||||
|
+ DPRINTF(ad->port_no, "Attempt to unmap NULL CLB address\n");
|
||||||
|
+ return;
|
||||||
|
+ }
|
||||||
|
dma_memory_unmap(ad->hba->as, ad->lst, 1024,
|
||||||
|
DMA_DIRECTION_FROM_DEVICE, 1024);
|
||||||
|
ad->lst = NULL;
|
49
gnu/packages/patches/qemu-usb-ehci-oob-read.patch
Normal file
49
gnu/packages/patches/qemu-usb-ehci-oob-read.patch
Normal file
|
@ -0,0 +1,49 @@
|
||||||
|
From: Prasad J Pandit <pjp@fedoraproject.org>
|
||||||
|
Date: Wed, 20 Jan 2016 01:26:46 +0530
|
||||||
|
Subject: [PATCH] usb: check page select value while processing iTD
|
||||||
|
|
||||||
|
While processing isochronous transfer descriptors(iTD), the page
|
||||||
|
select(PG) field value could lead to an OOB read access. Add
|
||||||
|
check to avoid it.
|
||||||
|
|
||||||
|
Reported-by: Qinghao Tang <luodalongde@gmail.com>
|
||||||
|
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
|
||||||
|
Message-id: 1453233406-12165-1-git-send-email-ppandit@redhat.com
|
||||||
|
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
|
||||||
|
(cherry picked from commit 49d925ce50383a286278143c05511d30ec41a36e)
|
||||||
|
---
|
||||||
|
hw/usb/hcd-ehci.c | 10 ++++++----
|
||||||
|
1 file changed, 6 insertions(+), 4 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/hw/usb/hcd-ehci.c b/hw/usb/hcd-ehci.c
|
||||||
|
index d07f228..c40013e 100644
|
||||||
|
--- a/hw/usb/hcd-ehci.c
|
||||||
|
+++ b/hw/usb/hcd-ehci.c
|
||||||
|
@@ -1404,21 +1404,23 @@ static int ehci_process_itd(EHCIState *ehci,
|
||||||
|
if (itd->transact[i] & ITD_XACT_ACTIVE) {
|
||||||
|
pg = get_field(itd->transact[i], ITD_XACT_PGSEL);
|
||||||
|
off = itd->transact[i] & ITD_XACT_OFFSET_MASK;
|
||||||
|
- ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);
|
||||||
|
- ptr2 = (itd->bufptr[pg+1] & ITD_BUFPTR_MASK);
|
||||||
|
len = get_field(itd->transact[i], ITD_XACT_LENGTH);
|
||||||
|
|
||||||
|
if (len > max * mult) {
|
||||||
|
len = max * mult;
|
||||||
|
}
|
||||||
|
-
|
||||||
|
- if (len > BUFF_SIZE) {
|
||||||
|
+ if (len > BUFF_SIZE || pg > 6) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
+ ptr1 = (itd->bufptr[pg] & ITD_BUFPTR_MASK);
|
||||||
|
qemu_sglist_init(&ehci->isgl, ehci->device, 2, ehci->as);
|
||||||
|
if (off + len > 4096) {
|
||||||
|
/* transfer crosses page border */
|
||||||
|
+ if (pg == 6) {
|
||||||
|
+ return -1; /* avoid page pg + 1 */
|
||||||
|
+ }
|
||||||
|
+ ptr2 = (itd->bufptr[pg + 1] & ITD_BUFPTR_MASK);
|
||||||
|
uint32_t len2 = off + len - 4096;
|
||||||
|
uint32_t len1 = len - len2;
|
||||||
|
qemu_sglist_add(&ehci->isgl, ptr1 + off, len1);
|
|
@ -71,7 +71,11 @@ (define-public qemu
|
||||||
"qemu-CVE-2015-8613.patch"
|
"qemu-CVE-2015-8613.patch"
|
||||||
"qemu-CVE-2015-8701.patch"
|
"qemu-CVE-2015-8701.patch"
|
||||||
"qemu-CVE-2015-8743.patch"
|
"qemu-CVE-2015-8743.patch"
|
||||||
"qemu-CVE-2016-1568.patch")))))
|
"qemu-CVE-2016-1568.patch"
|
||||||
|
"qemu-CVE-2015-8619.patch"
|
||||||
|
"qemu-CVE-2016-1981.patch"
|
||||||
|
"qemu-usb-ehci-oob-read.patch"
|
||||||
|
"qemu-CVE-2016-2197.patch")))))
|
||||||
(build-system gnu-build-system)
|
(build-system gnu-build-system)
|
||||||
(arguments
|
(arguments
|
||||||
'(#:phases (alist-replace
|
'(#:phases (alist-replace
|
||||||
|
|
Loading…
Reference in a new issue