--- Begin Message ---
Package: release.debian.org
Severity: normal
User: release.debian....@packages.debian.org
Usertags: unblock
Dear Release Team,
Please unblock latest libevent in unstable.
Changes:
libevent (2.0.21-stable-3) unstable; urgency=medium
.
* Fix three vulnerabilites (Closes: #854092):
- DNS remote stack overread vulnerability (CVE-2016-10195)
- (Stack) buffer overflow in evutil_parse_sockaddr_port()
(CVE-2016-10196)
- Out-of-bounds read in search_make_new() (CVE-2016-10197)
* Add myself as an uploader
* ACK NMU
Cheers,
Balint
unblock libevent/2.0.21-stable-3
diff -Nru libevent-2.0.21-stable/debian/changelog libevent-2.0.21-stable/debian/changelog
--- libevent-2.0.21-stable/debian/changelog 2016-11-03 08:43:46.000000000 +0100
+++ libevent-2.0.21-stable/debian/changelog 2017-02-12 21:45:49.000000000 +0100
@@ -1,3 +1,15 @@
+libevent (2.0.21-stable-3) unstable; urgency=medium
+
+ * Fix three vulnerabilites (Closes: #854092):
+ - DNS remote stack overread vulnerability (CVE-2016-10195)
+ - (Stack) buffer overflow in evutil_parse_sockaddr_port()
+ (CVE-2016-10196)
+ - Out-of-bounds read in search_make_new() (CVE-2016-10197)
+ * Add myself as an uploader
+ * ACK NMU
+
+ -- Balint Reczey <bal...@balintreczey.hu> Sun, 12 Feb 2017 21:43:18 +0100
+
libevent (2.0.21-stable-2.1) unstable; urgency=medium
[ Helmut Grohne ]
diff -Nru libevent-2.0.21-stable/debian/control libevent-2.0.21-stable/debian/control
--- libevent-2.0.21-stable/debian/control 2014-08-25 18:02:38.000000000 +0200
+++ libevent-2.0.21-stable/debian/control 2017-02-12 21:45:49.000000000 +0100
@@ -2,7 +2,8 @@
Section: libs
Priority: optional
Maintainer: Anibal Monsalve Salazar <ani...@debian.org>
-Uploaders: Leo Costela <cost...@debian.org>
+Uploaders: Leo Costela <cost...@debian.org>,
+ Balint Reczey <bal...@balintreczey.hu>
Build-Depends: dpkg-dev (>= 1.16.1~), debhelper (>= 9), libssl-dev, dh-autoreconf
Standards-Version: 3.9.3
Homepage: http://libevent.org/
diff -Nru libevent-2.0.21-stable/debian/patches/0001-evdns-fix-searching-empty-hostnames.patch libevent-2.0.21-stable/debian/patches/0001-evdns-fix-searching-empty-hostnames.patch
--- libevent-2.0.21-stable/debian/patches/0001-evdns-fix-searching-empty-hostnames.patch 1970-01-01 01:00:00.000000000 +0100
+++ libevent-2.0.21-stable/debian/patches/0001-evdns-fix-searching-empty-hostnames.patch 2017-02-12 21:45:49.000000000 +0100
@@ -0,0 +1,65 @@
+From ec65c42052d95d2c23d1d837136d1cf1d9ecef9e Mon Sep 17 00:00:00 2001
+From: Azat Khuzhin <a3at.m...@gmail.com>
+Date: Fri, 25 Mar 2016 00:33:47 +0300
+Subject: [PATCH] evdns: fix searching empty hostnames
+
+From #332:
+ Here follows a bug report by **Guido Vranken** via the _Tor bug bounty program_. Please credit Guido accordingly.
+
+ ## Bug report
+
+ The DNS code of Libevent contains this rather obvious OOB read:
+
+ ```c
+ static char *
+ search_make_new(const struct search_state *const state, int n, const char *const base_name) {
+ const size_t base_len = strlen(base_name);
+ const char need_to_append_dot = base_name[base_len - 1] == '.' ? 0 : 1;
+ ```
+
+ If the length of ```base_name``` is 0, then line 3125 reads 1 byte before the buffer. This will trigger a crash on ASAN-protected builds.
+
+ To reproduce:
+
+ Build libevent with ASAN:
+ ```
+ $ CFLAGS='-fomit-frame-pointer -fsanitize=address' ./configure && make -j4
+ ```
+ Put the attached ```resolv.conf``` and ```poc.c``` in the source directory and then do:
+
+ ```
+ $ gcc -fsanitize=address -fomit-frame-pointer poc.c .libs/libevent.a
+ $ ./a.out
+ =================================================================
+ ==22201== ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60060000efdf at pc 0x4429da bp 0x7ffe1ed47300 sp 0x7ffe1ed472f8
+ READ of size 1 at 0x60060000efdf thread T0
+ ```
+
+P.S. we can add a check earlier, but since this is very uncommon, I didn't add it.
+
+Fixes: #332
+---
+ evdns.c | 5 ++++-
+ 1 file changed, 4 insertions(+), 1 deletion(-)
+
+diff --git a/evdns.c b/evdns.c
+index 905ff6b..e9dbc35 100644
+--- a/evdns.c
++++ b/evdns.c
+@@ -3175,9 +3175,12 @@ search_set_from_hostname(struct evdns_base *base) {
+ static char *
+ search_make_new(const struct search_state *const state, int n, const char *const base_name) {
+ const size_t base_len = strlen(base_name);
+- const char need_to_append_dot = base_name[base_len - 1] == '.' ? 0 : 1;
++ char need_to_append_dot;
+ struct search_domain *dom;
+
++ if (!base_len) return NULL;
++ need_to_append_dot = base_name[base_len - 1] == '.' ? 0 : 1;
++
+ for (dom = state->head; dom; dom = dom->next) {
+ if (!n--) {
+ /* this is the postfix we want */
+--
+2.1.4
+
diff -Nru libevent-2.0.21-stable/debian/patches/0002-test-dns-regression-for-empty-hostname.patch libevent-2.0.21-stable/debian/patches/0002-test-dns-regression-for-empty-hostname.patch
--- libevent-2.0.21-stable/debian/patches/0002-test-dns-regression-for-empty-hostname.patch 1970-01-01 01:00:00.000000000 +0100
+++ libevent-2.0.21-stable/debian/patches/0002-test-dns-regression-for-empty-hostname.patch 2017-02-12 21:45:49.000000000 +0100
@@ -0,0 +1,55 @@
+From 683cf19b56dad3bc7b5915e2765b3e3c325c2dfe Mon Sep 17 00:00:00 2001
+From: Azat Khuzhin <a3at.m...@gmail.com>
+Date: Fri, 25 Mar 2016 00:21:06 +0300
+Subject: [PATCH] test/dns: regression for empty hostname
+
+Refs: #332
+
+Conflicts:
+ test/regress_dns.c
+---
+ test/regress_dns.c | 21 +++++++++++++++++++++
+ 1 file changed, 21 insertions(+)
+
+diff --git a/test/regress_dns.c b/test/regress_dns.c
+index 4d90d67..1817fb3 100644
+--- a/test/regress_dns.c
++++ b/test/regress_dns.c
+@@ -562,6 +562,26 @@ end:
+
+ regress_clean_dnsserver();
+ }
++static void
++dns_search_empty_test(void *arg)
++{
++ struct basic_test_data *data = arg;
++ struct event_base *base = data->base;
++ struct evdns_base *dns = NULL;
++
++ dns = evdns_base_new(base, 0);
++
++ evdns_base_search_add(dns, "whatever.example.com");
++
++ n_replies_left = 1;
++ exit_base = base;
++
++ tt_ptr_op(evdns_base_resolve_ipv4(dns, "", 0, generic_dns_callback, NULL), ==, NULL);
++
++end:
++ if (dns)
++ evdns_base_free(dns, 0);
++}
+
+ static int request_count = 0;
+ static struct evdns_request *current_req = NULL;
+@@ -1831,6 +1851,7 @@ struct testcase_t dns_testcases[] = {
+ DNS_LEGACY(gethostbyname6, TT_FORK|TT_NEED_BASE|TT_NEED_DNS),
+ DNS_LEGACY(gethostbyaddr, TT_FORK|TT_NEED_BASE|TT_NEED_DNS),
+ { "resolve_reverse", dns_resolve_reverse, TT_FORK, NULL, NULL },
++ { "search_empty", dns_search_empty_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
+ { "search", dns_search_test, TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
+ { "search_cancel", dns_search_cancel_test,
+ TT_FORK|TT_NEED_BASE, &basic_setup, NULL },
+--
+2.1.4
+
diff -Nru libevent-2.0.21-stable/debian/patches/0003-evdns-name_parse-fix-remote-stack-overread.patch libevent-2.0.21-stable/debian/patches/0003-evdns-name_parse-fix-remote-stack-overread.patch
--- libevent-2.0.21-stable/debian/patches/0003-evdns-name_parse-fix-remote-stack-overread.patch 1970-01-01 01:00:00.000000000 +0100
+++ libevent-2.0.21-stable/debian/patches/0003-evdns-name_parse-fix-remote-stack-overread.patch 2017-02-12 21:45:49.000000000 +0100
@@ -0,0 +1,115 @@
+From 96f64a022014a208105ead6c8a7066018449d86d Mon Sep 17 00:00:00 2001
+From: Azat Khuzhin <a3at.m...@gmail.com>
+Date: Mon, 1 Feb 2016 17:32:09 +0300
+Subject: [PATCH] evdns: name_parse(): fix remote stack overread
+
+@asn-the-goblin-slayer:
+ "the name_parse() function in libevent's DNS code is vulnerable to a buffer overread.
+
+ 971 if (cp != name_out) {
+ 972 if (cp + 1 >= end) return -1;
+ 973 *cp++ = '.';
+ 974 }
+ 975 if (cp + label_len >= end) return -1;
+ 976 memcpy(cp, packet + j, label_len);
+ 977 cp += label_len;
+ 978 j += label_len;
+ No check is made against length before the memcpy occurs.
+
+ This was found through the Tor bug bounty program and the discovery should be credited to 'Guido Vranken'."
+
+Reproducer for gdb (https://gist.github.com/azat/e4fcf540e9b89ab86d02):
+ set $PROT_NONE=0x0
+ set $PROT_READ=0x1
+ set $PROT_WRITE=0x2
+ set $MAP_ANONYMOUS=0x20
+ set $MAP_SHARED=0x01
+ set $MAP_FIXED=0x10
+ set $MAP_32BIT=0x40
+
+ start
+
+ set $length=202
+ # overread
+ set $length=2
+ # allocate with mmap to have a seg fault on page boundary
+ set $l=(1<<20)*2
+ p mmap(0, $l, $PROT_READ|$PROT_WRITE, $MAP_ANONYMOUS|$MAP_SHARED|$MAP_32BIT, -1, 0)
+ set $packet=(char *)$1+$l-$length
+ # hack the packet
+ set $packet[0]=63
+ set $packet[1]='/'
+
+ p malloc(sizeof(int))
+ set $idx=(int *)$2
+ set $idx[0]=0
+ set $name_out_len=202
+
+ p malloc($name_out_len)
+ set $name_out=$3
+
+ # have WRITE only mapping to fail on read
+ set $end=$1+$l
+ p (void *)mmap($end, 1<<12, $PROT_NONE, $MAP_ANONYMOUS|$MAP_SHARED|$MAP_FIXED|$MAP_32BIT, -1, 0)
+ set $m=$4
+
+ p name_parse($packet, $length, $idx, $name_out, $name_out_len)
+ x/2s (char *)$name_out
+
+Before this patch:
+$ gdb -ex 'source gdb' dns-example
+$1 = 1073741824
+$2 = (void *) 0x633010
+$3 = (void *) 0x633030
+$4 = (void *) 0x40200000
+
+Program received signal SIGSEGV, Segmentation fault.
+__memcpy_sse2_unaligned () at memcpy-sse2-unaligned.S:33
+
+After this patch:
+$ gdb -ex 'source gdb' dns-example
+$1 = 1073741824
+$2 = (void *) 0x633010
+$3 = (void *) 0x633030
+$4 = (void *) 0x40200000
+$5 = -1
+0x633030: "/"
+0x633032: ""
+(gdb) p $m
+$6 = (void *) 0x40200000
+(gdb) p $1
+$7 = 1073741824
+(gdb) p/x $1
+$8 = 0x40000000
+(gdb) quit
+
+P.S. plus drop one condition duplicate.
+
+Fixes: #317
+---
+ evdns.c | 2 +-
+ 1 file changed, 1 insertion(+), 1 deletion(-)
+
+diff --git a/evdns.c b/evdns.c
+index 0955a28..c411233 100644
+--- a/evdns.c
++++ b/evdns.c
+@@ -976,7 +976,6 @@ name_parse(u8 *packet, int length, int *idx, char *name_out, int name_out_len) {
+
+ for (;;) {
+ u8 label_len;
+- if (j >= length) return -1;
+ GET8(label_len);
+ if (!label_len) break;
+ if (label_len & 0xc0) {
+@@ -997,6 +996,7 @@ name_parse(u8 *packet, int length, int *idx, char *name_out, int name_out_len) {
+ *cp++ = '.';
+ }
+ if (cp + label_len >= end) return -1;
++ if (j + label_len > length) return -1;
+ memcpy(cp, packet + j, label_len);
+ cp += label_len;
+ j += label_len;
+--
+2.1.4
+
diff -Nru libevent-2.0.21-stable/debian/patches/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch libevent-2.0.21-stable/debian/patches/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch
--- libevent-2.0.21-stable/debian/patches/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch 1970-01-01 01:00:00.000000000 +0100
+++ libevent-2.0.21-stable/debian/patches/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch 2017-02-12 21:45:49.000000000 +0100
@@ -0,0 +1,88 @@
+From 329acc18a0768c21ba22522f01a5c7f46cacc4d5 Mon Sep 17 00:00:00 2001
+From: Azat Khuzhin <a3at.m...@gmail.com>
+Date: Sun, 31 Jan 2016 00:57:16 +0300
+Subject: [PATCH] evutil_parse_sockaddr_port(): fix buffer overflow
+
+@asn-the-goblin-slayer:
+ "Length between '[' and ']' is cast to signed 32 bit integer on line 1815. Is
+ the length is more than 2<<31 (INT_MAX), len will hold a negative value.
+ Consequently, it will pass the check at line 1816. Segfault happens at line
+ 1819.
+
+ Generate a resolv.conf with generate-resolv.conf, then compile and run
+ poc.c. See entry-functions.txt for functions in tor that might be
+ vulnerable.
+
+ Please credit 'Guido Vranken' for this discovery through the Tor bug bounty
+ program."
+
+Reproducer for gdb (https://gist.github.com/azat/be2b0d5e9417ba0dfe2c):
+ start
+ p (1ULL<<31)+1ULL
+ # $1 = 2147483649
+ p malloc(sizeof(struct sockaddr))
+ # $2 = (void *) 0x646010
+ p malloc(sizeof(int))
+ # $3 = (void *) 0x646030
+ p malloc($1)
+ # $4 = (void *) 0x7fff76a2a010
+ p memset($4, 1, $1)
+ # $5 = 1990369296
+ p (char *)$4
+ # $6 = 0x7fff76a2a010 '\001' <repeats 200 times>...
+ set $6[0]='['
+ set $6[$1]=']'
+ p evutil_parse_sockaddr_port($4, $2, $3)
+ # $7 = -1
+
+Before:
+ $ gdb bin/http-connect < gdb
+ (gdb) $1 = 2147483649
+ (gdb) (gdb) $2 = (void *) 0x646010
+ (gdb) (gdb) $3 = (void *) 0x646030
+ (gdb) (gdb) $4 = (void *) 0x7fff76a2a010
+ (gdb) (gdb) $5 = 1990369296
+ (gdb) (gdb) $6 = 0x7fff76a2a010 '\001' <repeats 200 times>...
+ (gdb) (gdb) (gdb) (gdb)
+ Program received signal SIGSEGV, Segmentation fault.
+ __memcpy_sse2_unaligned () at memcpy-sse2-unaligned.S:36
+
+After:
+ $ gdb bin/http-connect < gdb
+ (gdb) $1 = 2147483649
+ (gdb) (gdb) $2 = (void *) 0x646010
+ (gdb) (gdb) $3 = (void *) 0x646030
+ (gdb) (gdb) $4 = (void *) 0x7fff76a2a010
+ (gdb) (gdb) $5 = 1990369296
+ (gdb) (gdb) $6 = 0x7fff76a2a010 '\001' <repeats 200 times>...
+ (gdb) (gdb) (gdb) (gdb) $7 = -1
+ (gdb) (gdb) quit
+
+Fixes: #318
+---
+ evutil.c | 6 +++---
+ 1 file changed, 3 insertions(+), 3 deletions(-)
+
+diff --git a/evutil.c b/evutil.c
+index 79d825d..495bfcc 100644
+--- a/evutil.c
++++ b/evutil.c
+@@ -2058,12 +2058,12 @@ evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int *
+
+ cp = strchr(ip_as_string, ':');
+ if (*ip_as_string == '[') {
+- int len;
++ size_t len;
+ if (!(cp = strchr(ip_as_string, ']'))) {
+ return -1;
+ }
+- len = (int) ( cp-(ip_as_string + 1) );
+- if (len > (int)sizeof(buf)-1) {
++ len = ( cp-(ip_as_string + 1) );
++ if (len > sizeof(buf)-1) {
+ return -1;
+ }
+ memcpy(buf, ip_as_string+1, len);
+--
+2.1.4
+
diff -Nru libevent-2.0.21-stable/debian/patches/series libevent-2.0.21-stable/debian/patches/series
--- libevent-2.0.21-stable/debian/patches/series 2016-11-03 08:42:38.000000000 +0100
+++ libevent-2.0.21-stable/debian/patches/series 2017-02-12 21:45:49.000000000 +0100
@@ -6,3 +6,10 @@
# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=774645
20d6d445.patch
openssl_1.1.patch
+# CVE-2016-10197
+0001-evdns-fix-searching-empty-hostnames.patch
+0002-test-dns-regression-for-empty-hostname.patch
+# CVE-2016-10196
+0003-evdns-name_parse-fix-remote-stack-overread.patch
+# CVE-2016-10195
+0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch
--- End Message ---