1
0
mirror of https://github.com/KDE/krfb synced 2026-07-02 00:01:18 -07:00

Compare commits

...

4 Commits

Author SHA1 Message Date
Martin T. H. Sandsmark
d931eafccf 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
2014-09-23 23:06:21 +02:00
Martin T. H. Sandsmark
126a746dd7 libnvcserver: Do not accept a scaling factor of zero.
This would cause a division by zero and crash the server.

Upstream commit: 05a9bd41a8ec0a9d580a8f420f41718bdd235446
2014-09-23 23:06:18 +02:00
Martin T. H. Sandsmark
2e21157945 libvncserver: Fix multiple stack-based buffer overflows in file transfer feature
Upstream commit: 06ccdf016154fde8eccb5355613ba04c59127b2e

CVE-2014-6055
2014-09-23 23:05:56 +02:00
Martin T. H. Sandsmark
857c2b411e libvncserver: Fix stack-based buffer overflow in rfbFileTransferOffer message, FileTime processing
Upstream commit: f528072216dec01cee7ca35d94e171a3b909e677

CVE-2014-6055
2014-09-23 23:05:49 +02:00

View File

@@ -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);