diff options
Diffstat (limited to 'libvncclient/vncviewer.c')
-rw-r--r-- | libvncclient/vncviewer.c | 23 |
1 files changed, 21 insertions, 2 deletions
diff --git a/libvncclient/vncviewer.c b/libvncclient/vncviewer.c index 3b16a6f..65b7412 100644 --- a/libvncclient/vncviewer.c +++ b/libvncclient/vncviewer.c @@ -82,9 +82,27 @@ static char* ReadPassword(rfbClient* client) { #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; } @@ -232,7 +250,8 @@ static rfbBool rfbInitConnection(rfbClient* client) client->width=client->si.framebufferWidth; client->height=client->si.framebufferHeight; - client->MallocFrameBuffer(client); + if (!client->MallocFrameBuffer(client)) + return FALSE; if (!SetFormatAndEncodings(client)) return FALSE; |