Subject: [alpine-aports] [PATCH v3.3] main/libvncserver: security fixes #6640

From: Sergei Lukin <[email-masked]>
Date: Wed, 18 Jan 2017 14:53:43 +0000

CVE-2016-9941: Heap-based buffer overflow in rfbproto.c
CVE-2016-9942: Heap-based buffer overflow in ultra.c
---
 main/libvncserver/APKBUILD            | 22 +++++++++---
 main/libvncserver/CVE-2016-9941.patch | 66 +++++++++++++++++++++++++++++++++++
 main/libvncserver/CVE-2016-9942.patch | 41 ++++++++++++++++++++++
 3 files changed, 125 insertions(+), 4 deletions(-)
 create mode 100644 main/libvncserver/CVE-2016-9941.patch
 create mode 100644 main/libvncserver/CVE-2016-9942.patch

diff --git a/main/libvncserver/APKBUILD b/main/libvncserver/APKBUILD
index c93b528..86e6cdd 100644
--- a/main/libvncserver/APKBUILD
+++ b/main/libvncserver/APKBUILD
@@ -1,8 +1,9 @@
+# Contributor: Sergei Lukin <[email-masked]>
 # Contributor: Natanael Copa <[email-masked]>
 # Maintainer:
 pkgname=libvncserver
 pkgver=0.9.10
-pkgrel=1
+pkgrel=2
 pkgdesc="Library to make writing a vnc server easy"
 url="http://libvncserver.sourceforge.net/"
 arch="all"
@@ -16,8 +17,15 @@ install=""
 subpackages="$pkgname-dev"
 source="http://downloads.sf.net/libvncserver/LibVNCServer-$pkgver.tar.gz"
 source="https://github.com/LibVNC/libvncserver/archive/LibVNCServer-$pkgver.tar.gz
+	CVE-2016-9941.patch
+	CVE-2016-9942.patch
 	"
 
+# secfixes:
+#   0.9.10-r2:
+#     - CVE-2016-9941
+#     - CVE-2016-9942
+
 _builddir="$srcdir"/libvncserver-LibVNCServer-$pkgver
 prepare() {
 	local i
@@ -46,6 +54,12 @@ package() {
 	make install DESTDIR="$pkgdir" || return 1
 }
 
-md5sums="e1b888fae717b06896f8aec100163d27  LibVNCServer-0.9.10.tar.gz"
-sha256sums="ed10819a5bfbf269969f97f075939cc38273cc1b6d28bccfb0999fba489411f7  LibVNCServer-0.9.10.tar.gz"
-sha512sums="eb637dfb72dc50fb713a715c9d0cc8824a6871527c2edb497e70c92e2e708021fbd5d8134f2dee6a9e90d1c8fd3fee53c5f5ece790c2804e938011a980ffceae  LibVNCServer-0.9.10.tar.gz"
+md5sums="e1b888fae717b06896f8aec100163d27  LibVNCServer-0.9.10.tar.gz
+d97e55435a06ff3870fae3669975b950  CVE-2016-9941.patch
+1f1f20acce8988a6be3620d1765749a2  CVE-2016-9942.patch"
+sha256sums="ed10819a5bfbf269969f97f075939cc38273cc1b6d28bccfb0999fba489411f7  LibVNCServer-0.9.10.tar.gz
+9073e1d3f734bd6a4fc003de7163f861d38234a78ac585665d96e386b8dc22ae  CVE-2016-9941.patch
+2c4d908d71713012d542345ededbe49f60cc0ad76ca96d111e18fd5374528b34  CVE-2016-9942.patch"
+sha512sums="eb637dfb72dc50fb713a715c9d0cc8824a6871527c2edb497e70c92e2e708021fbd5d8134f2dee6a9e90d1c8fd3fee53c5f5ece790c2804e938011a980ffceae  LibVNCServer-0.9.10.tar.gz
+c0796f0c45fe6cd23ceeba45a2b6efb90a5499b096ea7f5850722fb68b5bbde01fdf001bf582614328862bc3b40f9c9dc9d6c75aa1aa6c002d5eec505d0ffeee  CVE-2016-9941.patch
+36f22fdf49ac494d8d4c66c1d4ce03d2b62ed54a7726b2951129a18263ca964dbaa0b0c38ab2cee04dbb276a234bc0ee9ca3b396f0bb244288717ddd86347f15  CVE-2016-9942.patch"
diff --git a/main/libvncserver/CVE-2016-9941.patch b/main/libvncserver/CVE-2016-9941.patch
new file mode 100644
index 0000000..b36fc63
--- /dev/null
+++ b/main/libvncserver/CVE-2016-9941.patch
@@ -0,0 +1,66 @@
+commit 5418e8007c248bf9668d22a8c1fa9528149b69f2
+Author: Josef Gajdusek <[email-masked]>
+Date:   Mon Nov 14 11:39:01 2016 +0100
+
+    Fix heap overflows in the various rectangle fill functions
+    
+    Altough rfbproto.c does check whether the overall FramebufferUpdate rectangle is
+    too large, some of the individual encoding decoders do not, which allows a
+    malicious server to overwrite parts of the heap.
+
+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/main/libvncserver/CVE-2016-9942.patch b/main/libvncserver/CVE-2016-9942.patch
new file mode 100644
index 0000000..d79ac4a
--- /dev/null
+++ b/main/libvncserver/CVE-2016-9942.patch
@@ -0,0 +1,41 @@
+commit 5fff4353f66427b467eb29e5fdc1da4f2be028bb
+Author: Josef Gajdusek <[email-masked]>
+Date:   Mon Nov 14 12:38:05 2016 +0100
+
+    Fix heap overflow in the ultra.c decoder
+    
+    The Ultra type tile decoder does not use the _safe variant of the LZO
+    decompress function, which allows a maliciuous server to overwrite parts of the
+    heap by sending a larger-than-specified LZO data stream.
+
+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 ) 
-- 
2.6.6

---
Unsubscribe:  [email-masked]
Help:         [email-masked]
---