diff options
Diffstat (limited to 'libvncserver/rfbserver.c')
-rw-r--r-- | libvncserver/rfbserver.c | 48 |
1 files changed, 37 insertions, 11 deletions
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c index fa8423d..182d18b 100644 --- a/libvncserver/rfbserver.c +++ b/libvncserver/rfbserver.c @@ -32,6 +32,7 @@ #include <rfb/rfb.h> #include <rfb/rfbregion.h> #include "private.h" +#include "rfb/rfbconfig.h" #ifdef LIBVNCSERVER_HAVE_FCNTL_H #include <fcntl.h> @@ -69,7 +70,9 @@ /* stst() */ #include <sys/types.h> #include <sys/stat.h> +#if LIBVNCSERVER_HAVE_UNISTD_H #include <unistd.h> +#endif #ifndef WIN32 /* readdir() */ @@ -457,9 +460,7 @@ rfbNewTCPOrUDPClient(rfbScreenInfoPtr rfbScreen, #ifdef LIBVNCSERVER_WITH_WEBSOCKETS /* - * Wait a few ms for the client to send one of: - * - Flash policy request - * - WebSockets connection (TLS/SSL or plain) + * Wait a few ms for the client to send WebSockets connection (TLS/SSL or plain) */ if (!webSocketsCheck(cl)) { /* Error reporting handled in webSocketsHandshake */ @@ -615,6 +616,11 @@ rfbClientConnectionGone(rfbClientPtr cl) UNLOCK(cl->sendMutex); TINI_MUTEX(cl->sendMutex); +#ifdef LIBVNCSERVER_HAVE_LIBPTHREAD + close(cl->pipe_notify_client_thread[0]); + close(cl->pipe_notify_client_thread[1]); +#endif + rfbPrintStats(cl); rfbResetStats(cl); @@ -1457,11 +1463,21 @@ char *rfbProcessFileTransferReadBuffer(rfbClientPtr cl, uint32_t length) int n=0; FILEXFER_ALLOWED_OR_CLOSE_AND_RETURN("", cl, NULL); + /* - rfbLog("rfbProcessFileTransferReadBuffer(%dlen)\n", length); + We later alloc length+1, which might wrap around on 32-bit systems if length equals + 0XFFFFFFFF, i.e. SIZE_MAX for 32-bit systems. On 64-bit systems, a length of 0XFFFFFFFF + will safely be allocated since this check will never trigger and malloc() can digest length+1 + without problems as length is a uint32_t. */ + if(length == SIZE_MAX) { + rfbErr("rfbProcessFileTransferReadBuffer: too big file transfer length requested: %u", (unsigned int)length); + rfbCloseClient(cl); + return NULL; + } + if (length>0) { - buffer=malloc(length+1); + buffer=malloc((size_t)length+1); if (buffer!=NULL) { if ((n = rfbReadExact(cl, (char *)buffer, length)) <= 0) { if (n != 0) @@ -1993,11 +2009,6 @@ rfbProcessClientNormalMessage(rfbClientPtr cl) char encBuf[64]; char encBuf2[64]; -#ifdef LIBVNCSERVER_WITH_WEBSOCKETS - if (cl->wsctx && webSocketCheckDisconnect(cl)) - return; -#endif - if ((n = rfbReadExact(cl, (char *)&msg, 1)) <= 0) { if (n != 0) rfbLogPerror("rfbProcessClientNormalMessage: read"); @@ -2582,7 +2593,22 @@ rfbProcessClientNormalMessage(rfbClientPtr cl) msg.cct.length = Swap32IfLE(msg.cct.length); - str = (char *)malloc(msg.cct.length); + /* uint32_t input is passed to malloc()'s size_t argument, + * to rfbReadExact()'s int argument, to rfbStatRecordMessageRcvd()'s int + * argument increased of sz_rfbClientCutTextMsg, and to setXCutText()'s int + * argument. Here we impose a limit of 1 MB so that the value fits + * into all of the types to prevent from misinterpretation and thus + * from accessing uninitialized memory (CVE-2018-7225) and also to + * prevent from a denial-of-service by allocating too much memory in + * the server. */ + if (msg.cct.length > 1<<20) { + rfbLog("rfbClientCutText: too big cut text length requested: %u B > 1 MB\n", (unsigned int)msg.cct.length); + rfbCloseClient(cl); + return; + } + + /* Allow zero-length client cut text. */ + str = (char *)calloc(msg.cct.length ? msg.cct.length : 1, 1); if (str == NULL) { rfbLogPerror("rfbProcessClientNormalMessage: not enough memory"); rfbCloseClient(cl); |