Security fixes (#1145878) ...

- CVE-2014-6051 (#1144287)
- CVE-2014-6052 (#1144288)
- CVE-2014-6053 (#1144289)
- CVE-2014-6054 (#1144291)
- CVE-2014-6055 (#1144293)
epel9
Rex Dieter 11 years ago
parent af4fbcf96f
commit de37ba2f0a

@ -0,0 +1,42 @@
commit 045a044e8ae79db9244593fbce154cdf6e843273
Author: newsoft <newsoft@MacBook-Air-de-newsoft-2.local>
Date: Fri Aug 15 16:31:13 2014 +0200
Fix integer overflow in MallocFrameBuffer()
Promote integers to uint64_t to avoid integer overflow issue during
frame buffer allocation for very large screen sizes
diff --git a/libvncclient/vncviewer.c b/libvncclient/vncviewer.c
index 3b16a6f..24bc6f8 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;
}

@ -0,0 +1,59 @@
commit 85a778c0e45e87e35ee7199f1f25020648e8b812
Author: newsoft <newsoft@MacBook-Air-de-newsoft-2.local>
Date: Fri Aug 15 16:41:58 2014 +0200
Check for MallocFrameBuffer() return value
If MallocFrameBuffer() returns FALSE, frame buffer pointer is left to
NULL. Subsequent writes into that buffer could lead to memory
corruption, or even arbitrary code execution.
diff --git a/libvncclient/rfbproto.c b/libvncclient/rfbproto.c
index b4d7156..f55c74f 100644
--- a/libvncclient/rfbproto.c
+++ b/libvncclient/rfbproto.c
@@ -1829,7 +1829,8 @@ HandleRFBServerMessage(rfbClient* client)
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;
@@ -2290,7 +2291,9 @@ HandleRFBServerMessage(rfbClient* client)
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;
@@ -2306,7 +2309,8 @@ HandleRFBServerMessage(rfbClient* client)
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;
diff --git a/libvncclient/vncviewer.c b/libvncclient/vncviewer.c
index 24bc6f8..65b7412 100644
--- a/libvncclient/vncviewer.c
+++ b/libvncclient/vncviewer.c
@@ -250,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;

@ -0,0 +1,22 @@
commit 6037a9074d52b1963c97cb28ea1096c7c14cbf28
Author: Nicolas Ruff <nruff@google.com>
Date: Mon Aug 18 15:16:16 2014 +0200
Check malloc() return value on client->server ClientCutText message. Client can send up to 2**32-1 bytes of text, and such a large allocation is likely to fail in case of high memory pressure. This would in a server crash (write at address 0).
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
index 5f3b31d..7e43fe3 100644
--- a/libvncserver/rfbserver.c
+++ b/libvncserver/rfbserver.c
@@ -2461,6 +2461,11 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
msg.cct.length = Swap32IfLE(msg.cct.length);
str = (char *)malloc(msg.cct.length);
+ if (str == NULL) {
+ rfbLogPerror("rfbProcessClientNormalMessage: not enough memory");
+ rfbCloseClient(cl);
+ return;
+ }
if ((n = rfbReadExact(cl, str, msg.cct.length)) <= 0) {
if (n != 0)

@ -0,0 +1,38 @@
commit 05a9bd41a8ec0a9d580a8f420f41718bdd235446
Author: Nicolas Ruff <nruff@google.com>
Date: Mon Aug 18 15:22:48 2014 +0200
Do not accept a scaling factor of zero on PalmVNCSetScaleFactor and SetScale client->server messages. This would cause a division by zero and crash the server.
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
index 7e43fe3..df7d74c 100644
--- a/libvncserver/rfbserver.c
+++ b/libvncserver/rfbserver.c
@@ -2491,6 +2491,13 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
rfbCloseClient(cl);
return;
}
+
+ if (msg.ssc.scale == 0) {
+ rfbLogPerror("rfbProcessClientNormalMessage: will not accept a scale factor of zero");
+ rfbCloseClient(cl);
+ return;
+ }
+
rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbSetScaleMsg, sz_rfbSetScaleMsg);
rfbLog("rfbSetScale(%d)\n", msg.ssc.scale);
rfbScalingSetup(cl,cl->screen->width/msg.ssc.scale, cl->screen->height/msg.ssc.scale);
@@ -2507,6 +2514,13 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
rfbCloseClient(cl);
return;
}
+
+ if (msg.ssc.scale == 0) {
+ rfbLogPerror("rfbProcessClientNormalMessage: will not accept a scale factor of zero");
+ rfbCloseClient(cl);
+ return;
+ }
+
rfbStatRecordMessageRcvd(cl, msg.type, sz_rfbSetScaleMsg, sz_rfbSetScaleMsg);
rfbLog("rfbSetScale(%d)\n", msg.ssc.scale);
rfbScalingSetup(cl,cl->screen->width/msg.ssc.scale, cl->screen->height/msg.ssc.scale);

@ -0,0 +1,165 @@
commit 06ccdf016154fde8eccb5355613ba04c59127b2e
Author: Nicolas Ruff <nruff@google.com>
Date: Mon Sep 1 14:36:26 2014 +0200
Fix multiple stack-based buffer overflows in file transfer feature
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
index df7d74c..445331a 100644
--- a/libvncserver/rfbserver.c
+++ b/libvncserver/rfbserver.c
@@ -1241,21 +1241,35 @@ typedef struct {
#define RFB_FILE_ATTRIBUTE_TEMPORARY 0x100
#define RFB_FILE_ATTRIBUTE_COMPRESSED 0x800
-rfbBool rfbFilenameTranslate2UNIX(rfbClientPtr cl, char *path, char *unixPath)
+rfbBool rfbFilenameTranslate2UNIX(rfbClientPtr cl, /* in */ char *path, /* out */ char *unixPath, size_t unixPathMaxLen )
{
int x;
char *home=NULL;
FILEXFER_ALLOWED_OR_CLOSE_AND_RETURN("", cl, FALSE);
+ /*
+ * Do not use strncpy() - truncating the file name would probably have undesirable side effects
+ * Instead check if destination buffer is big enough
+ */
+
+ if (strlen(path) >= unixPathMaxLen)
+ return FALSE;
+
/* C: */
if (path[0]=='C' && path[1]==':')
+ {
strcpy(unixPath, &path[2]);
+ }
else
{
home = getenv("HOME");
if (home!=NULL)
{
+ /* Re-check buffer size */
+ if ((strlen(path) + strlen(home) + 1) >= unixPathMaxLen)
+ return FALSE;
+
strcpy(unixPath, home);
strcat(unixPath,"/");
strcat(unixPath, path);
@@ -1293,7 +1307,8 @@ rfbBool rfbSendDirContent(rfbClientPtr cl, int length, char *buffer)
FILEXFER_ALLOWED_OR_CLOSE_AND_RETURN("", cl, FALSE);
/* Client thinks we are Winblows */
- rfbFilenameTranslate2UNIX(cl, buffer, path);
+ if (!rfbFilenameTranslate2UNIX(cl, buffer, path, sizeof(path)))
+ return FALSE;
if (DB) rfbLog("rfbProcessFileTransfer() rfbDirContentRequest: rfbRDirContent: \"%s\"->\"%s\"\n",buffer, path);
@@ -1570,7 +1585,11 @@ rfbBool rfbProcessFileTransfer(rfbClientPtr cl, uint8_t contentType, uint8_t con
/* add some space to the end of the buffer as we will be adding a timespec to it */
if ((buffer = rfbProcessFileTransferReadBuffer(cl, length))==NULL) return FALSE;
/* The client requests a File */
- rfbFilenameTranslate2UNIX(cl, buffer, filename1);
+ if (!rfbFilenameTranslate2UNIX(cl, buffer, filename1, sizeof(filename1)))
+ {
+ if (buffer!=NULL) free(buffer);
+ return FALSE;
+ }
cl->fileTransfer.fd=open(filename1, O_RDONLY, 0744);
/*
@@ -1685,7 +1704,11 @@ rfbBool rfbProcessFileTransfer(rfbClientPtr cl, uint8_t contentType, uint8_t con
}
sizeHtmp = Swap32IfLE(sizeHtmp);
- rfbFilenameTranslate2UNIX(cl, buffer, filename1);
+ if (!rfbFilenameTranslate2UNIX(cl, buffer, filename1, sizeof(filename1)))
+ {
+ if (buffer!=NULL) free(buffer);
+ return FALSE;
+ }
/* If the file exists... We can send a rfbFileChecksums back to the client before we send an rfbFileAcceptHeader */
/* TODO: Delta Transfer */
@@ -1814,7 +1837,12 @@ rfbBool rfbProcessFileTransfer(rfbClientPtr cl, uint8_t contentType, uint8_t con
if ((buffer = rfbProcessFileTransferReadBuffer(cl, length))==NULL) return FALSE;
switch (contentParam) {
case rfbCDirCreate: /* Client requests the creation of a directory */
- rfbFilenameTranslate2UNIX(cl, buffer, filename1);
+ if (!rfbFilenameTranslate2UNIX(cl, buffer, filename1, sizeof(filename1)))
+ {
+ if (buffer!=NULL) free(buffer);
+ return FALSE;
+ }
+
retval = mkdir(filename1, 0755);
if (DB) rfbLog("rfbProcessFileTransfer() rfbCommand: rfbCDirCreate(\"%s\"->\"%s\") %s\n", buffer, filename1, (retval==-1?"Failed":"Success"));
/*
@@ -1823,7 +1851,12 @@ rfbBool rfbProcessFileTransfer(rfbClientPtr cl, uint8_t contentType, uint8_t con
if (buffer!=NULL) free(buffer);
return retval;
case rfbCFileDelete: /* Client requests the deletion of a file */
- rfbFilenameTranslate2UNIX(cl, buffer, filename1);
+ if (!rfbFilenameTranslate2UNIX(cl, buffer, filename1, sizeof(filename1)))
+ {
+ if (buffer!=NULL) free(buffer);
+ return FALSE;
+ }
+
if (stat(filename1,&statbuf)==0)
{
if (S_ISDIR(statbuf.st_mode))
@@ -1841,8 +1874,18 @@ rfbBool rfbProcessFileTransfer(rfbClientPtr cl, uint8_t contentType, uint8_t con
{
/* Split into 2 filenames ('*' is a seperator) */
*p = '\0';
- rfbFilenameTranslate2UNIX(cl, buffer, filename1);
- rfbFilenameTranslate2UNIX(cl, p+1, filename2);
+ if (!rfbFilenameTranslate2UNIX(cl, buffer, filename1, sizeof(filename1)))
+ {
+ if (buffer!=NULL) free(buffer);
+ return FALSE;
+ }
+
+ if (!rfbFilenameTranslate2UNIX(cl, p+1, filename2, sizeof(filename2)))
+ {
+ if (buffer!=NULL) free(buffer);
+ return FALSE;
+ }
+
retval = rename(filename1,filename2);
if (DB) rfbLog("rfbProcessFileTransfer() rfbCommand: rfbCFileRename(\"%s\"->\"%s\" -->> \"%s\"->\"%s\") %s\n", buffer, filename1, p+1, filename2, (retval==-1?"Failed":"Success"));
/*
commit f528072216dec01cee7ca35d94e171a3b909e677
Author: Nicolas Ruff <nruff@google.com>
Date: Mon Sep 1 14:51:07 2014 +0200
Fix stack-based buffer overflow in rfbFileTransferOffer message, FileTime processing
diff --git a/libvncserver/rfbserver.c b/libvncserver/rfbserver.c
index 445331a..23532b0 100644
--- a/libvncserver/rfbserver.c
+++ b/libvncserver/rfbserver.c
@@ -1683,16 +1683,17 @@ rfbBool rfbProcessFileTransfer(rfbClientPtr cl, uint8_t contentType, uint8_t con
*/
if ((buffer = rfbProcessFileTransferReadBuffer(cl, length))==NULL) return FALSE;
- /* Parse the FileTime */
+ /* Parse the FileTime
+ * TODO: FileTime is actually never used afterwards
+ */
p = strrchr(buffer, ',');
if (p!=NULL) {
*p = '\0';
- strcpy(szFileTime, p+1);
+ strncpy(szFileTime, p+1, sizeof(szFileTime));
+ szFileTime[sizeof(szFileTime)-1] = '\x00'; /* ensure NULL terminating byte is present, even if copy overflowed */
} else
szFileTime[0]=0;
-
-
/* Need to read in sizeHtmp */
if ((n = rfbReadExact(cl, (char *)&sizeHtmp, 4)) <= 0) {
if (n != 0)

@ -30,6 +30,19 @@ Patch12: 0002-allow-rfbInitSockets-with-non-ready-states.patch
## upstream patches ## upstream patches
## security patches
## pulled from (fork): https://github.com/newsoft/libvncserver
# https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2014-6051
Patch201: CVE-2014-6051.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2014-6052
Patch202: CVE-2014-6052.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2014-6053
Patch203: CVE-2014-6053.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2014-6054
Patch204: CVE-2014-6054.patch
# https://bugzilla.redhat.com/show_bug.cgi?id=CVE-2014-6055
Patch205: CVE-2014-6055.patch
# upstream name # upstream name
Obsoletes: LibVNCServer < 0.9.1 Obsoletes: LibVNCServer < 0.9.1
Provides: LibVNCServer = %{version}-%{release} Provides: LibVNCServer = %{version}-%{release}
@ -84,6 +97,11 @@ rm -fv common/lzodefs.h common/lzoconf.h commmon/minilzo.h common/minilzo.c
%patch3 -p1 -b .pkgconfig %patch3 -p1 -b .pkgconfig
%patch11 -p1 -b .0001 %patch11 -p1 -b .0001
%patch12 -p1 -b .0002 %patch12 -p1 -b .0002
%patch201 -p1 -b .CVE-2014-6051
%patch202 -p1 -b .CVE-2014-6052
%patch203 -p1 -b .CVE-2014-6053
%patch204 -p1 -b .CVE-2014-6054
%patch205 -p1 -b .CVE-2014-6055
# fix encoding # fix encoding
for file in AUTHORS ChangeLog ; do for file in AUTHORS ChangeLog ; do
@ -151,6 +169,14 @@ xvfb-run -a make -C test test ||:
%changelog %changelog
* Thu Sep 25 2014 Rex Dieter <rdieter@fedoraproject.org> 0.9.10-0.5.20140718git9453be42
- Security fixes (#1145878) ...
- CVE-2014-6051 (#1144287)
- CVE-2014-6052 (#1144288)
- CVE-2014-6053 (#1144289)
- CVE-2014-6054 (#1144291)
- CVE-2014-6055 (#1144293)
* Sun Aug 17 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.9.10-0.5.20140718git9453be42 * Sun Aug 17 2014 Fedora Release Engineering <rel-eng@lists.fedoraproject.org> - 0.9.10-0.5.20140718git9453be42
- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild - Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild

Loading…
Cancel
Save