Description: fix denial of service and possible code execution via integer overflow and lack of malloc error handling in MallocFrameBuffer() Origin: backport, https://github.com/newsoft/libvncserver/commit/045a044e8ae79db9244593fbce154cdf6e843273 Origin: backport, https://github.com/newsoft/libvncserver/commit/85a778c0e45e87e35ee7199f1f25020648e8b812 Signed-off-by: Gustavo Zacarias Index: libvncserver-0.9.9+dfsg/libvncclient/rfbproto.c =================================================================== --- libvncserver-0.9.9+dfsg.orig/libvncclient/rfbproto.c 2012-05-04 10:19:00.000000000 -0400 +++ libvncserver-0.9.9+dfsg/libvncclient/rfbproto.c 2014-09-25 11:11:55.884057336 -0400 @@ -1807,7 +1807,8 @@ client->updateRect.x = client->updateRect.y = 0; client->updateRect.w = client->width; client->updateRect.h = client->height; - client->MallocFrameBuffer(client); + if (!client->MallocFrameBuffer(client)) + return FALSE; SendFramebufferUpdateRequest(client, 0, 0, rect.r.w, rect.r.h, FALSE); rfbClientLog("Got new framebuffer size: %dx%d\n", rect.r.w, rect.r.h); continue; @@ -2260,7 +2261,8 @@ client->updateRect.x = client->updateRect.y = 0; client->updateRect.w = client->width; client->updateRect.h = client->height; - client->MallocFrameBuffer(client); + if (!client->MallocFrameBuffer(client)) + return FALSE; SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE); rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height); break; @@ -2276,7 +2278,9 @@ client->updateRect.x = client->updateRect.y = 0; client->updateRect.w = client->width; client->updateRect.h = client->height; - client->MallocFrameBuffer(client); + if (!client->MallocFrameBuffer(client)) + return FALSE; + SendFramebufferUpdateRequest(client, 0, 0, client->width, client->height, FALSE); rfbClientLog("Got new framebuffer size: %dx%d\n", client->width, client->height); break; Index: libvncserver-0.9.9+dfsg/libvncclient/vncviewer.c =================================================================== --- libvncserver-0.9.9+dfsg.orig/libvncclient/vncviewer.c 2012-05-04 10:19:00.000000000 -0400 +++ libvncserver-0.9.9+dfsg/libvncclient/vncviewer.c 2014-09-25 11:10:29.984055035 -0400 @@ -82,9 +82,27 @@ #endif } static rfbBool MallocFrameBuffer(rfbClient* client) { +uint64_t allocSize; + if(client->frameBuffer) free(client->frameBuffer); - client->frameBuffer=malloc(client->width*client->height*client->format.bitsPerPixel/8); + + /* SECURITY: promote 'width' into uint64_t so that the multiplication does not overflow + 'width' and 'height' are 16-bit integers per RFB protocol design + SIZE_MAX is the maximum value that can fit into size_t + */ + allocSize = (uint64_t)client->width * client->height * client->format.bitsPerPixel/8; + + if (allocSize >= SIZE_MAX) { + rfbClientErr("CRITICAL: cannot allocate frameBuffer, requested size is too large\n"); + return FALSE; + } + + client->frameBuffer=malloc( (size_t)allocSize ); + + if (client->frameBuffer == NULL) + rfbClientErr("CRITICAL: frameBuffer allocation failed, requested size too large or not enough memory?\n"); + return client->frameBuffer?TRUE:FALSE; } @@ -225,7 +243,8 @@ client->width=client->si.framebufferWidth; client->height=client->si.framebufferHeight; - client->MallocFrameBuffer(client); + if (!client->MallocFrameBuffer(client)) + return FALSE; if (!SetFormatAndEncodings(client)) return FALSE;