Description: patch for CVE-2020-8608 Index: slirp-1.0.17/src/misc.c =================================================================== --- slirp-1.0.17.orig/src/misc.c 2020-12-22 09:39:03.378638270 +0100 +++ slirp-1.0.17/src/misc.c 2020-12-22 09:39:03.370637710 +0100 @@ -8,6 +8,7 @@ #define WANT_SYS_IOCTL_H #include #include +#include "debug.h" u_int curtime, time_fasttimo, last_slowtimo, detach_time; u_int detach_wait = 600000; /* 10 minutes */ @@ -981,9 +982,64 @@ return ptr; } +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) { + DEBUG_ERROR(("vsnprintf() failed: %s", 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 + */ +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) { + DEBUG_ERROR((dfd, "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 + */ +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) { + DEBUG_ERROR((dfd, "vsnprintf() truncation")); + if (size > 0) + str[size - 1] = '\0'; + rv = size; + } else { + rv += 1; /* include \0 */ + } + return rv; +} Index: slirp-1.0.17/src/misc.h =================================================================== --- slirp-1.0.17.orig/src/misc.h 2020-12-22 09:39:03.378638270 +0100 +++ slirp-1.0.17/src/misc.h 2020-12-22 09:39:03.374637990 +0100 @@ -29,6 +29,9 @@ void do_wait _P((int)); +int slirp_fmt(char *str, size_t size, const char *format, ...); +int slirp_fmt0(char *str, size_t size, const char *format, ...); + #define EMU_NONE 0x0 /* TCP emulations */ Index: slirp-1.0.17/src/tcp_subr.c =================================================================== --- slirp-1.0.17.orig/src/tcp_subr.c 2020-12-22 09:39:03.378638270 +0100 +++ slirp-1.0.17/src/tcp_subr.c 2020-12-22 09:39:03.374637990 +0100 @@ -1015,8 +1015,8 @@ 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) { /* @@ -1046,9 +1046,9 @@ 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; } @@ -1071,7 +1071,7 @@ } if (m->m_data[m->m_len-1] == '\0' && lport != 0 && (so = solisten(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)) + 1; return 1; case EMU_IRC: @@ -1088,7 +1088,7 @@ 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", + 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) { @@ -1096,7 +1096,7 @@ 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", + 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) { @@ -1104,7 +1104,7 @@ 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", + 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); }