Package: release.debian.org
Severity: normal
User: release.debian@packages.debian.org
Usertags: unblock
Dear Release Team,
Please unblock package openconnect, version 3.20-3 already uploaded to
unstable. This upload fixes RC bug #700794 (CVE-2012-6128), a
stack-based buffer overflow vulnerability.
The fix was made upstream and this change is a backport of that patch to
version 3.20. The debdiff is included below. Thanks in advance.
diffstat for openconnect-3.20 openconnect-3.20
changelog |7 +
patches/02_CVE-2012-6128.patch | 281 +
patches/series |1
3 files changed, 289 insertions(+)
diff -Nru openconnect-3.20/debian/changelog openconnect-3.20/debian/changelog
--- openconnect-3.20/debian/changelog 2012-06-06 08:54:48.0 -0400
+++ openconnect-3.20/debian/changelog 2013-02-17 12:25:52.0 -0500
@@ -1,3 +1,10 @@
+openconnect (3.20-3) unstable; urgency=low
+
+ * debian/patches/02_CVE-2012-6128.patch: Backport patch from upstream to fix
+buffer overflow (CVE-2012-6128). (Closes: #700794)
+
+ -- Mike Miller mtmil...@ieee.org Sun, 17 Feb 2013 11:56:35 -0500
+
openconnect (3.20-2) unstable; urgency=low
* Depend on vpnc-scripts for routing and DNS configuration. (Closes:
diff -Nru openconnect-3.20/debian/patches/02_CVE-2012-6128.patch
openconnect-3.20/debian/patches/02_CVE-2012-6128.patch
--- openconnect-3.20/debian/patches/02_CVE-2012-6128.patch 1969-12-31
19:00:00.0 -0500
+++ openconnect-3.20/debian/patches/02_CVE-2012-6128.patch 2013-02-17
12:25:52.0 -0500
@@ -0,0 +1,281 @@
+Origin: upstream,
http://git.infradead.org/users/dwmw2/openconnect.git/commitdiff/26f752c3dbf69227679fc6bebb4ae071aecec491
+From: Kevin Cernekee cerne...@gmail.com
+Subject: http: Fix overflow on HTTP request buffers
+
+A malicious VPN gateway can send a very long hostname/path (for redirects)
+or cookie list (in general), which OpenConnect will attempt to sprintf()
+into a fixed length buffer. Each HTTP server response line can add
+roughly MAX_BUF_LEN (131072) bytes to the next OpenConnect HTTP request,
+but the request buffer (buf) is capped at MAX_BUF_LEN bytes and is
+allocated on the stack.
+
+The result of passing a long Location: header looks like:
+
+Attempting to connect to server 127.0.0.1:443
+SSL negotiation with localhost
+Server certificate verify failed: self signed certificate in certificate
chain
+Connected to HTTPS on localhost
+GET https://localhost/
+Got HTTP response: HTTP/1.0 301 Moved
+Ignoring unknown HTTP response line 'aa'
+SSL negotiation with localhost
+Server certificate verify failed: self signed certificate in certificate
chain
+Connected to HTTPS on localhost
+*** buffer overflow detected ***: /scr/openconnect2/.libs/lt-openconnect
terminated
+=== Backtrace: =
+/lib/x86_64-linux-gnu/libc.so.6(__fortify_fail+0x5c)[0x7fd62729b82c]
+/lib/x86_64-linux-gnu/libc.so.6(+0x109700)[0x7fd62729a700]
+/lib/x86_64-linux-gnu/libc.so.6(+0x108b69)[0x7fd627299b69]
+/lib/x86_64-linux-gnu/libc.so.6(_IO_default_xsputn+0xdd)[0x7fd62720d13d]
+/lib/x86_64-linux-gnu/libc.so.6(_IO_vfprintf+0x1ae7)[0x7fd6271db4a7]
+/lib/x86_64-linux-gnu/libc.so.6(__vsprintf_chk+0x94)[0x7fd627299c04]
+/lib/x86_64-linux-gnu/libc.so.6(__sprintf_chk+0x7d)[0x7fd627299b4d]
+
/scr/openconnect2/.libs/libopenconnect.so.2(openconnect_obtain_cookie+0xc0)[0x7fd62832d210]
+/scr/openconnect2/.libs/lt-openconnect[0x40413f]
+/lib/x86_64-linux-gnu/libc.so.6(__libc_start_main+0xed)[0x7fd6271b276d]
+/scr/openconnect2/.libs/lt-openconnect[0x404579]
+
+The proposed fix is to use dynamically allocated buffers with overflow
+checking.
+
+--- a/http.c
b/http.c
+@@ -32,6 +32,7 @@
+ #include pwd.h
+ #include sys/stat.h
+ #include sys/types.h
++#include stdarg.h
+
+ #include openssl/ssl.h
+ #include openssl/err.h
+@@ -45,6 +46,85 @@ static int proxy_read(struct openconnect
+ unsigned char *buf, size_t len);
+
+ #define MAX_BUF_LEN 131072
++#define BUF_CHUNK_SIZE 4096
++
++struct oc_text_buf {
++ char *data;
++ int pos;
++ int buf_len;
++ int error;
++};
++
++static struct oc_text_buf *buf_alloc(void)
++{
++ return calloc(1, sizeof(struct oc_text_buf));
++}
++
++static void buf_append(struct oc_text_buf *buf, const char *fmt, ...)
++{
++ va_list ap;
++
++ if (!buf || buf-error)
++ return;
++
++ if (!buf-data) {
++ buf-data = malloc(BUF_CHUNK_SIZE);
++ if (!buf-data) {
++ buf-error = -ENOMEM;
++ return;
++ }
++ buf-buf_len = BUF_CHUNK_SIZE;
++ }
++
++ while (1) {
++ int max_len = buf-buf_len - buf-pos, ret;
++
++ va_start(ap, fmt);
++ ret = vsnprintf(buf-data + buf-pos, max_len,