aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRaphael Kubo da Costa <rakuco@FreeBSD.org>2014-09-25 09:08:23 +0000
committerRaphael Kubo da Costa <rakuco@FreeBSD.org>2014-09-25 09:08:23 +0000
commitc892043c43ae802fb5e830d1588e87465cad2864 (patch)
treeabdba07d8bba9f93d65bf95c137ad291334518af
parent6e36a23e27b52dfb2a50e1d9343ed0703b22322b (diff)
downloadports-c892043c43ae802fb5e830d1588e87465cad2864.tar.gz
ports-c892043c43ae802fb5e830d1588e87465cad2864.zip
MFH: r369207
Add upstream patches for CVE-2014-6055 (more vulnerabilities in libvncserver). Don't worry, more recent krfb versions will stop bundling libvncserver. Security: fb25333d-442f-11e4-98f3-5453ed2e2b49 Approved by: portmgr (erwin), ports-secteam (rea)
Notes
Notes: svn path=/branches/2014Q3/; revision=369224
-rw-r--r--net/krfb/Makefile2
-rw-r--r--net/krfb/files/patch-CVE-2014-6055212
2 files changed, 213 insertions, 1 deletions
diff --git a/net/krfb/Makefile b/net/krfb/Makefile
index c7d8cee140bb..fd60e9b10269 100644
--- a/net/krfb/Makefile
+++ b/net/krfb/Makefile
@@ -2,7 +2,7 @@
PORTNAME= krfb
PORTVERSION= ${KDE4_VERSION}
-PORTREVISION= 1
+PORTREVISION= 4
CATEGORIES= net kde
MASTER_SITES= KDE/${KDE4_BRANCH}/${PORTVERSION}/src
DIST_SUBDIR= KDE/${PORTVERSION}
diff --git a/net/krfb/files/patch-CVE-2014-6055 b/net/krfb/files/patch-CVE-2014-6055
new file mode 100644
index 000000000000..a39aea378353
--- /dev/null
+++ b/net/krfb/files/patch-CVE-2014-6055
@@ -0,0 +1,212 @@
+Fixes for CVE-2014-6055, taken from upstream.
+
+commit d931eafccf3140d740ac61e876dce72a23ade7f4
+Author: Martin T. H. Sandsmark <martin.sandsmark@kde.org>
+Date: Tue Sep 23 22:46:27 2014 +0200
+
+ libvncserver: 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).
+
+ Upstream commit: 6037a9074d52b1963c97cb28ea1096c7c14cbf28
+
+commit 126a746dd7bee35840083e9bec7a52935a010346
+Author: Martin T. H. Sandsmark <martin.sandsmark@kde.org>
+Date: Tue Sep 23 22:43:38 2014 +0200
+
+ libnvcserver: Do not accept a scaling factor of zero.
+
+ This would cause a division by zero and crash the server.
+
+ Upstream commit: 05a9bd41a8ec0a9d580a8f420f41718bdd235446
+
+commit 2e211579455fd832fb21322482c005b6a85aa1bf
+Author: Martin T. H. Sandsmark <martin.sandsmark@kde.org>
+Date: Tue Sep 23 22:40:17 2014 +0200
+
+ libvncserver: Fix multiple stack-based buffer overflows in file transfer feature
+
+ Upstream commit: 06ccdf016154fde8eccb5355613ba04c59127b2e
+
+ CVE-2014-6055
+
+commit 857c2b411ed806ef806116407612a2d2a40fab9c
+Author: Martin T. H. Sandsmark <martin.sandsmark@kde.org>
+Date: Tue Sep 23 17:54:11 2014 +0200
+
+ libvncserver: Fix stack-based buffer overflow in rfbFileTransferOffer message, FileTime processing
+
+ Upstream commit: f528072216dec01cee7ca35d94e171a3b909e677
+
+ CVE-2014-6055
+--- libvncserver/rfbserver.c
++++ libvncserver/rfbserver.c
+@@ -1175,13 +1175,21 @@ 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, char *path, 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]);
+@@ -1190,6 +1198,10 @@ rfbBool rfbFilenameTranslate2UNIX(rfbClientPtr cl, char *path, char *unixPath)
+ 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);
+@@ -1227,7 +1239,9 @@ 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);
+
+@@ -1504,7 +1518,12 @@ 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);
+
+ /*
+@@ -1602,7 +1621,8 @@ rfbBool rfbProcessFileTransfer(rfbClientPtr cl, uint8_t contentType, uint8_t con
+ 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;
+
+@@ -1619,7 +1639,12 @@ 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 */
+@@ -1745,7 +1770,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"));
+ /*
+@@ -1754,7 +1784,11 @@ 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))
+@@ -1772,8 +1806,17 @@ 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"));
+ /*
+@@ -2361,6 +2404,12 @@ rfbProcessClientNormalMessage(rfbClientPtr cl)
+
+ 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)
+ rfbLogPerror("rfbProcessClientNormalMessage: read");
+@@ -2385,6 +2434,11 @@ 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);
+@@ -2401,6 +2455,11 @@ 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);