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 @@
 | 
				
			||||||
                     "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
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Reference in a new issue