diff options
author | Christian Beier <dontmind@freeshell.org> | 2016-11-24 18:09:12 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2016-11-24 18:09:12 +0100 |
commit | bfee34615584982fe77b5eadd6cb0734de39b17b (patch) | |
tree | feae225764c402517ff2a51452c147de210ab91b /libvncclient | |
parent | 01698f5c5be8fe7af08f8704f115344f6a0cac45 (diff) | |
parent | 5fff4353f66427b467eb29e5fdc1da4f2be028bb (diff) | |
download | libtdevnc-bfee34615584982fe77b5eadd6cb0734de39b17b.tar.gz libtdevnc-bfee34615584982fe77b5eadd6cb0734de39b17b.zip |
Merge pull request #137 from atalax/master
Fix two heap buffer overflows
Diffstat (limited to 'libvncclient')
-rw-r--r-- | libvncclient/rfbproto.c | 24 | ||||
-rw-r--r-- | libvncclient/ultra.c | 8 |
2 files changed, 28 insertions, 4 deletions
diff --git a/libvncclient/rfbproto.c b/libvncclient/rfbproto.c index 94b9bdb..9edfbad 100644 --- a/libvncclient/rfbproto.c +++ b/libvncclient/rfbproto.c @@ -147,6 +147,10 @@ void* rfbClientGetClientData(rfbClient* client, void* tag) /* messages */ +static boolean CheckRect(rfbClient* client, int x, int y, int w, int h) { + return x + w <= client->width && y + h <= client->height; +} + static void FillRectangle(rfbClient* client, int x, int y, int w, int h, uint32_t colour) { int i,j; @@ -154,6 +158,11 @@ static void FillRectangle(rfbClient* client, int x, int y, int w, int h, uint32_ return; } + if (!CheckRect(client, x, y, w, h)) { + rfbClientLog("Rect out of bounds: %dx%d at (%d, %d)\n", x, y, w, h); + return; + } + #define FILL_RECT(BPP) \ for(j=y*client->width;j<(y+h)*client->width;j+=client->width) \ for(i=x;i<x+w;i++) \ @@ -175,6 +184,11 @@ static void CopyRectangle(rfbClient* client, uint8_t* buffer, int x, int y, int return; } + if (!CheckRect(client, x, y, w, h)) { + rfbClientLog("Rect out of bounds: %dx%d at (%d, %d)\n", x, y, w, h); + return; + } + #define COPY_RECT(BPP) \ { \ int rs = w * BPP / 8, rs2 = client->width * BPP / 8; \ @@ -201,6 +215,16 @@ static void CopyRectangleFromRectangle(rfbClient* client, int src_x, int src_y, return; } + if (!CheckRect(client, src_x, src_y, w, h)) { + rfbClientLog("Source rect out of bounds: %dx%d at (%d, %d)\n", src_x, src_y, w, h); + return; + } + + if (!CheckRect(client, dest_x, dest_y, w, h)) { + rfbClientLog("Dest rect out of bounds: %dx%d at (%d, %d)\n", dest_x, dest_y, w, h); + return; + } + #define COPY_RECT_FROM_RECT(BPP) \ { \ uint##BPP##_t* _buffer=((uint##BPP##_t*)client->frameBuffer)+(src_y-dest_y)*client->width+src_x-dest_x; \ diff --git a/libvncclient/ultra.c b/libvncclient/ultra.c index dac89b5..32a1b2b 100644 --- a/libvncclient/ultra.c +++ b/libvncclient/ultra.c @@ -86,14 +86,14 @@ HandleUltraBPP (rfbClient* client, int rx, int ry, int rw, int rh) /* uncompress the data */ uncompressedBytes = client->raw_buffer_size; - inflateResult = lzo1x_decompress( + inflateResult = lzo1x_decompress_safe( (lzo_byte *)client->ultra_buffer, toRead, (lzo_byte *)client->raw_buffer, (lzo_uintp) &uncompressedBytes, NULL); - + /* Note that uncompressedBytes will be 0 on output overrun */ if ((rw * rh * (BPP / 8)) != uncompressedBytes) - rfbClientLog("Ultra decompressed too little (%d < %d)", (rw * rh * (BPP / 8)), uncompressedBytes); + rfbClientLog("Ultra decompressed unexpected amount of data (%d != %d)\n", (rw * rh * (BPP / 8)), uncompressedBytes); /* Put the uncompressed contents of the update on the screen. */ if ( inflateResult == LZO_E_OK ) @@ -168,7 +168,7 @@ HandleUltraZipBPP (rfbClient* client, int rx, int ry, int rw, int rh) /* uncompress the data */ uncompressedBytes = client->raw_buffer_size; - inflateResult = lzo1x_decompress( + inflateResult = lzo1x_decompress_safe( (lzo_byte *)client->ultra_buffer, toRead, (lzo_byte *)client->raw_buffer, &uncompressedBytes, NULL); if ( inflateResult != LZO_E_OK ) |