summaryrefslogtreecommitdiffstats
path: root/package/libvncserver/libvncserver-0004-CVE-2014-6055.patch
diff options
context:
space:
mode:
Diffstat (limited to 'package/libvncserver/libvncserver-0004-CVE-2014-6055.patch')
-rw-r--r--package/libvncserver/libvncserver-0004-CVE-2014-6055.patch150
1 files changed, 150 insertions, 0 deletions
diff --git a/package/libvncserver/libvncserver-0004-CVE-2014-6055.patch b/package/libvncserver/libvncserver-0004-CVE-2014-6055.patch
new file mode 100644
index 0000000000..2a6ee76ae3
--- /dev/null
+++ b/package/libvncserver/libvncserver-0004-CVE-2014-6055.patch
@@ -0,0 +1,150 @@
+Description: fix denial of service and possible code execution via
+ stack overflows in File Transfer feature
+Origin: backport, https://github.com/newsoft/libvncserver/commit/06ccdf016154fde8eccb5355613ba04c59127b2e
+Origin: backport, https://github.com/newsoft/libvncserver/commit/f528072216dec01cee7ca35d94e171a3b909e677
+Origin: backport, https://github.com/newsoft/libvncserver/commit/256964b884c980038cd8b2f0d180fbb295b1c748
+
+Signed-off-by: Gustavo Zacarias <gustavo@zacarias.com.ar>
+
+Index: libvncserver-0.9.9+dfsg/libvncserver/rfbserver.c
+===================================================================
+--- libvncserver-0.9.9+dfsg.orig/libvncserver/rfbserver.c 2014-09-25 11:20:22.972070915 -0400
++++ libvncserver-0.9.9+dfsg/libvncserver/rfbserver.c 2014-09-25 11:20:40.368071381 -0400
+@@ -1237,21 +1237,35 @@
+ #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);
+@@ -1289,7 +1303,8 @@
+ 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);
+
+@@ -1566,7 +1581,9 @@
+ /* 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)))
++ goto fail;
++
+ cl->fileTransfer.fd=open(filename1, O_RDONLY, 0744);
+
+ /*
+@@ -1660,16 +1677,17 @@
+ */
+ 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)
+@@ -1681,7 +1699,8 @@
+ }
+ sizeHtmp = Swap32IfLE(sizeHtmp);
+
+- rfbFilenameTranslate2UNIX(cl, buffer, filename1);
++ if (!rfbFilenameTranslate2UNIX(cl, buffer, filename1, sizeof(filename1)))
++ goto fail;
+
+ /* If the file exists... We can send a rfbFileChecksums back to the client before we send an rfbFileAcceptHeader */
+ /* TODO: Delta Transfer */
+@@ -1810,7 +1829,9 @@
+ 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)))
++ goto fail;
++
+ retval = mkdir(filename1, 0755);
+ if (DB) rfbLog("rfbProcessFileTransfer() rfbCommand: rfbCDirCreate(\"%s\"->\"%s\") %s\n", buffer, filename1, (retval==-1?"Failed":"Success"));
+ /*
+@@ -1819,7 +1840,9 @@
+ 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)))
++ goto fail;
++
+ if (stat(filename1,&statbuf)==0)
+ {
+ if (S_ISDIR(statbuf.st_mode))
+@@ -1837,8 +1860,12 @@
+ {
+ /* 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)))
++ goto fail;
++
++ if (!rfbFilenameTranslate2UNIX(cl, p+1, filename2, sizeof(filename2)))
++ goto fail;
++
+ 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"));
+ /*
+@@ -1858,6 +1885,10 @@
+ /* NOTE: don't forget to free(buffer) if you return early! */
+ if (buffer!=NULL) free(buffer);
+ return TRUE;
++
++fail:
++ if (buffer!=NULL) free(buffer);
++ return FALSE;
+ }
+
+ /*
OpenPOWER on IntegriCloud