chardev data is dropped when host side closed (bz #1352977)

CVE-2016-8667: dma: divide by zero error in set_next_tick (bz #1384876)
IPv6 DNS problems in qemu user networking (bz #1401165)
Fix crash in qxl memslot_get_virt (bz #1405847)
CVE-2017-5579: serial: fix memory leak in serial exit (bz #1416161)
spec: Pull in ipxe/vgabios links via -common package (bz #1431403)
Clean up binfmt.d configuration files (bz #1394859)
This commit is contained in:
Cole Robinson 2017-04-13 20:46:57 -04:00
parent 01e01cbfac
commit f081074661
8 changed files with 315 additions and 115 deletions

View File

@ -0,0 +1,32 @@
From: Ed Swierk <eswierk@skyportsystems.com>
Date: Tue, 31 Jan 2017 05:45:29 -0800
Subject: [PATCH] char: drop data written to a disconnected pty
When a serial port writes data to a pty that's disconnected, drop the
data and return the length dropped. This avoids triggering pointless
retries in callers like the 16550A serial_xmit(), and causes
qemu_chr_fe_write() to write all data to the log file, rather than
logging only while a pty client like virsh console happens to be
connected.
Signed-off-by: Ed Swierk <eswierk@skyportsystems.com>
Message-Id: <1485870329-79428-1-git-send-email-eswierk@skyportsystems.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 1c64fdbc8177058802df205f5d7cd65edafa59a8)
---
qemu-char.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/qemu-char.c b/qemu-char.c
index 90e9627..4ec9ae5 100644
--- a/qemu-char.c
+++ b/qemu-char.c
@@ -1328,7 +1328,7 @@ static int pty_chr_write(CharDriverState *chr, const uint8_t *buf, int len)
/* guest sends data, check for (re-)connect */
pty_chr_update_read_handler_locked(chr);
if (!s->connected) {
- return 0;
+ return len;
}
}
return io_channel_send(s->ioc, buf, len);

View File

@ -1,112 +0,0 @@
From ecbddbb106114f90008024b4e6c3ba1c38d7ca0e Mon Sep 17 00:00:00 2001
From: "Richard W.M. Jones" <rjones@redhat.com>
Date: Fri, 31 Mar 2017 21:51:33 +0100
Subject: [PATCH] main-loop: Acquire main_context lock around
os_host_main_loop_wait.
When running virt-rescue the serial console hangs from time to time.
Virt-rescue runs an ordinary Linux kernel "appliance", but there is
only a single idle process running inside, so the qemu main loop is
largely idle. With virt-rescue >= 1.37 you may be able to observe the
hang by doing:
$ virt-rescue -e ^] --scratch
><rescue> while true; do ls -l /usr/bin; done
The hang in virt-rescue can be resolved by pressing a key on the
serial console.
Possibly with the same root cause, we also observed hangs during very
early boot of regular Linux VMs with a serial console. Those hangs
are extremely rare, but you may be able to observe them by running
this command on baremetal for a sufficiently long time:
$ while libguestfs-test-tool -t 60 >& /tmp/log ; do echo -n . ; done
(Check in /tmp/log that the failure was caused by a hang during early
boot, and not some other reason)
During investigation of this bug, Paolo Bonzini wrote:
> glib is expecting QEMU to use g_main_context_acquire around accesses to
> GMainContext. However QEMU is not doing that, instead it is taking its
> own mutex. So we should add g_main_context_acquire and
> g_main_context_release in the two implementations of
> os_host_main_loop_wait; these should undo the effect of Frediano's
> glib patch.
This patch exactly implements Paolo's suggestion in that paragraph.
This fixes the serial console hang in my testing, across 3 different
physical machines (AMD, Intel Core i7 and Intel Xeon), over many hours
of automated testing. I wasn't able to reproduce the early boot hangs
(but as noted above, these are extremely rare in any case).
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1435432
Reported-by: Richard W.M. Jones <rjones@redhat.com>
Tested-by: Richard W.M. Jones <rjones@redhat.com>
Signed-off-by: Richard W.M. Jones <rjones@redhat.com>
Message-Id: <20170331205133.23906-1-rjones@redhat.com>
[Paolo: this is actually a glib bug: recent glib versions are also
expecting g_main_context_acquire around g_poll---but that is not
documented and probably not even intended].
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
main-loop.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/main-loop.c b/main-loop.c
index 4534c89..19cad6b 100644
--- a/main-loop.c
+++ b/main-loop.c
@@ -218,9 +218,12 @@ static void glib_pollfds_poll(void)
static int os_host_main_loop_wait(int64_t timeout)
{
+ GMainContext *context = g_main_context_default();
int ret;
static int spin_counter;
+ g_main_context_acquire(context);
+
glib_pollfds_fill(&timeout);
/* If the I/O thread is very busy or we are incorrectly busy waiting in
@@ -256,6 +259,9 @@ static int os_host_main_loop_wait(int64_t timeout)
}
glib_pollfds_poll();
+
+ g_main_context_release(context);
+
return ret;
}
#else
@@ -412,12 +418,15 @@ static int os_host_main_loop_wait(int64_t timeout)
fd_set rfds, wfds, xfds;
int nfds;
+ g_main_context_acquire(context);
+
/* XXX: need to suppress polling by better using win32 events */
ret = 0;
for (pe = first_polling_entry; pe != NULL; pe = pe->next) {
ret |= pe->func(pe->opaque);
}
if (ret != 0) {
+ g_main_context_release(context);
return ret;
}
@@ -472,6 +481,8 @@ static int os_host_main_loop_wait(int64_t timeout)
g_main_context_dispatch(context);
}
+ g_main_context_release(context);
+
return select_ret || g_poll_ret;
}
#endif
--
2.9.3

View File

@ -0,0 +1,35 @@
From: Prasad J Pandit <pjp@fedoraproject.org>
Date: Wed, 12 Oct 2016 18:07:41 +0530
Subject: [PATCH] dma: rc4030: limit interval timer reload value
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
The JAZZ RC4030 chipset emulator has a periodic timer and
associated interval reload register. The reload value is used
as divider when computing timer's next tick value. If reload
value is large, it could lead to divide by zero error. Limit
the interval reload value to avoid it.
Reported-by: Huawei PSIRT <psirt@huawei.com>
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
Tested-by: Hervé Poussineau <hpoussin@reactos.org>
Signed-off-by: Yongbok Kim <yongbok.kim@imgtec.com>
(cherry picked from commit c0a3172fa6bbddcc73192f2a2c48d0bf3a7ba61c)
---
hw/dma/rc4030.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/hw/dma/rc4030.c b/hw/dma/rc4030.c
index 2f2576f..c1b4997 100644
--- a/hw/dma/rc4030.c
+++ b/hw/dma/rc4030.c
@@ -460,7 +460,7 @@ static void rc4030_write(void *opaque, hwaddr addr, uint64_t data,
break;
/* Interval timer reload */
case 0x0228:
- s->itr = val;
+ s->itr = val & 0x01FF;
qemu_irq_lower(s->timer_irq);
set_next_tick(s);
break;

View File

@ -0,0 +1,88 @@
From: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Sun, 26 Mar 2017 20:28:11 +0200
Subject: [PATCH] slirp: Make RA build more flexible
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Do not hardcode the RA size at all, use a pl_size variable which
accounts the accumulated size, and fill rip->ip_pl at the end.
This will allow to make some blocks optional.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
(cherry picked from commit e42f869b5118fa9ac64dcea624276204567fc581)
---
slirp/ip6_icmp.c | 24 +++++++++---------------
1 file changed, 9 insertions(+), 15 deletions(-)
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index 6d18e28..3f74389 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -143,17 +143,10 @@ void ndp_send_ra(Slirp *slirp)
/* Build IPv6 packet */
struct mbuf *t = m_get(slirp);
struct ip6 *rip = mtod(t, struct ip6 *);
+ size_t pl_size = 0;
rip->ip_src = (struct in6_addr)LINKLOCAL_ADDR;
rip->ip_dst = (struct in6_addr)ALLNODES_MULTICAST;
rip->ip_nh = IPPROTO_ICMPV6;
- rip->ip_pl = htons(ICMP6_NDP_RA_MINLEN
- + NDPOPT_LINKLAYER_LEN
- + NDPOPT_PREFIXINFO_LEN
-#ifndef _WIN32
- + NDPOPT_RDNSS_LEN
-#endif
- );
- t->m_len = sizeof(struct ip6) + ntohs(rip->ip_pl);
/* Build ICMPv6 packet */
t->m_data += sizeof(struct ip6);
@@ -171,6 +164,7 @@ void ndp_send_ra(Slirp *slirp)
ricmp->icmp6_nra.reach_time = htonl(NDP_AdvReachableTime);
ricmp->icmp6_nra.retrans_time = htonl(NDP_AdvRetransTime);
t->m_data += ICMP6_NDP_RA_MINLEN;
+ pl_size += ICMP6_NDP_RA_MINLEN;
/* Source link-layer address (NDP option) */
struct ndpopt *opt = mtod(t, struct ndpopt *);
@@ -178,6 +172,7 @@ void ndp_send_ra(Slirp *slirp)
opt->ndpopt_len = NDPOPT_LINKLAYER_LEN / 8;
in6_compute_ethaddr(rip->ip_src, opt->ndpopt_linklayer);
t->m_data += NDPOPT_LINKLAYER_LEN;
+ pl_size += NDPOPT_LINKLAYER_LEN;
/* Prefix information (NDP option) */
struct ndpopt *opt2 = mtod(t, struct ndpopt *);
@@ -192,6 +187,7 @@ void ndp_send_ra(Slirp *slirp)
opt2->ndpopt_prefixinfo.reserved2 = 0;
opt2->ndpopt_prefixinfo.prefix = slirp->vprefix_addr6;
t->m_data += NDPOPT_PREFIXINFO_LEN;
+ pl_size += NDPOPT_PREFIXINFO_LEN;
#ifndef _WIN32
/* Prefix information (NDP option) */
@@ -203,16 +199,14 @@ void ndp_send_ra(Slirp *slirp)
opt3->ndpopt_rdnss.lifetime = htonl(2 * NDP_MaxRtrAdvInterval);
opt3->ndpopt_rdnss.addr = slirp->vnameserver_addr6;
t->m_data += NDPOPT_RDNSS_LEN;
+ pl_size += NDPOPT_RDNSS_LEN;
#endif
+ rip->ip_pl = htons(pl_size);
+ t->m_data -= sizeof(struct ip6) + pl_size;
+ t->m_len = sizeof(struct ip6) + pl_size;
+
/* ICMPv6 Checksum */
-#ifndef _WIN32
- t->m_data -= NDPOPT_RDNSS_LEN;
-#endif
- t->m_data -= NDPOPT_PREFIXINFO_LEN;
- t->m_data -= NDPOPT_LINKLAYER_LEN;
- t->m_data -= ICMP6_NDP_RA_MINLEN;
- t->m_data -= sizeof(struct ip6);
ricmp->icmp6_cksum = ip6_cksum(t);
ip6_output(NULL, t, 0);

View File

@ -0,0 +1,65 @@
From: Samuel Thibault <samuel.thibault@ens-lyon.org>
Date: Sun, 26 Mar 2017 20:46:34 +0200
Subject: [PATCH] slirp: Send RDNSS in RA only if host has an IPv6 DNS server
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Previously we would always send an RDNSS option in the RA, making the guest
try to resolve DNS through IPv6, even if the host does not actually have
and IPv6 DNS server available.
This makes the RDNSS option enabled only when an IPv6 DNS server is
available.
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
Reviewed-by: Philippe Mathieu-Daudé <f4bug@amsat.org>
(cherry picked from commit a2f80fdfc683019901cdf4c0863a5920c0ca7245)
---
slirp/ip6_icmp.c | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/slirp/ip6_icmp.c b/slirp/ip6_icmp.c
index 3f74389..4c71f4c 100644
--- a/slirp/ip6_icmp.c
+++ b/slirp/ip6_icmp.c
@@ -144,6 +144,9 @@ void ndp_send_ra(Slirp *slirp)
struct mbuf *t = m_get(slirp);
struct ip6 *rip = mtod(t, struct ip6 *);
size_t pl_size = 0;
+ struct in6_addr addr;
+ uint32_t scope_id;
+
rip->ip_src = (struct in6_addr)LINKLOCAL_ADDR;
rip->ip_dst = (struct in6_addr)ALLNODES_MULTICAST;
rip->ip_nh = IPPROTO_ICMPV6;
@@ -189,18 +192,18 @@ void ndp_send_ra(Slirp *slirp)
t->m_data += NDPOPT_PREFIXINFO_LEN;
pl_size += NDPOPT_PREFIXINFO_LEN;
-#ifndef _WIN32
/* Prefix information (NDP option) */
- /* disabled for windows for now, until get_dns6_addr is implemented */
- struct ndpopt *opt3 = mtod(t, struct ndpopt *);
- opt3->ndpopt_type = NDPOPT_RDNSS;
- opt3->ndpopt_len = NDPOPT_RDNSS_LEN / 8;
- opt3->ndpopt_rdnss.reserved = 0;
- opt3->ndpopt_rdnss.lifetime = htonl(2 * NDP_MaxRtrAdvInterval);
- opt3->ndpopt_rdnss.addr = slirp->vnameserver_addr6;
- t->m_data += NDPOPT_RDNSS_LEN;
- pl_size += NDPOPT_RDNSS_LEN;
-#endif
+ if (get_dns6_addr(&addr, &scope_id) >= 0) {
+ /* Host system does have an IPv6 DNS server, announce our proxy. */
+ struct ndpopt *opt3 = mtod(t, struct ndpopt *);
+ opt3->ndpopt_type = NDPOPT_RDNSS;
+ opt3->ndpopt_len = NDPOPT_RDNSS_LEN / 8;
+ opt3->ndpopt_rdnss.reserved = 0;
+ opt3->ndpopt_rdnss.lifetime = htonl(2 * NDP_MaxRtrAdvInterval);
+ opt3->ndpopt_rdnss.addr = slirp->vnameserver_addr6;
+ t->m_data += NDPOPT_RDNSS_LEN;
+ pl_size += NDPOPT_RDNSS_LEN;
+ }
rip->ip_pl = htons(pl_size);
t->m_data -= sizeof(struct ip6) + pl_size;

View File

@ -0,0 +1,37 @@
From: Gerd Hoffmann <kraxel@redhat.com>
Date: Mon, 6 Mar 2017 09:31:51 +0100
Subject: [PATCH] qxl: clear guest_cursor on QXL_CURSOR_HIDE
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Make sure we don't leave guest_cursor pointing into nowhere. This might
lead to (rare) live migration failures, due to target trying to restore
the cursor from the stale pointer.
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1421788
Reported-by: Dr. David Alan Gilbert <dgilbert@redhat.com>
Signed-off-by: Gerd Hoffmann <kraxel@redhat.com>
Reviewed-by: Marc-André Lureau <marcandre.lureau@redhat.com>
Message-id: 1488789111-27340-1-git-send-email-kraxel@redhat.com
(cherry picked from commit dbb5fb8d3519130559b10fa4e1395e4486c633f8)
---
hw/display/qxl.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/hw/display/qxl.c b/hw/display/qxl.c
index 62d0c80..e09ce10 100644
--- a/hw/display/qxl.c
+++ b/hw/display/qxl.c
@@ -478,6 +478,11 @@ static int qxl_track_command(PCIQXLDevice *qxl, struct QXLCommandExt *ext)
qxl->guest_cursor = ext->cmd.data;
qemu_mutex_unlock(&qxl->track_lock);
}
+ if (cmd->type == QXL_CURSOR_HIDE) {
+ qemu_mutex_lock(&qxl->track_lock);
+ qxl->guest_cursor = 0;
+ qemu_mutex_unlock(&qxl->track_lock);
+ }
break;
}
}

View File

@ -0,0 +1,37 @@
From: Li Qiang <liqiang6-s@360.cn>
Date: Wed, 4 Jan 2017 00:43:16 -0800
Subject: [PATCH] serial: fix memory leak in serial exit
The serial_exit_core function doesn't free some resources.
This can lead memory leak when hotplug and unplug. This
patch avoid this.
Signed-off-by: Li Qiang <liqiang6-s@360.cn>
Message-Id: <586cb5ab.f31d9d0a.38ac3.acf2@mx.google.com>
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
(cherry picked from commit 8409dc884a201bf74b30a9d232b6bbdd00cb7e2b)
---
hw/char/serial.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/hw/char/serial.c b/hw/char/serial.c
index eec72b7..455119f 100644
--- a/hw/char/serial.c
+++ b/hw/char/serial.c
@@ -904,6 +904,16 @@ void serial_realize_core(SerialState *s, Error **errp)
void serial_exit_core(SerialState *s)
{
qemu_chr_add_handlers(s->chr, NULL, NULL, NULL, NULL);
+
+ timer_del(s->modem_status_poll);
+ timer_free(s->modem_status_poll);
+
+ timer_del(s->fifo_timeout_timer);
+ timer_free(s->fifo_timeout_timer);
+
+ fifo8_destroy(&s->recv_fifo);
+ fifo8_destroy(&s->xmit_fifo);
+
qemu_unregister_reset(serial_reset, s);
}

View File

@ -68,7 +68,7 @@
Summary: QEMU is a FAST! processor emulator
Name: qemu
Version: 2.7.1
Release: 5%{?rcrel}%{?dist}
Release: 6%{?rcrel}%{?dist}
Epoch: 2
License: GPLv2+ and LGPLv2+ and BSD
Group: Development/Tools
@ -243,8 +243,17 @@ Patch0065: 0065-Revert-cirrus-allow-zero-source-pitch-in-pattern-fil.patch
Patch0066: 0066-cirrus-add-blit_is_unsafe-call-to-cirrus_bitblt_cput.patch
# Fix spice GL with new mesa/libglvnd (bz #1431905)
Patch0067: 0067-egl-helpers-Support-newer-MESA-versions.patch
# Workaround hangs with recent glib (bz #1435432, gnome.org bz #761102)
Patch0068: 0068-main-loop-Acquire-main_context-lock-around-os_host_m.patch
# chardev data is dropped when host side closed (bz #1352977)
Patch0068: 0068-char-drop-data-written-to-a-disconnected-pty.patch
# CVE-2016-8667: dma: divide by zero error in set_next_tick (bz #1384876)
Patch0069: 0069-dma-rc4030-limit-interval-timer-reload-value.patch
# IPv6 DNS problems in qemu user networking (bz #1401165)
Patch0070: 0070-slirp-Make-RA-build-more-flexible.patch
Patch0071: 0071-slirp-Send-RDNSS-in-RA-only-if-host-has-an-IPv6-DNS-.patch
# Fix crash in qxl memslot_get_virt (bz #1405847)
Patch0072: 0072-qxl-clear-guest_cursor-on-QXL_CURSOR_HIDE.patch
# CVE-2017-5579: serial: fix memory leak in serial exit (bz #1416161)
Patch0073: 0073-serial-fix-memory-leak-in-serial-exit.patch
# documentation deps
BuildRequires: texinfo
@ -1718,6 +1727,15 @@ getent passwd qemu >/dev/null || \
%changelog
* Thu Apr 13 2017 Cole Robinson <crobinso@redhat.com> - 2:2.7.1-6
- chardev data is dropped when host side closed (bz #1352977)
- CVE-2016-8667: dma: divide by zero error in set_next_tick (bz #1384876)
- IPv6 DNS problems in qemu user networking (bz #1401165)
- Fix crash in qxl memslot_get_virt (bz #1405847)
- CVE-2017-5579: serial: fix memory leak in serial exit (bz #1416161)
- spec: Pull in ipxe/vgabios links via -common package (bz #1431403)
- Clean up binfmt.d configuration files (bz #1394859)
* Tue Apr 4 2017 Paolo Bonzini <pbonzini@redhat.com> - 2:2.7.1-5
* Workaround hangs with recent glib (bz #1435432, gnome.org bz #761102)