From e3b251d364db1c686605e6ff303759354df72b31 Mon Sep 17 00:00:00 2001 From: CentOS Sources Date: Mar 31 2020 12:25:55 +0000 Subject: import qemu-kvm-ma-2.12.0-44.el7_8.1 --- diff --git a/SOURCES/kvm-tcp_emu-fix-unsafe-snprintf-usages.patch b/SOURCES/kvm-tcp_emu-fix-unsafe-snprintf-usages.patch new file mode 100644 index 0000000..dd70d6b --- /dev/null +++ b/SOURCES/kvm-tcp_emu-fix-unsafe-snprintf-usages.patch @@ -0,0 +1,148 @@ +From bac27b0e9302c5b869d962879d43df1ebdd09c83 Mon Sep 17 00:00:00 2001 +From: jmaloy +Date: Wed, 19 Feb 2020 16:29:23 +0100 +Subject: [PATCH 2/2] tcp_emu: fix unsafe snprintf() usages +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Message-id: <20200219162923.18327-3-jmaloy@redhat.com> +Patchwork-id: 93977 +O-Subject: [RHEL-7.8 qemu-kvm-rhev PATCH v2 2/2] tcp_emu: fix unsafe snprintf() usages +Bugzilla: 1798974 +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Eduardo Habkost +RH-Acked-by: Philippe Mathieu-Daudé + +From: Marc-André Lureau + +Various calls to snprintf() assume that snprintf() returns "only" the +number of bytes written (excluding terminating NUL). + +https://pubs.opengroup.org/onlinepubs/9699919799/functions/snprintf.html#tag_16_159_04 + +"Upon successful completion, the snprintf() function shall return the +number of bytes that would be written to s had n been sufficiently +large excluding the terminating null byte." + +Before patch ce131029, if there isn't enough room in "m_data" for the +"DCC ..." message, we overflow "m_data". + +After the patch, if there isn't enough room for the same, we don't +overflow "m_data", but we set "m_len" out-of-bounds. The next time an +access is bounded by "m_len", we'll have a buffer overflow then. + +Use slirp_fmt*() to fix potential OOB memory access. + +Reported-by: Laszlo Ersek +Signed-off-by: Marc-André Lureau +Reviewed-by: Samuel Thibault +Message-Id: <20200127092414.169796-7-marcandre.lureau@redhat.com> +(cherry picked from libslirp commit 68ccb8021a838066f0951d4b2817eb6b6f10a843) +Signed-off-by: Jon Maloy + +Signed-off-by: Miroslav Rezanina +--- + slirp/tcp_subr.c | 44 +++++++++++++++++++++----------------------- + 1 file changed, 21 insertions(+), 23 deletions(-) + +diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c +index c5196a4..944e1d7 100644 +--- a/slirp/tcp_subr.c ++++ b/slirp/tcp_subr.c +@@ -665,8 +665,7 @@ tcp_emu(struct socket *so, struct mbuf *m) + 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)); ++ m->m_len = slirp_fmt(m->m_data, M_ROOM(m), "%d,%d\r\n", n1, n2); + } else { + *eol = '\r'; + } +@@ -706,9 +705,9 @@ tcp_emu(struct socket *so, struct mbuf *m) + n4 = (laddr & 0xff); + + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, M_FREEROOM(m), +- "ORT %d,%d,%d,%d,%d,%d\r\n%s", +- n1, n2, n3, n4, n5, n6, x==7?buff:""); ++ m->m_len += slirp_fmt(bptr, M_FREEROOM(m), ++ "ORT %d,%d,%d,%d,%d,%d\r\n%s", ++ n1, n2, n3, n4, n5, n6, x == 7 ? buff : ""); + return 1; + } else if ((bptr = (char *)strstr(m->m_data, "27 Entering")) != NULL) { + /* +@@ -739,10 +738,9 @@ tcp_emu(struct socket *so, struct mbuf *m) + n4 = (laddr & 0xff); + + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, M_FREEROOM(m), +- "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", +- n1, n2, n3, n4, n5, n6, x==7?buff:""); +- ++ m->m_len += slirp_fmt(bptr, M_FREEROOM(m), ++ "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s", ++ n1, n2, n3, n4, n5, n6, x == 7 ? buff : ""); + return 1; + } + +@@ -765,8 +763,8 @@ tcp_emu(struct socket *so, struct mbuf *m) + if (m->m_data[m->m_len-1] == '\0' && lport != 0 && + (so = tcp_listen(slirp, INADDR_ANY, 0, so->so_laddr.s_addr, + htons(lport), SS_FACCEPTONCE)) != NULL) +- m->m_len = snprintf(m->m_data, M_ROOM(m), +- "%d", ntohs(so->so_fport)) + 1; ++ m->m_len = slirp_fmt0(m->m_data, M_ROOM(m), ++ "%d", ntohs(so->so_fport)); + return 1; + + case EMU_IRC: +@@ -786,10 +784,10 @@ tcp_emu(struct socket *so, struct mbuf *m) + return 1; + } + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, M_FREEROOM(m), +- "DCC CHAT chat %lu %u%c\n", +- (unsigned long)ntohl(so->so_faddr.s_addr), +- ntohs(so->so_fport), 1); ++ m->m_len += slirp_fmt(bptr, M_FREEROOM(m), ++ "DCC CHAT chat %lu %u%c\n", ++ (unsigned long)ntohl(so->so_faddr.s_addr), ++ ntohs(so->so_fport), 1); + } else if (sscanf(bptr, "DCC SEND %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { + if ((so = tcp_listen(slirp, INADDR_ANY, 0, + htonl(laddr), htons(lport), +@@ -797,10 +795,10 @@ tcp_emu(struct socket *so, struct mbuf *m) + return 1; + } + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, M_FREEROOM(m), +- "DCC SEND %s %lu %u %u%c\n", buff, +- (unsigned long)ntohl(so->so_faddr.s_addr), +- ntohs(so->so_fport), n1, 1); ++ m->m_len += slirp_fmt(bptr, M_FREEROOM(m), ++ "DCC SEND %s %lu %u %u%c\n", buff, ++ (unsigned long)ntohl(so->so_faddr.s_addr), ++ ntohs(so->so_fport), n1, 1); + } else if (sscanf(bptr, "DCC MOVE %256s %u %u %u", buff, &laddr, &lport, &n1) == 4) { + if ((so = tcp_listen(slirp, INADDR_ANY, 0, + htonl(laddr), htons(lport), +@@ -808,10 +806,10 @@ tcp_emu(struct socket *so, struct mbuf *m) + return 1; + } + m->m_len = bptr - m->m_data; /* Adjust length */ +- m->m_len += snprintf(bptr, M_FREEROOM(m), +- "DCC MOVE %s %lu %u %u%c\n", buff, +- (unsigned long)ntohl(so->so_faddr.s_addr), +- ntohs(so->so_fport), n1, 1); ++ m->m_len += slirp_fmt(bptr, M_FREEROOM(m), ++ "DCC MOVE %s %lu %u %u%c\n", buff, ++ (unsigned long)ntohl(so->so_faddr.s_addr), ++ ntohs(so->so_fport), n1, 1); + } + return 1; + +-- +1.8.3.1 + diff --git a/SOURCES/kvm-util-add-slirp_fmt-helpers.patch b/SOURCES/kvm-util-add-slirp_fmt-helpers.patch new file mode 100644 index 0000000..8c61825 --- /dev/null +++ b/SOURCES/kvm-util-add-slirp_fmt-helpers.patch @@ -0,0 +1,141 @@ +From 8f130c9462750f2ec8205b0749ecd64b799144b5 Mon Sep 17 00:00:00 2001 +From: jmaloy +Date: Wed, 19 Feb 2020 16:29:22 +0100 +Subject: [PATCH 1/2] util: add slirp_fmt() helpers +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +Message-id: <20200219162923.18327-2-jmaloy@redhat.com> +Patchwork-id: 93976 +O-Subject: [RHEL-7.8 qemu-kvm-rhev PATCH v2 1/2] util: add slirp_fmt() helpers +Bugzilla: 1798974 +RH-Acked-by: Maxim Levitsky +RH-Acked-by: Stefan Hajnoczi +RH-Acked-by: Eduardo Habkost + +From: Marc-André Lureau + +Various calls to snprintf() in libslirp assume that snprintf() returns +"only" the number of bytes written (excluding terminating NUL). + +https://pubs.opengroup.org/onlinepubs/9699919799/functions/snprintf.html#tag_16_159_04 + +"Upon successful completion, the snprintf() function shall return the +number of bytes that would be written to s had n been sufficiently +large excluding the terminating null byte." + +Introduce slirp_fmt() that handles several pathological cases the +way libslirp usually expect: + +- treat error as fatal (instead of silently returning -1) + +- fmt0() will always \0 end + +- return the number of bytes actually written (instead of what would + have been written, which would usually result in OOB later), including + the ending \0 for fmt0() + +- warn if truncation happened (instead of ignoring) + + Other less common cases can still be handled with strcpy/snprintf() etc. + +Signed-off-by: Marc-André Lureau +Reviewed-by: Samuel Thibault +Message-Id: <20200127092414.169796-2-marcandre.lureau@redhat.com> + +(cherry picked from libslirp commit 30648c03b27fb8d9611b723184216cd3174b6775) + +Manually re-adapted, since there is no util.c file in this code version. +We add the two functions as static functions in the file where they +are going to be used. + +Signed-off-by: Jon Maloy +Signed-off-by: Miroslav Rezanina +--- + slirp/tcp_subr.c | 65 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ + 1 file changed, 65 insertions(+) + +diff --git a/slirp/tcp_subr.c b/slirp/tcp_subr.c +index b95ba23..c5196a4 100644 +--- a/slirp/tcp_subr.c ++++ b/slirp/tcp_subr.c +@@ -45,6 +45,9 @@ + /* Don't do rfc1323 performance enhancements */ + #define TCP_DO_RFC1323 0 + ++static int slirp_fmt(char *str, size_t size, const char *format, ...); ++static int slirp_fmt0(char *str, size_t size, const char *format, ...); ++ + /* + * Tcp initialization + */ +@@ -990,3 +993,65 @@ int tcp_ctl(struct socket *so) + sb->sb_wptr += sb->sb_cc; + return 0; + } ++ ++static int slirp_vsnprintf(char *str, size_t size, ++ const char *format, va_list args) ++{ ++ int rv = vsnprintf(str, size, format, args); ++ ++ if (rv < 0) { ++ g_error("vsnprintf() failed: %s", g_strerror(errno)); ++ } ++ ++ return rv; ++} ++ ++/* ++ * A snprintf()-like function that: ++ * - returns the number of bytes written (excluding optional \0-ending) ++ * - dies on error ++ * - warn on truncation ++ */ ++static int slirp_fmt(char *str, size_t size, const char *format, ...) ++{ ++ va_list args; ++ int rv; ++ ++ va_start(args, format); ++ rv = slirp_vsnprintf(str, size, format, args); ++ va_end(args); ++ ++ if (rv > size) { ++ g_critical("vsnprintf() truncation"); ++ } ++ ++ return MIN(rv, size); ++} ++ ++/* ++ * A snprintf()-like function that: ++ * - always \0-end (unless size == 0) ++ * - returns the number of bytes actually written, including \0 ending ++ * - dies on error ++ * - warn on truncation ++ */ ++static int slirp_fmt0(char *str, size_t size, const char *format, ...) ++{ ++ va_list args; ++ int rv; ++ ++ va_start(args, format); ++ rv = slirp_vsnprintf(str, size, format, args); ++ va_end(args); ++ ++ if (rv >= size) { ++ g_critical("vsnprintf() truncation"); ++ if (size > 0) ++ str[size - 1] = '\0'; ++ rv = size; ++ } else { ++ rv += 1; /* include \0 */ ++ } ++ ++ return rv; ++} +-- +1.8.3.1 + diff --git a/SPECS/qemu-kvm.spec b/SPECS/qemu-kvm.spec index 06ad481..1f4cbc8 100644 --- a/SPECS/qemu-kvm.spec +++ b/SPECS/qemu-kvm.spec @@ -108,7 +108,7 @@ Obsoletes: %1%{rhel_ma_suffix} < %{obsoletes_version2} \ Summary: QEMU is a machine emulator and virtualizer Name: %{pkgname}%{?pkgsuffix} Version: 2.12.0 -Release: 44%{?dist} +Release: 44%{?dist}.1 # 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 @@ -1956,6 +1956,10 @@ Patch897: kvm-iscsi-Avoid-potential-for-get_status-overflow.patch # For bz#1794499 - CVE-2020-1711 qemu-kvm-rhev: QEMU: block: iscsi: OOB heap access via an unexpected response of iSCSI Server [rhel-7.8] # For bz#1794505 - CVE-2020-1711 qemu-kvm-ma: QEMU: block: iscsi: OOB heap access via an unexpected response of iSCSI Server [rhel-7.8] Patch898: kvm-iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch +# For bz#1798974 - CVE-2020-8608 qemu-kvm-ma: QEMU: Slirp: potential OOB access due to unsafe snprintf() usages [rhel-7.8.z] +Patch899: kvm-util-add-slirp_fmt-helpers.patch +# For bz#1798974 - CVE-2020-8608 qemu-kvm-ma: QEMU: Slirp: potential OOB access due to unsafe snprintf() usages [rhel-7.8.z] +Patch900: kvm-tcp_emu-fix-unsafe-snprintf-usages.patch BuildRequires: zlib-devel BuildRequires: glib2-devel @@ -3071,6 +3075,8 @@ ApplyOptionalPatch() %patch896 -p1 %patch897 -p1 %patch898 -p1 +%patch899 -p1 +%patch900 -p1 # Fix executable permission for iotests chmod 755 $(ls tests/qemu-iotests/???) @@ -3591,6 +3597,12 @@ useradd -r -u 107 -g qemu -G kvm -d / -s /sbin/nologin \ %endif %changelog +* Wed Mar 04 2020 Miroslav Rezanina - ma-2.12.0-44.el7_8.1 +- kvm-util-add-slirp_fmt-helpers.patch [bz#1798974] +- kvm-tcp_emu-fix-unsafe-snprintf-usages.patch [bz#1798974] +- Resolves: bz#1798974 + (CVE-2020-8608 qemu-kvm-ma: QEMU: Slirp: potential OOB access due to unsafe snprintf() usages [rhel-7.8.z]) + * Wed Feb 05 2020 Miroslav Rezanina - 2.12.0-44.el7 - kvm-iscsi-Avoid-potential-for-get_status-overflow.patch [bz#1794505] - kvm-iscsi-Cap-block-count-from-GET-LBA-STATUS-CVE-2020-1.patch [bz#1794505]