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