diff --git a/SOURCES/kvm-slirp-check-sscanf-result-when-emulating-ident.patch b/SOURCES/kvm-slirp-check-sscanf-result-when-emulating-ident.patch new file mode 100644 index 0000000..e4347b0 --- /dev/null +++ b/SOURCES/kvm-slirp-check-sscanf-result-when-emulating-ident.patch @@ -0,0 +1,62 @@ +From 5cba04974b46608f462b7ce711c8eb0966f5d101 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Mon, 20 May 2019 17:00:52 +0200 +Subject: [PATCH 1/4] slirp: check sscanf result when emulating ident +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20190520170055.15404-2-marcandre.lureau@redhat.com> +Patchwork-id: 88098 +O-Subject: [RHEL-7.6.z qemu-kvm PATCH 1/4] slirp: check sscanf result when emulating ident +Bugzilla: 1669067 +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +From: William Bowling + +When emulating ident in tcp_emu, if the strchr checks passed but the +sscanf check failed, two uninitialized variables would be copied and +sent in the reply, so move this code inside the if(sscanf()) clause. + +Signed-off-by: William Bowling +Cc: qemu-stable@nongnu.org +Cc: secalert@redhat.com +Message-Id: <1551476756-25749-1-git-send-email-will@wbowling.info> +Signed-off-by: Samuel Thibault +Reviewed-by: Philippe Mathieu-Daudé + +(cherry picked from commit d3222975c7d6cda9e25809dea05241188457b113) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + slirp/tcp_subr.c | 10 +++++----- + 1 file changed, 5 insertions(+), 5 deletions(-) + +diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c +index 043f28f..0b7138b 100644 +--- a/slirp/tcp_subr.c ++++ b/slirp/tcp_subr.c +@@ -605,12 +605,12 @@ tcp_emu(struct socket *so, struct mbuf *m) + break; + } + } ++ so_rcv->sb_cc = snprintf(so_rcv->sb_data, ++ so_rcv->sb_datalen, ++ "%d,%d\r\n", n1, n2); ++ so_rcv->sb_rptr = so_rcv->sb_data; ++ so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; + } +- so_rcv->sb_cc = snprintf(so_rcv->sb_data, +- so_rcv->sb_datalen, +- "%d,%d\r\n", n1, n2); +- so_rcv->sb_rptr = so_rcv->sb_data; +- so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; + } + m_free(m); + return 0; +-- +1.8.3.1 + diff --git a/SOURCES/kvm-slirp-don-t-manipulate-so_rcv-in-tcp_emu.patch b/SOURCES/kvm-slirp-don-t-manipulate-so_rcv-in-tcp_emu.patch new file mode 100644 index 0000000..8ab4afc --- /dev/null +++ b/SOURCES/kvm-slirp-don-t-manipulate-so_rcv-in-tcp_emu.patch @@ -0,0 +1,127 @@ +From dae1fad6e93e6bdff0d5366fdb269904cd00c83c Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Mon, 20 May 2019 17:00:55 +0200 +Subject: [PATCH 4/4] slirp: don't manipulate so_rcv in tcp_emu() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20190520170055.15404-5-marcandre.lureau@redhat.com> +Patchwork-id: 88097 +O-Subject: [RHEL-7.6.z qemu-kvm PATCH 4/4] slirp: don't manipulate so_rcv in tcp_emu() +Bugzilla: 1669067 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Thomas Huth + +For some reason, EMU_IDENT is not like other "emulated" protocols and +tries to reconstitute the original buffer, if it came in multiple +packets. Unfortunately, it does so wrongly, as it doesn't respect the +sbuf circular buffer appending rules, nor does it maintain some of the +invariants (rptr is incremented without bounds, etc): this leads to +further memory corruption revealed by ASAN or various malloc +errors. Furthermore, the so_rcv buffer is regularly flushed, so there +is no guarantee that buffer reconstruction will do what is expected. + +Instead, do what the function comment says: "XXX Assumes the whole +command came in one packet", and don't touch so_rcv. + +Related to: https://bugzilla.redhat.com/show_bug.cgi?id=1664205 + +Cc: Prasad J Pandit +Signed-off-by: Marc-André Lureau + +(cherry picked from libslirp commit +9da0da837780f825b5db31db6620492f8b7cd5d6) + +[ MA - backported with style conflicts, and without qemu commit +a7104eda7dab99d0cdbd3595c211864cba415905 which is unnecessary with +this patch ] + +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + slirp/tcp_subr.c | 63 +++++++++++++++++++++++++++----------------------------- + 1 file changed, 30 insertions(+), 33 deletions(-) + +diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c +index 578b204..d49a366 100644 +--- a/slirp/tcp_subr.c ++++ b/slirp/tcp_subr.c +@@ -581,42 +581,39 @@ tcp_emu(struct socket *so, struct mbuf *m) + struct socket *tmpso; + struct sockaddr_in addr; + socklen_t addrlen = sizeof(struct sockaddr_in); +- struct sbuf *so_rcv = &so->so_rcv; +- +- memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); +- so_rcv->sb_wptr += m->m_len; +- so_rcv->sb_rptr += m->m_len; +- m_inc(m, m->m_len + 1); +- m->m_data[m->m_len] = 0; /* NULL terminate */ +- if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) { +- if (sscanf(so_rcv->sb_data, "%u%*[ ,]%u", &n1, &n2) == 2) { +- HTONS(n1); +- HTONS(n2); +- /* n2 is the one on our host */ +- for (tmpso = slirp->tcb.so_next; +- tmpso != &slirp->tcb; +- tmpso = tmpso->so_next) { +- if (tmpso->so_laddr.s_addr == so->so_laddr.s_addr && +- tmpso->so_lport == n2 && +- tmpso->so_faddr.s_addr == so->so_faddr.s_addr && +- tmpso->so_fport == n1) { +- if (getsockname(tmpso->s, +- (struct sockaddr *)&addr, &addrlen) == 0) +- n2 = addr.sin_port; +- break; +- } ++ char *eol = g_strstr_len(m->m_data, m->m_len, "\r\n"); ++ ++ if (!eol) { ++ return 1; ++ } ++ ++ *eol = '\0'; ++ if (sscanf(m->m_data, "%u%*[ ,]%u", &n1, &n2) == 2) { ++ HTONS(n1); ++ HTONS(n2); ++ /* n2 is the one on our host */ ++ for (tmpso = slirp->tcb.so_next; tmpso != &slirp->tcb; ++ tmpso = tmpso->so_next) { ++ if (tmpso->so_laddr.s_addr == so->so_laddr.s_addr && ++ tmpso->so_lport == n2 && ++ tmpso->so_faddr.s_addr == so->so_faddr.s_addr && ++ tmpso->so_fport == n1) { ++ if (getsockname(tmpso->s, (struct sockaddr *)&addr, ++ &addrlen) == 0) ++ n2 = addr.sin_port; ++ break; + } +- NTOHS(n1); +- NTOHS(n2); +- so_rcv->sb_cc = snprintf(so_rcv->sb_data, +- so_rcv->sb_datalen, +- "%d,%d\r\n", n1, n2); +- so_rcv->sb_rptr = so_rcv->sb_data; +- so_rcv->sb_wptr = so_rcv->sb_data + so_rcv->sb_cc; + } ++ NTOHS(n1); ++ NTOHS(n2); ++ m_inc(m, snprintf(NULL, 0, "%d,%d\r\n", n1, n2) + 1); ++ m->m_len = snprintf(m->m_data, M_ROOM(m), "%d,%d\r\n", n1, n2); ++ assert(m->m_len < M_ROOM(m)); ++ } else { ++ *eol = '\r'; + } +- m_free(m); +- return 0; ++ ++ return 1; + } + + case EMU_FTP: /* ftp */ +-- +1.8.3.1 + diff --git a/SOURCES/kvm-slirp-ensure-there-is-enough-space-in-mbuf-to-null-t.patch b/SOURCES/kvm-slirp-ensure-there-is-enough-space-in-mbuf-to-null-t.patch new file mode 100644 index 0000000..ceb2fc0 --- /dev/null +++ b/SOURCES/kvm-slirp-ensure-there-is-enough-space-in-mbuf-to-null-t.patch @@ -0,0 +1,66 @@ +From 16725ff1e92b21449017a6e3aa9b1621d06c84a4 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Mon, 20 May 2019 17:00:54 +0200 +Subject: [PATCH 3/4] slirp: ensure there is enough space in mbuf to + null-terminate +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20190520170055.15404-4-marcandre.lureau@redhat.com> +Patchwork-id: 88099 +O-Subject: [RHEL-7.6.z qemu-kvm PATCH 3/4] slirp: ensure there is enough space in mbuf to null-terminate +Bugzilla: 1669067 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Thomas Huth + +Prevents from buffer overflows. +Related to: https://bugzilla.redhat.com/show_bug.cgi?id=1664205 + +Cc: Prasad J Pandit +Signed-off-by: Marc-André Lureau + +(cherry picked from libslirp commit +306fef58b54d793ba4b259728c21322765bda917) + +[ MA - backported with style conflicts fixes ] +Signed-off-by: Marc-André Lureau + +Signed-off-by: Miroslav Rezanina +--- + slirp/tcp_subr.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c +index 80538a9..578b204 100644 +--- a/slirp/tcp_subr.c ++++ b/slirp/tcp_subr.c +@@ -586,6 +586,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + memcpy(so_rcv->sb_wptr, m->m_data, m->m_len); + so_rcv->sb_wptr += m->m_len; + so_rcv->sb_rptr += m->m_len; ++ m_inc(m, m->m_len + 1); + m->m_data[m->m_len] = 0; /* NULL terminate */ + if (strchr(m->m_data, '\r') || strchr(m->m_data, '\n')) { + if (sscanf(so_rcv->sb_data, "%u%*[ ,]%u", &n1, &n2) == 2) { +@@ -619,6 +620,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + } + + case EMU_FTP: /* ftp */ ++ m_inc(m, m->m_len + 1); + *(m->m_data+m->m_len) = 0; /* NUL terminate for strstr */ + if ((bptr = (char *)strstr(m->m_data, "ORT")) != NULL) { + /* +@@ -716,6 +718,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + /* + * Need to emulate DCC CHAT, DCC SEND and DCC MOVE + */ ++ m_inc(m, m->m_len + 1); + *(m->m_data+m->m_len) = 0; /* NULL terminate the string for strstr */ + if ((bptr = (char *)strstr(m->m_data, "DCC")) == NULL) + return 1; +-- +1.8.3.1 + diff --git a/SOURCES/kvm-slirp-fix-big-little-endian-conversion-in-ident-prot.patch b/SOURCES/kvm-slirp-fix-big-little-endian-conversion-in-ident-prot.patch new file mode 100644 index 0000000..861404e --- /dev/null +++ b/SOURCES/kvm-slirp-fix-big-little-endian-conversion-in-ident-prot.patch @@ -0,0 +1,52 @@ +From 6e4dad9d915f8de71e1695720398160c97e8ebd0 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Marc-Andr=C3=A9=20Lureau?= +Date: Mon, 20 May 2019 17:00:53 +0200 +Subject: [PATCH 2/4] slirp: fix big/little endian conversion in ident protocol +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +RH-Author: Marc-André Lureau +Message-id: <20190520170055.15404-3-marcandre.lureau@redhat.com> +Patchwork-id: 88100 +O-Subject: [RHEL-7.6.z qemu-kvm PATCH 2/4] slirp: fix big/little endian conversion in ident protocol +Bugzilla: 1669067 +RH-Acked-by: Philippe Mathieu-Daudé +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Thomas Huth + +From: Samuel Thibault + +Signed-off-by: Samuel Thibault +Reviewed-by: Philippe Mathieu-Daudé + +[ MA - backported to ease backport of CVE-2019-6778 ] + +(cherry picked from commit 1fd71067dae501f1c78618e9583c6cc72db0cfa6) +Signed-off-by: Marc-André Lureau +Signed-off-by: Miroslav Rezanina +--- + slirp/tcp_subr.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c +index 0b7138b..80538a9 100644 +--- a/slirp/tcp_subr.c ++++ b/slirp/tcp_subr.c +@@ -601,10 +601,12 @@ tcp_emu(struct socket *so, struct mbuf *m) + tmpso->so_fport == n1) { + if (getsockname(tmpso->s, + (struct sockaddr *)&addr, &addrlen) == 0) +- n2 = ntohs(addr.sin_port); ++ n2 = addr.sin_port; + break; + } + } ++ NTOHS(n1); ++ NTOHS(n2); + so_rcv->sb_cc = snprintf(so_rcv->sb_data, + so_rcv->sb_datalen, + "%d,%d\r\n", n1, n2); +-- +1.8.3.1 + diff --git a/SPECS/qemu-kvm.spec b/SPECS/qemu-kvm.spec index a813c1b..b7e76d5 100644 --- a/SPECS/qemu-kvm.spec +++ b/SPECS/qemu-kvm.spec @@ -76,7 +76,7 @@ Obsoletes: %1 < %{obsoletes_version} \ Summary: QEMU is a machine emulator and virtualizer Name: %{pkgname}%{?pkgsuffix} Version: 1.5.3 -Release: 160%{?dist}.2 +Release: 160%{?dist}.3 # Epoch because we pushed a qemu-1.0 package. AIUI this can't ever be dropped Epoch: 10 License: GPLv2 and GPLv2+ and CC-BY @@ -3943,6 +3943,14 @@ Patch1942: kvm-slirp-Correct-size-check-in-m_inc.patch Patch1943: kvm-i386-Deprecate-arch-facilities-and-make-it-block-liv.patch # For bz#1693216 - qemu-kvm: hardware: Microarchitectural Store Buffer Data Sampling [rhel-7.6.z] Patch1944: kvm-target-i386-define-md-clear-bit-rhel.patch +# For bz#1669067 - CVE-2019-6778 qemu-kvm: QEMU: slirp: heap buffer overflow in tcp_emu() [rhel-7.6.z] +Patch1945: kvm-slirp-check-sscanf-result-when-emulating-ident.patch +# For bz#1669067 - CVE-2019-6778 qemu-kvm: QEMU: slirp: heap buffer overflow in tcp_emu() [rhel-7.6.z] +Patch1946: kvm-slirp-fix-big-little-endian-conversion-in-ident-prot.patch +# For bz#1669067 - CVE-2019-6778 qemu-kvm: QEMU: slirp: heap buffer overflow in tcp_emu() [rhel-7.6.z] +Patch1947: kvm-slirp-ensure-there-is-enough-space-in-mbuf-to-null-t.patch +# For bz#1669067 - CVE-2019-6778 qemu-kvm: QEMU: slirp: heap buffer overflow in tcp_emu() [rhel-7.6.z] +Patch1948: kvm-slirp-don-t-manipulate-so_rcv-in-tcp_emu.patch BuildRequires: zlib-devel @@ -6065,6 +6073,10 @@ tar -xf %{SOURCE21} %patch1942 -p1 %patch1943 -p1 %patch1944 -p1 +%patch1945 -p1 +%patch1946 -p1 +%patch1947 -p1 +%patch1948 -p1 %build buildarch="%{kvm_target}-softmmu" @@ -6510,6 +6522,14 @@ sh %{_sysconfdir}/sysconfig/modules/kvm.modules &> /dev/null || : %{_mandir}/man8/qemu-nbd.8* %changelog +* Tue May 28 2019 Miroslav Rezanina - 1.5.3-160.el7_6.3 +- kvm-slirp-check-sscanf-result-when-emulating-ident.patch [bz#1669067] +- kvm-slirp-fix-big-little-endian-conversion-in-ident-prot.patch [bz#1669067] +- kvm-slirp-ensure-there-is-enough-space-in-mbuf-to-null-t.patch [bz#1669067] +- kvm-slirp-don-t-manipulate-so_rcv-in-tcp_emu.patch [bz#1669067] +- Resolves: bz#1669067 + (CVE-2019-6778 qemu-kvm: QEMU: slirp: heap buffer overflow in tcp_emu() [rhel-7.6.z]) + * Wed Apr 10 2019 Danilo C. L. de Paula - 1.5.3-160.el7_6.2 - kvm-target-i386-define-md-clear-bit-rhel.patch - Resolves: bz#1693216