Control: tags 762745 + patch Dear maintainer,
I prepared below patch by cherry-picking upstream patches. I did NOT yet test the resulting package, but I will do ASAP. Meanwhile feeback is appreciated. (I will after testing probably do an NMU to DELAY/5, but I will announce that seperatly.) -- tobi Regards. diff -Nru libvncserver-0.9.9+dfsg/debian/changelog libvncserver-0.9.9+dfsg/debian/changelog --- libvncserver-0.9.9+dfsg/debian/changelog 2014-08-12 16:02:30.000000000 +0200 +++ libvncserver-0.9.9+dfsg/debian/changelog 2014-11-23 16:19:53.000000000 +0100 @@ -1,3 +1,12 @@ +libvncserver (0.9.9+dfsg-6.1) unstable; urgency=medium + + * Non-maintainer upload. + * CVE-2014-6051, CVE-2014-6052, CVE-2014-6053, CVE-2014-6054, CVE-2014-6055: + Multiple issues in libVNCserver -- cherry picking targeted fixed from + upstream (Closes: #762745) + + -- Tobias Frost <t...@debian.org> Sun, 23 Nov 2014 16:19:53 +0100 + libvncserver (0.9.9+dfsg-6) unstable; urgency=medium [ Luca Falavigna ] diff -Nru libvncserver-0.9.9+dfsg/debian/patches/CVE-2014-6051.patch libvncserver-0.9.9+dfsg/debian/patches/CVE-2014-6051.patch --- libvncserver-0.9.9+dfsg/debian/patches/CVE-2014-6051.patch 1970-01-01 01:00:00.000000000 +0100 +++ libvncserver-0.9.9+dfsg/debian/patches/CVE-2014-6051.patch 2014-11-23 15:29:25.000000000 +0100 @@ -0,0 +1,39 @@ +Description: Fix integer overflow in MallocFrameBuffer() (CVE-2014-6051) + Promote integers to uint64_t to avoid integer overflow issue during + frame buffer allocation for very large screen sizes +Origin: https://github.com/newsoft/libvncserver/commit/045a044e8ae79db9244593fbce154cdf6e843273 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: libvncserver-0.9.9+dfsg/libvncclient/vncviewer.c +=================================================================== +--- libvncserver-0.9.9+dfsg.orig/libvncclient/vncviewer.c ++++ libvncserver-0.9.9+dfsg/libvncclient/vncviewer.c +@@ -82,9 +82,27 @@ static char* ReadPassword(rfbClient* cli + #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; + } + diff -Nru libvncserver-0.9.9+dfsg/debian/patches/CVE-2014-6052.patch libvncserver-0.9.9+dfsg/debian/patches/CVE-2014-6052.patch --- libvncserver-0.9.9+dfsg/debian/patches/CVE-2014-6052.patch 1970-01-01 01:00:00.000000000 +0100 +++ libvncserver-0.9.9+dfsg/debian/patches/CVE-2014-6052.patch 2014-11-23 15:39:16.000000000 +0100 @@ -0,0 +1,56 @@ +Description: Check for MallocFrameBuffer() return value (CVE-2014-6052) + 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. +Origin: https://github.com/newsoft/libvncserver/commit/85a778c0e45e87e35ee7199f1f25020648e8b812 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: libvncserver-0.9.9+dfsg/libvncclient/rfbproto.c +=================================================================== +--- libvncserver-0.9.9+dfsg.orig/libvncclient/rfbproto.c ++++ libvncserver-0.9.9+dfsg/libvncclient/rfbproto.c +@@ -1807,7 +1807,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; +@@ -2260,7 +2261,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; +@@ -2276,7 +2278,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; +Index: libvncserver-0.9.9+dfsg/libvncclient/vncviewer.c +=================================================================== +--- libvncserver-0.9.9+dfsg.orig/libvncclient/vncviewer.c ++++ libvncserver-0.9.9+dfsg/libvncclient/vncviewer.c +@@ -243,7 +243,8 @@ static rfbBool rfbInitConnection(rfbClie + + client->width=client->si.framebufferWidth; + client->height=client->si.framebufferHeight; +- client->MallocFrameBuffer(client); ++ if (!client->MallocFrameBuffer(client)) ++ return FALSE; + + if (!SetFormatAndEncodings(client)) + return FALSE; diff -Nru libvncserver-0.9.9+dfsg/debian/patches/CVE-2014-6054.patch libvncserver-0.9.9+dfsg/debian/patches/CVE-2014-6054.patch --- libvncserver-0.9.9+dfsg/debian/patches/CVE-2014-6054.patch 1970-01-01 01:00:00.000000000 +0100 +++ libvncserver-0.9.9+dfsg/debian/patches/CVE-2014-6054.patch 2014-11-23 15:54:17.000000000 +0100 @@ -0,0 +1,39 @@ +Description: Do not accept a scaling factor of zero (CVE-2014-6054) + 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. +Origin: https://github.com/newsoft/libvncserver/commit/05a9bd41a8ec0a9d580a8f420f41718bdd235446 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: libvncserver-0.9.9+dfsg/libvncserver/rfbserver.c +=================================================================== +--- libvncserver-0.9.9+dfsg.orig/libvncserver/rfbserver.c ++++ libvncserver-0.9.9+dfsg/libvncserver/rfbserver.c +@@ -2487,6 +2487,13 @@ rfbProcessClientNormalMessage(rfbClientP + 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); +@@ -2503,6 +2510,13 @@ rfbProcessClientNormalMessage(rfbClientP + 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); diff -Nru libvncserver-0.9.9+dfsg/debian/patches/CVE-2014-6055.patch libvncserver-0.9.9+dfsg/debian/patches/CVE-2014-6055.patch --- libvncserver-0.9.9+dfsg/debian/patches/CVE-2014-6055.patch 1970-01-01 01:00:00.000000000 +0100 +++ libvncserver-0.9.9+dfsg/debian/patches/CVE-2014-6055.patch 2014-11-23 16:29:51.000000000 +0100 @@ -0,0 +1,152 @@ +Descript$ion: Fix multiple stack-based buffer overflows in file transfer feature + Note: The patch has been modified to be a targeting fix without the risk of breaking +ABI -- https://bugzilla.redhat.com/show_bug.cgi?id=1144293#c2. +However, as this function is not in header it is unlikely to be used outside of the lib. +Origin: https://github.com/newsoft/libvncserver/commit/06ccdf016154fde8eccb5355613ba04c59127b2e +Origin: https://github.com/newsoft/libvncserver/commit/f528072216dec01cee7ca35d94e171a3b909e677 +Origin: https://github.com/newsoft/libvncserver/commit/256964b884c980038cd8b2f0d180fbb295b1c748 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: libvncserver-0.9.9+dfsg/libvncserver/rfbserver.c +=================================================================== +--- libvncserver-0.9.9+dfsg.orig/libvncserver/rfbserver.c ++++ libvncserver-0.9.9+dfsg/libvncserver/rfbserver.c +@@ -1237,21 +1237,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 ) + { + int x; + char *home=NULL; +- ++ size_t unixPathMaxLen = MAX_PATH; + 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 @@ rfbBool rfbSendDirContent(rfbClientPtr c + FILEXFER_ALLOWED_OR_CLOSE_AND_RETURN("", cl, FALSE); + + /* Client thinks we are Winblows */ +- rfbFilenameTranslate2UNIX(cl, buffer, path); ++ if (!rfbFilenameTranslate2UNIX(cl, buffer, path)) ++ return FALSE; + + if (DB) rfbLog("rfbProcessFileTransfer() rfbDirContentRequest: rfbRDirContent: \"%s\"->\"%s\"\n",buffer, path); + +@@ -1566,7 +1581,9 @@ rfbBool rfbProcessFileTransfer(rfbClient + /* 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)) ++ goto fail; ++ + cl->fileTransfer.fd=open(filename1, O_RDONLY, 0744); + + /* +@@ -1660,16 +1677,17 @@ rfbBool rfbProcessFileTransfer(rfbClient + */ + 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 @@ rfbBool rfbProcessFileTransfer(rfbClient + } + sizeHtmp = Swap32IfLE(sizeHtmp); + +- rfbFilenameTranslate2UNIX(cl, buffer, filename1); ++ if (!rfbFilenameTranslate2UNIX(cl, buffer, 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 @@ rfbBool rfbProcessFileTransfer(rfbClient + 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)) ++ 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 @@ rfbBool rfbProcessFileTransfer(rfbClient + 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)) ++ goto fail; ++ + if (stat(filename1,&statbuf)==0) + { + if (S_ISDIR(statbuf.st_mode)) +@@ -1837,8 +1860,12 @@ rfbBool rfbProcessFileTransfer(rfbClient + { + /* Split into 2 filenames ('*' is a seperator) */ + *p = '\0'; +- rfbFilenameTranslate2UNIX(cl, buffer, filename1); +- rfbFilenameTranslate2UNIX(cl, p+1, filename2); ++ if (!rfbFilenameTranslate2UNIX(cl, buffer, filename1)) ++ goto fail; ++ ++ if (!rfbFilenameTranslate2UNIX(cl, p+1, 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 @@ rfbBool rfbProcessFileTransfer(rfbClient + /* 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; + } + + /* diff -Nru libvncserver-0.9.9+dfsg/debian/patches/CVE-2015-6053.patch libvncserver-0.9.9+dfsg/debian/patches/CVE-2015-6053.patch --- libvncserver-0.9.9+dfsg/debian/patches/CVE-2015-6053.patch 1970-01-01 01:00:00.000000000 +0100 +++ libvncserver-0.9.9+dfsg/debian/patches/CVE-2015-6053.patch 2014-11-23 15:45:29.000000000 +0100 @@ -0,0 +1,24 @@ +Description: Check malloc() return value (CVE-2014-6053) + 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). +Origin: https://github.com/newsoft/libvncserver/commit/6037a9074d52b1963c97cb28ea1096c7c14cbf28 +--- +This patch header follows DEP-3: http://dep.debian.net/deps/dep3/ +Index: libvncserver-0.9.9+dfsg/libvncserver/rfbserver.c +=================================================================== +--- libvncserver-0.9.9+dfsg.orig/libvncserver/rfbserver.c ++++ libvncserver-0.9.9+dfsg/libvncserver/rfbserver.c +@@ -2457,6 +2457,11 @@ rfbProcessClientNormalMessage(rfbClientP + 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) diff -Nru libvncserver-0.9.9+dfsg/debian/patches/series libvncserver-0.9.9+dfsg/debian/patches/series --- libvncserver-0.9.9+dfsg/debian/patches/series 2014-08-11 00:21:58.000000000 +0200 +++ libvncserver-0.9.9+dfsg/debian/patches/series 2014-11-23 16:03:36.000000000 +0100 @@ -5,3 +5,8 @@ listenSock.patch ppc64el.patch pkgconfig.patch +CVE-2014-6051.patch +CVE-2014-6052.patch +CVE-2015-6053.patch +CVE-2014-6054.patch +CVE-2014-6055.patch -- To UNSUBSCRIBE, email to debian-bugs-rc-requ...@lists.debian.org with a subject of "unsubscribe". Trouble? Contact listmas...@lists.debian.org