summaryrefslogtreecommitdiffstats
path: root/libvncclient
diff options
context:
space:
mode:
authorChristian Beier <dontmind@freeshell.org>2016-11-24 18:09:12 +0100
committerGitHub <noreply@github.com>2016-11-24 18:09:12 +0100
commitbfee34615584982fe77b5eadd6cb0734de39b17b (patch)
treefeae225764c402517ff2a51452c147de210ab91b /libvncclient
parent01698f5c5be8fe7af08f8704f115344f6a0cac45 (diff)
parent5fff4353f66427b467eb29e5fdc1da4f2be028bb (diff)
downloadlibtdevnc-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.c24
-rw-r--r--libvncclient/ultra.c8
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 )