[app-emulation/qemu] bump
This commit is contained in:
		
							
								
								
									
										86
									
								
								app-emulation/qemu/files/qemu-2.4.0-CVE-2015-5225.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										86
									
								
								app-emulation/qemu/files/qemu-2.4.0-CVE-2015-5225.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,86 @@ | ||||
| https://bugs.gentoo.org/558416 | ||||
|  | ||||
| fix from upstream git | ||||
|  | ||||
| From eb8934b0418b3b1d125edddc4fc334a54334a49b Mon Sep 17 00:00:00 2001 | ||||
| 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> | ||||
| --- | ||||
|  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; | ||||
|              } | ||||
| --  | ||||
| 2.5.0 | ||||
|  | ||||
							
								
								
									
										124
									
								
								app-emulation/qemu/files/qemu-2.4.0-block-mirror-crash.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										124
									
								
								app-emulation/qemu/files/qemu-2.4.0-block-mirror-crash.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,124 @@ | ||||
| https://bugs.gentoo.org/558396 | ||||
|  | ||||
| fix from upstream git | ||||
|  | ||||
| From e424aff5f307227b1c2512bbb8ece891bb895cef Mon Sep 17 00:00:00 2001 | ||||
| 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> | ||||
| --- | ||||
|  block/mirror.c | 15 ++++++++++----- | ||||
|  1 file changed, 10 insertions(+), 5 deletions(-) | ||||
|  | ||||
| diff --git a/block/mirror.c b/block/mirror.c | ||||
| index 0841964..9474443 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); | ||||
| @@ -337,7 +338,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; | ||||
|      } | ||||
|  } | ||||
|   | ||||
| @@ -510,7 +513,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); | ||||
| --  | ||||
| 2.5.0 | ||||
|  | ||||
							
								
								
									
										39
									
								
								app-emulation/qemu/files/qemu-2.4.0-e1000-loop.patch
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										39
									
								
								app-emulation/qemu/files/qemu-2.4.0-e1000-loop.patch
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,39 @@ | ||||
| https://bugs.gentoo.org/559656 | ||||
|  | ||||
| https://lists.gnu.org/archive/html/qemu-devel/2015-09/msg01199.html | ||||
|  | ||||
| From: Stefan Hajnoczi <stefanha@redhat.com> | ||||
| Subject: [PATCH] e1000: Avoid infinite loop in processing	transmit descriptor | ||||
| Newsgroups: gmane.comp.emulators.qemu | ||||
| Date: 2015-09-04 16:21:06 GMT (2 days, 12 hours and 51 minutes ago) | ||||
| From: P J P <pjp@fedoraproject.org> | ||||
|  | ||||
| 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> | ||||
| --- | ||||
|  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"); | ||||
| --  | ||||
| 2.4.3 | ||||
| @@ -21,7 +21,7 @@ if [[ ${PV} = *9999* ]]; then | ||||
| else | ||||
| 	SRC_URI="http://wiki.qemu-project.org/download/${P}.tar.bz2 | ||||
| 	${BACKPORTS:+ | ||||
| 		http://dev.gentoo.org/~cardoe/distfiles/${P}-${BACKPORTS}.tar.xz}" | ||||
| 		https://dev.gentoo.org/~cardoe/distfiles/${P}-${BACKPORTS}.tar.xz}" | ||||
| 	KEYWORDS="~amd64 ~ppc ~ppc64 ~x86 ~x86-fbsd" | ||||
| fi | ||||
| 
 | ||||
| @@ -41,8 +41,8 @@ virtfs +vnc vte xattr xen xfs" | ||||
| COMMON_TARGETS="aarch64 alpha arm cris i386 m68k microblaze microblazeel mips | ||||
| mips64 mips64el mipsel or32 ppc ppc64 s390x sh4 sh4eb sparc sparc64 unicore32 | ||||
| x86_64" | ||||
| IUSE_SOFTMMU_TARGETS="${COMMON_TARGETS} lm32 moxie ppcemb xtensa xtensaeb" | ||||
| IUSE_USER_TARGETS="${COMMON_TARGETS} armeb mipsn32 mipsn32el ppc64abi32 sparc32plus" | ||||
| IUSE_SOFTMMU_TARGETS="${COMMON_TARGETS} lm32 moxie ppcemb tricore xtensa xtensaeb" | ||||
| IUSE_USER_TARGETS="${COMMON_TARGETS} armeb mipsn32 mipsn32el ppc64abi32 ppc64le sparc32plus" | ||||
| 
 | ||||
| use_softmmu_targets=$(printf ' qemu_softmmu_targets_%s' ${IUSE_SOFTMMU_TARGETS}) | ||||
| use_user_targets=$(printf ' qemu_user_targets_%s' ${IUSE_USER_TARGETS}) | ||||
| @@ -136,7 +136,7 @@ USER_LIB_DEPEND="${COMMON_LIB_DEPEND}" | ||||
| X86_FIRMWARE_DEPEND=" | ||||
| 	>=sys-firmware/ipxe-1.0.0_p20130624 | ||||
| 	pin-upstream-blobs? ( | ||||
| 		~sys-firmware/seabios-1.7.5 | ||||
| 		~sys-firmware/seabios-1.8.2 | ||||
| 		~sys-firmware/sgabios-0.1_pre8 | ||||
| 		~sys-firmware/vgabios-0.7a | ||||
| 	) | ||||
| @@ -271,7 +271,29 @@ pkg_setup() { | ||||
| 
 | ||||
| #S="${WORKDIR}/${MY_P}" | ||||
| 
 | ||||
| # Sanity check to make sure target lists are kept up-to-date. | ||||
| check_targets() { | ||||
| 	local var=$1 mak=$2 | ||||
| 	local detected sorted | ||||
| 
 | ||||
| 	pushd "${S}"/default-configs >/dev/null || die | ||||
| 
 | ||||
| 	detected=$(echo $(printf '%s\n' *-${mak}.mak | sed "s:-${mak}.mak::" | sort -u)) | ||||
| 	sorted=$(echo $(printf '%s\n' ${!var} | sort -u)) | ||||
| 	if [[ ${sorted} != "${detected}" ]] ; then | ||||
| 		eerror "The ebuild needs to be kept in sync." | ||||
| 		eerror "${var}: ${sorted}" | ||||
| 		eerror "$(printf '%-*s' ${#var} configure): ${detected}" | ||||
| 		die "sync ${var} to the list of targets" | ||||
| 	fi | ||||
| 
 | ||||
| 	popd >/dev/null | ||||
| } | ||||
| 
 | ||||
| src_prepare() { | ||||
| 	check_targets IUSE_SOFTMMU_TARGETS softmmu | ||||
| 	check_targets IUSE_USER_TARGETS linux-user | ||||
| 
 | ||||
| 	# Alter target makefiles to accept CFLAGS set via flag-o | ||||
| 	sed -i -r \ | ||||
| 		-e 's/^(C|OP_C|HELPER_C)FLAGS=/\1FLAGS+=/' \ | ||||
| @@ -281,6 +303,9 @@ src_prepare() { | ||||
| 	use nls || rm -f po/*.po | ||||
| 
 | ||||
| 	epatch "${FILESDIR}"/qemu-1.7.0-cflags.patch | ||||
| 	epatch "${FILESDIR}"/${P}-block-mirror-crash.patch #558396 | ||||
| 	epatch "${FILESDIR}"/${P}-CVE-2015-5225.patch #558416 | ||||
| 	epatch "${FILESDIR}"/${PN}-2.4.0-e1000-loop.patch #559656 | ||||
| 	[[ -n ${BACKPORTS} ]] && \ | ||||
| 		EPATCH_FORCE=yes EPATCH_SUFFIX="patch" EPATCH_SOURCE="${S}/patches" \ | ||||
| 			epatch | ||||
		Reference in New Issue
	
	Block a user