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