50f0fe
From 2655fffed7a9e765bcb4701dd876e9dab975f289 Mon Sep 17 00:00:00 2001
50f0fe
From: Samuel Thibault <samuel.thibault@ens-lyon.org>
50f0fe
Date: Wed, 8 Jan 2020 00:58:48 +0100
50f0fe
Subject: [PATCH] tcp_emu: Fix oob access
50f0fe
50f0fe
The main loop only checks for one available byte, while we sometimes
50f0fe
need two bytes.
50f0fe
50f0fe
2.24.1
50f0fe
50f0fe
From 82ebe9c370a0e2970fb5695aa19aa5214a6a1c80 Mon Sep 17 00:00:00 2001
50f0fe
From: Prasad J Pandit <pjp@fedoraproject.org>
50f0fe
Date: Thu, 9 Jan 2020 15:12:28 +0530
50f0fe
Subject: [PATCH] slirp: use correct size while emulating commands
50f0fe
50f0fe
While emulating services in tcp_emu(), it uses 'mbuf' size
50f0fe
'm->m_size' to write commands via snprintf(3). Use M_FREEROOM(m)
50f0fe
size to avoid possible OOB access.
50f0fe
50f0fe
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
50f0fe
Signed-off-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
50f0fe
Message-Id: <20200109094228.79764-3-ppandit@redhat.com>
50f0fe
50f0fe
2.24.1
50f0fe
50f0fe
From ce131029d6d4a405cb7d3ac6716d03e58fb4a5d9 Mon Sep 17 00:00:00 2001
50f0fe
From: Prasad J Pandit <pjp@fedoraproject.org>
50f0fe
Date: Thu, 9 Jan 2020 15:12:27 +0530
50f0fe
Subject: [PATCH] slirp: use correct size while emulating IRC commands
50f0fe
50f0fe
While emulating IRC DCC commands, tcp_emu() uses 'mbuf' size
50f0fe
'm->m_size' to write DCC commands via snprintf(3). This may
50f0fe
lead to OOB write access, because 'bptr' points somewhere in
50f0fe
the middle of 'mbuf' buffer, not at the start. Use M_FREEROOM(m)
50f0fe
size to avoid OOB access.
50f0fe
50f0fe
Reported-by: Vishnu Dev TJ <vishnudevtj@gmail.com>
50f0fe
Signed-off-by: Prasad J Pandit <pjp@fedoraproject.org>
50f0fe
Reviewed-by: Samuel Thibault <samuel.thibault@ens-lyon.org>
50f0fe
Message-Id: <20200109094228.79764-2-ppandit@redhat.com>
50f0fe
50f0fe
---
50f0fe
 CHANGELOG.md   | 1 +
50f0fe
 src/tcp_subr.c | 7 +++++++
50f0fe
 2 files changed, 8 insertions(+)
50f0fe
50f0fe
diff -up slirp4netns-c4e1bc5a5e6987f3a352ca524f13320a2d483398/qemu/slirp/tcp_subr.c.CVE-2020-7039 slirp4netns-c4e1bc5a5e6987f3a352ca524f13320a2d483398/qemu/slirp/tcp_subr.c
50f0fe
--- slirp4netns-c4e1bc5a5e6987f3a352ca524f13320a2d483398/qemu/slirp/tcp_subr.c.CVE-2020-7039	2020-01-16 11:13:39.558653385 +0100
50f0fe
+++ slirp4netns-c4e1bc5a5e6987f3a352ca524f13320a2d483398/qemu/slirp/tcp_subr.c	2020-01-16 14:23:54.027184429 +0100
50f0fe
@@ -704,7 +704,7 @@ tcp_emu(struct socket *so, struct mbuf *
50f0fe
 			n4 =  (laddr & 0xff);
50f0fe
 
50f0fe
 			m->m_len = bptr - m->m_data; /* Adjust length */
50f0fe
-                        m->m_len += snprintf(bptr, m->m_size - m->m_len,
50f0fe
+                        m->m_len += snprintf(bptr, M_FREEROOM(m),
50f0fe
                                              "ORT %d,%d,%d,%d,%d,%d\r\n%s",
50f0fe
                                              n1, n2, n3, n4, n5, n6, x==7?buff:"");
50f0fe
 			return 1;
50f0fe
@@ -737,7 +737,7 @@ tcp_emu(struct socket *so, struct mbuf *
50f0fe
 			n4 =  (laddr & 0xff);
50f0fe
 
50f0fe
 			m->m_len = bptr - m->m_data; /* Adjust length */
50f0fe
-			m->m_len += snprintf(bptr, m->m_size - m->m_len,
50f0fe
+			m->m_len += snprintf(bptr, M_FREEROOM(m),
50f0fe
                                              "27 Entering Passive Mode (%d,%d,%d,%d,%d,%d)\r\n%s",
50f0fe
                                              n1, n2, n3, n4, n5, n6, x==7?buff:"");
50f0fe
 
50f0fe
@@ -763,7 +763,7 @@ tcp_emu(struct socket *so, struct mbuf *
50f0fe
 		if (m->m_data[m->m_len-1] == '\0' && lport != 0 &&
50f0fe
 		    (so = tcp_listen(slirp, INADDR_ANY, 0, so->so_laddr.s_addr,
50f0fe
 		                     htons(lport), SS_FACCEPTONCE)) != NULL)
50f0fe
-                    m->m_len = snprintf(m->m_data, m->m_size, "%d",
50f0fe
+                    m->m_len = snprintf(m->m_data, M_ROOM(m), "%d",
50f0fe
                                         ntohs(so->so_fport)) + 1;
50f0fe
 		return 1;
50f0fe
 
50f0fe
@@ -783,7 +783,7 @@ tcp_emu(struct socket *so, struct mbuf *
50f0fe
 				return 1;
50f0fe
 			}
50f0fe
 			m->m_len = bptr - m->m_data; /* Adjust length */
50f0fe
-                        m->m_len += snprintf(bptr, m->m_size,
50f0fe
+                        m->m_len += snprintf(bptr, M_FREEROOM(m),
50f0fe
                                              "DCC CHAT chat %lu %u%c\n",
50f0fe
                                              (unsigned long)ntohl(so->so_faddr.s_addr),
50f0fe
                                              ntohs(so->so_fport), 1);
50f0fe
@@ -794,7 +794,7 @@ tcp_emu(struct socket *so, struct mbuf *
50f0fe
 				return 1;
50f0fe
 			}
50f0fe
 			m->m_len = bptr - m->m_data; /* Adjust length */
50f0fe
-                        m->m_len += snprintf(bptr, m->m_size,
50f0fe
+                        m->m_len += snprintf(bptr, M_FREEROOM(m),
50f0fe
                                              "DCC SEND %s %lu %u %u%c\n", buff,
50f0fe
                                              (unsigned long)ntohl(so->so_faddr.s_addr),
50f0fe
                                              ntohs(so->so_fport), n1, 1);
50f0fe
@@ -805,7 +805,7 @@ tcp_emu(struct socket *so, struct mbuf *
50f0fe
 				return 1;
50f0fe
 			}
50f0fe
 			m->m_len = bptr - m->m_data; /* Adjust length */
50f0fe
-                        m->m_len += snprintf(bptr, m->m_size,
50f0fe
+                        m->m_len += snprintf(bptr, M_FREEROOM(m),
50f0fe
                                              "DCC MOVE %s %lu %u %u%c\n", buff,
50f0fe
                                              (unsigned long)ntohl(so->so_faddr.s_addr),
50f0fe
                                              ntohs(so->so_fport), n1, 1);
50f0fe
@@ -892,6 +892,9 @@ tcp_emu(struct socket *so, struct mbuf *
50f0fe
 				break;
50f0fe
 
50f0fe
 			 case 5:
50f0fe
+				if (bptr == m->m_data + m->m_len - 1)
50f0fe
+				    return 1; /* We need two bytes */
50f0fe
+
50f0fe
 				/*
50f0fe
 				 * The difference between versions 1.0 and
50f0fe
 				 * 2.0 is here. For future versions of
50f0fe
@@ -907,6 +910,9 @@ tcp_emu(struct socket *so, struct mbuf *
50f0fe
 				/* This is the field containing the port
50f0fe
 				 * number that RA-player is listening to.
50f0fe
 				 */
50f0fe
+				if (bptr == m->m_data + m->m_len - 1)
50f0fe
+				    return 1; /* We need two bytes */
50f0fe
+
50f0fe
 				lport = (((u_char*)bptr)[0] << 8)
50f0fe
 				+ ((u_char *)bptr)[1];
50f0fe
 				if (lport < 6970)