86 lines
3.5 KiB
Diff
86 lines
3.5 KiB
Diff
|
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 <gustavo@zacarias.com.ar>
|
||
|
|
||
|
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;
|