[arch-commits] Commit in libevent/repos (14 files)

Jan de Groot jgc at archlinux.org
Fri Mar 3 09:23:09 UTC 2017


    Date: Friday, March 3, 2017 @ 09:23:09
  Author: jgc
Revision: 289913

archrelease: copy trunk to testing-i686, testing-x86_64

Added:
  libevent/repos/testing-i686/
  libevent/repos/testing-i686/0001-evdns-fix-searching-empty-hostnames.patch
    (from rev 289912, libevent/trunk/0001-evdns-fix-searching-empty-hostnames.patch)
  libevent/repos/testing-i686/0002-test-dns-regression-for-empty-hostname.patch
    (from rev 289912, libevent/trunk/0002-test-dns-regression-for-empty-hostname.patch)
  libevent/repos/testing-i686/0003-evdns-name_parse-fix-remote-stack-overread.patch
    (from rev 289912, libevent/trunk/0003-evdns-name_parse-fix-remote-stack-overread.patch)
  libevent/repos/testing-i686/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch
    (from rev 289912, libevent/trunk/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch)
  libevent/repos/testing-i686/PKGBUILD
    (from rev 289912, libevent/trunk/PKGBUILD)
  libevent/repos/testing-i686/openssl_1.1.patch
    (from rev 289912, libevent/trunk/openssl_1.1.patch)
  libevent/repos/testing-x86_64/
  libevent/repos/testing-x86_64/0001-evdns-fix-searching-empty-hostnames.patch
    (from rev 289912, libevent/trunk/0001-evdns-fix-searching-empty-hostnames.patch)
  libevent/repos/testing-x86_64/0002-test-dns-regression-for-empty-hostname.patch
    (from rev 289912, libevent/trunk/0002-test-dns-regression-for-empty-hostname.patch)
  libevent/repos/testing-x86_64/0003-evdns-name_parse-fix-remote-stack-overread.patch
    (from rev 289912, libevent/trunk/0003-evdns-name_parse-fix-remote-stack-overread.patch)
  libevent/repos/testing-x86_64/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch
    (from rev 289912, libevent/trunk/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch)
  libevent/repos/testing-x86_64/PKGBUILD
    (from rev 289912, libevent/trunk/PKGBUILD)
  libevent/repos/testing-x86_64/openssl_1.1.patch
    (from rev 289912, libevent/trunk/openssl_1.1.patch)

--------------------------------------------------------------------------+
 testing-i686/0001-evdns-fix-searching-empty-hostnames.patch              |   65 +++
 testing-i686/0002-test-dns-regression-for-empty-hostname.patch           |   55 ++
 testing-i686/0003-evdns-name_parse-fix-remote-stack-overread.patch       |  115 ++++++
 testing-i686/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch   |   88 ++++
 testing-i686/PKGBUILD                                                    |   54 ++
 testing-i686/openssl_1.1.patch                                           |  190 ++++++++++
 testing-x86_64/0001-evdns-fix-searching-empty-hostnames.patch            |   65 +++
 testing-x86_64/0002-test-dns-regression-for-empty-hostname.patch         |   55 ++
 testing-x86_64/0003-evdns-name_parse-fix-remote-stack-overread.patch     |  115 ++++++
 testing-x86_64/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch |   88 ++++
 testing-x86_64/PKGBUILD                                                  |   54 ++
 testing-x86_64/openssl_1.1.patch                                         |  190 ++++++++++
 12 files changed, 1134 insertions(+)

Copied: libevent/repos/testing-i686/0001-evdns-fix-searching-empty-hostnames.patch (from rev 289912, libevent/trunk/0001-evdns-fix-searching-empty-hostnames.patch)
===================================================================
--- testing-i686/0001-evdns-fix-searching-empty-hostnames.patch	                        (rev 0)
+++ testing-i686/0001-evdns-fix-searching-empty-hostnames.patch	2017-03-03 09:23:09 UTC (rev 289913)
@@ -0,0 +1,65 @@
+From ec65c42052d95d2c23d1d837136d1cf1d9ecef9e Mon Sep 17 00:00:00 2001
+From: Azat Khuzhin <a3at.mail at 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
+

Copied: libevent/repos/testing-i686/0002-test-dns-regression-for-empty-hostname.patch (from rev 289912, libevent/trunk/0002-test-dns-regression-for-empty-hostname.patch)
===================================================================
--- testing-i686/0002-test-dns-regression-for-empty-hostname.patch	                        (rev 0)
+++ testing-i686/0002-test-dns-regression-for-empty-hostname.patch	2017-03-03 09:23:09 UTC (rev 289913)
@@ -0,0 +1,55 @@
+From 683cf19b56dad3bc7b5915e2765b3e3c325c2dfe Mon Sep 17 00:00:00 2001
+From: Azat Khuzhin <a3at.mail at 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
+

Copied: libevent/repos/testing-i686/0003-evdns-name_parse-fix-remote-stack-overread.patch (from rev 289912, libevent/trunk/0003-evdns-name_parse-fix-remote-stack-overread.patch)
===================================================================
--- testing-i686/0003-evdns-name_parse-fix-remote-stack-overread.patch	                        (rev 0)
+++ testing-i686/0003-evdns-name_parse-fix-remote-stack-overread.patch	2017-03-03 09:23:09 UTC (rev 289913)
@@ -0,0 +1,115 @@
+From 96f64a022014a208105ead6c8a7066018449d86d Mon Sep 17 00:00:00 2001
+From: Azat Khuzhin <a3at.mail at gmail.com>
+Date: Mon, 1 Feb 2016 17:32:09 +0300
+Subject: [PATCH] evdns: name_parse(): fix remote stack overread
+
+ at 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
+

Copied: libevent/repos/testing-i686/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch (from rev 289912, libevent/trunk/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch)
===================================================================
--- testing-i686/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch	                        (rev 0)
+++ testing-i686/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch	2017-03-03 09:23:09 UTC (rev 289913)
@@ -0,0 +1,88 @@
+From 329acc18a0768c21ba22522f01a5c7f46cacc4d5 Mon Sep 17 00:00:00 2001
+From: Azat Khuzhin <a3at.mail at gmail.com>
+Date: Sun, 31 Jan 2016 00:57:16 +0300
+Subject: [PATCH] evutil_parse_sockaddr_port(): fix buffer overflow
+
+ at 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
+

Copied: libevent/repos/testing-i686/PKGBUILD (from rev 289912, libevent/trunk/PKGBUILD)
===================================================================
--- testing-i686/PKGBUILD	                        (rev 0)
+++ testing-i686/PKGBUILD	2017-03-03 09:23:09 UTC (rev 289913)
@@ -0,0 +1,54 @@
+# $Id$
+# Maintainer: Tom Gundersen <teg at jklm.no>
+# Contributor: Judd <jvinet at zeroflux.org>
+
+pkgname=libevent
+pkgver=2.0.22
+pkgrel=3
+pkgdesc="An event notification library"
+arch=('i686' 'x86_64')
+url="http://libevent.org/"
+license=('BSD')
+depends=('openssl')
+optdepends=('python2: to use event_rpcgen.py')
+source=(https://github.com/libevent/libevent/releases/download/release-$pkgver-stable/$pkgname-$pkgver-stable.tar.gz{,.asc}
+        openssl_1.1.patch
+        0001-evdns-fix-searching-empty-hostnames.patch
+        0002-test-dns-regression-for-empty-hostname.patch
+        0003-evdns-name_parse-fix-remote-stack-overread.patch
+        0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch)
+sha256sums=('71c2c49f0adadacfdbe6332a372c38cf9c8b7895bb73dabeaa53cdcc1d4e1fa3'
+            'SKIP'
+            '1c0e3a47e5739ce6f05cfdaeaf1bb33eb7c6c89003538f680586e50cbd2abb48'
+            '66ca7cd16a2260537e1f7d7d22ace9c50bcc54f5f47af41361f1771de6b37526'
+            'b76aaa4730fe377f49077a428645e6e5335a5fe5600fece1e0dd4503749e25d5'
+            'e2bbd44121f4f5c70ba891e4dc9f150254babae0c647bb47792571a6e88c0614'
+            'c02932ec76925d9c470a7b955add045f59dbef3dcc85b46020bda61151b22533')
+validpgpkeys=('B35BF85BF19489D04E28C33C21194EBB165733EA')
+
+prepare() {
+  cd ${pkgname}-${pkgver}-stable
+  patch -Np1 -i ../0001-evdns-fix-searching-empty-hostnames.patch
+  patch -Np1 -i ../0002-test-dns-regression-for-empty-hostname.patch
+  patch -Np1 -i ../0003-evdns-name_parse-fix-remote-stack-overread.patch
+  patch -Np1 -i ../0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch
+  #patch -Np1 -i ../openssl_1.1.patch
+}
+
+build() {
+  cd ${pkgname}-${pkgver}-stable
+  ./autogen.sh
+  ./configure --prefix=/usr --sysconfdir=/etc --disable-libevent-regress
+  make
+}
+
+check() {
+  cd ${pkgname}-${pkgver}-stable
+  make -j1 check
+}
+
+package() {
+  cd ${pkgname}-${pkgver}-stable
+  make DESTDIR="${pkgdir}" install
+  install -Dm 644 LICENSE "${pkgdir}"/usr/share/licenses/libevent/LICENSE
+}

Copied: libevent/repos/testing-i686/openssl_1.1.patch (from rev 289912, libevent/trunk/openssl_1.1.patch)
===================================================================
--- testing-i686/openssl_1.1.patch	                        (rev 0)
+++ testing-i686/openssl_1.1.patch	2017-03-03 09:23:09 UTC (rev 289913)
@@ -0,0 +1,190 @@
+From 7fb978bf21e21a1de36777b45ea984bb1d5c52dd Mon Sep 17 00:00:00 2001
+From: Kurt Roeckx <kurt at roeckx.be>
+Date: Mon, 19 Sep 2016 22:05:15 +0200
+Subject: [PATCH] Make it build using OpenSSL 1.1.0
+
+---
+ bufferevent_openssl.c                | 62 +++++++++++++++++-------------------
+ openssl-compat.h                     | 33 +++++++++++++++++++
+ 5 files changed, 102 insertions(+), 63 deletions(-)
+ create mode 100644 openssl-compat.h
+
+diff --git a/bufferevent_openssl.c b/bufferevent_openssl.c
+index 017bfce..b8a0fe0 100644
+--- a/bufferevent_openssl.c
++++ b/bufferevent_openssl.c
+@@ -66,6 +66,7 @@
+ #include <openssl/bio.h>
+ #include <openssl/ssl.h>
+ #include <openssl/err.h>
++#include "openssl-compat.h"
+ 
+ /*
+  * Define an OpenSSL bio that targets a bufferevent.
+@@ -109,10 +110,8 @@ print_err(int val)
+ static int
+ bio_bufferevent_new(BIO *b)
+ {
+-	b->init = 0;
+-	b->num = -1;
+-	b->ptr = NULL; /* We'll be putting the bufferevent in this field.*/
+-	b->flags = 0;
++	BIO_set_init(b, 0);
++	BIO_set_data(b, NULL); /* We'll be putting the bufferevent in this field.*/
+ 	return 1;
+ }
+ 
+@@ -122,12 +121,10 @@ bio_bufferevent_free(BIO *b)
+ {
+ 	if (!b)
+ 		return 0;
+-	if (b->shutdown) {
+-		if (b->init && b->ptr)
+-			bufferevent_free(b->ptr);
+-		b->init = 0;
+-		b->flags = 0;
+-		b->ptr = NULL;
++	if (BIO_get_shutdown(b)) {
++		if (BIO_get_init(b) && BIO_get_data(b))
++			bufferevent_free(BIO_get_data(b));
++		BIO_free(b);
+ 	}
+ 	return 1;
+ }
+@@ -143,10 +140,10 @@ bio_bufferevent_read(BIO *b, char *out, int outlen)
+ 
+ 	if (!out)
+ 		return 0;
+-	if (!b->ptr)
++	if (!BIO_get_data(b))
+ 		return -1;
+ 
+-	input = bufferevent_get_input(b->ptr);
++	input = bufferevent_get_input(BIO_get_data(b));
+ 	if (evbuffer_get_length(input) == 0) {
+ 		/* If there's no data to read, say so. */
+ 		BIO_set_retry_read(b);
+@@ -162,13 +159,13 @@ bio_bufferevent_read(BIO *b, char *out, int outlen)
+ static int
+ bio_bufferevent_write(BIO *b, const char *in, int inlen)
+ {
+-	struct bufferevent *bufev = b->ptr;
++	struct bufferevent *bufev = BIO_get_data(b);
+ 	struct evbuffer *output;
+ 	size_t outlen;
+ 
+ 	BIO_clear_retry_flags(b);
+ 
+-	if (!b->ptr)
++	if (!BIO_get_data(b))
+ 		return -1;
+ 
+ 	output = bufferevent_get_output(bufev);
+@@ -194,15 +191,15 @@ bio_bufferevent_write(BIO *b, const char *in, int inlen)
+ static long
+ bio_bufferevent_ctrl(BIO *b, int cmd, long num, void *ptr)
+ {
+-	struct bufferevent *bufev = b->ptr;
++	struct bufferevent *bufev = BIO_get_data(b);
+ 	long ret = 1;
+ 
+ 	switch (cmd) {
+ 	case BIO_CTRL_GET_CLOSE:
+-		ret = b->shutdown;
++		ret = BIO_get_shutdown(b);
+ 		break;
+ 	case BIO_CTRL_SET_CLOSE:
+-		b->shutdown = (int)num;
++		BIO_set_shutdown(b, (int)num);
+ 		break;
+ 	case BIO_CTRL_PENDING:
+ 		ret = evbuffer_get_length(bufferevent_get_input(bufev)) != 0;
+@@ -231,23 +228,24 @@ bio_bufferevent_puts(BIO *b, const char *s)
+ }
+ 
+ /* Method table for the bufferevent BIO */
+-static BIO_METHOD methods_bufferevent = {
+-	BIO_TYPE_LIBEVENT, "bufferevent",
+-	bio_bufferevent_write,
+-	bio_bufferevent_read,
+-	bio_bufferevent_puts,
+-	NULL /* bio_bufferevent_gets */,
+-	bio_bufferevent_ctrl,
+-	bio_bufferevent_new,
+-	bio_bufferevent_free,
+-	NULL /* callback_ctrl */,
+-};
++static BIO_METHOD *methods_bufferevent;
+ 
+ /* Return the method table for the bufferevents BIO */
+ static BIO_METHOD *
+ BIO_s_bufferevent(void)
+ {
+-	return &methods_bufferevent;
++	if (methods_bufferevent == NULL) {
++		methods_bufferevent = BIO_meth_new(BIO_TYPE_LIBEVENT, "bufferevent");
++		if (methods_bufferevent == NULL)
++			return NULL;
++		BIO_meth_set_write(methods_bufferevent, bio_bufferevent_write);
++		BIO_meth_set_read(methods_bufferevent, bio_bufferevent_read);
++		BIO_meth_set_puts(methods_bufferevent, bio_bufferevent_puts);
++		BIO_meth_set_ctrl(methods_bufferevent, bio_bufferevent_ctrl);
++		BIO_meth_set_create(methods_bufferevent, bio_bufferevent_new);
++		BIO_meth_set_destroy(methods_bufferevent, bio_bufferevent_free);
++	}
++	return methods_bufferevent;
+ }
+ 
+ /* Create a new BIO to wrap communication around a bufferevent.  If close_flag
+@@ -260,9 +258,9 @@ BIO_new_bufferevent(struct bufferevent *bufferevent, int close_flag)
+ 		return NULL;
+ 	if (!(result = BIO_new(BIO_s_bufferevent())))
+ 		return NULL;
+-	result->init = 1;
+-	result->ptr = bufferevent;
+-	result->shutdown = close_flag ? 1 : 0;
++	BIO_set_init(result, 1);
++	BIO_set_data(result, bufferevent);
++	BIO_set_shutdown(result, close_flag ? 1 : 0);
+ 	return result;
+ }
+ 
+diff --git a/openssl-compat.h b/openssl-compat.h
+new file mode 100644
+index 0000000..e47bac6
+--- /dev/null
++++ b/openssl-compat.h
+@@ -0,0 +1,33 @@
++#ifndef OPENSSL_COMPAT_H
++#define OPENSSL_COMPAT_H
++
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
++
++static BIO_METHOD *BIO_meth_new(int type, const char *name)
++{
++       BIO_METHOD *biom = calloc(1, sizeof(BIO_METHOD));
++
++       if (biom != NULL) {
++               biom->type = type;
++               biom->name = name;
++       }
++       return biom;
++}
++
++#define BIO_meth_set_write(b, f) b->bwrite = f
++#define BIO_meth_set_read(b, f) b->bread = f
++#define BIO_meth_set_puts(b, f) b->bputs = f
++#define BIO_meth_set_ctrl(b, f) b->ctrl = f
++#define BIO_meth_set_create(b, f) b->create = f
++#define BIO_meth_set_destroy(b, f) b->destroy = f
++
++#define BIO_set_init(b, val) b->init = val
++#define BIO_set_data(b, val) b->ptr = val
++#define BIO_set_shutdown(b, val) b->shutdown = val
++#define BIO_get_init(b) b->init
++#define BIO_get_data(b) b->ptr
++#define BIO_get_shutdown(b) b->shutdown
++
++#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
++
++#endif /* OPENSSL_COMPAT_H */

Copied: libevent/repos/testing-x86_64/0001-evdns-fix-searching-empty-hostnames.patch (from rev 289912, libevent/trunk/0001-evdns-fix-searching-empty-hostnames.patch)
===================================================================
--- testing-x86_64/0001-evdns-fix-searching-empty-hostnames.patch	                        (rev 0)
+++ testing-x86_64/0001-evdns-fix-searching-empty-hostnames.patch	2017-03-03 09:23:09 UTC (rev 289913)
@@ -0,0 +1,65 @@
+From ec65c42052d95d2c23d1d837136d1cf1d9ecef9e Mon Sep 17 00:00:00 2001
+From: Azat Khuzhin <a3at.mail at 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
+

Copied: libevent/repos/testing-x86_64/0002-test-dns-regression-for-empty-hostname.patch (from rev 289912, libevent/trunk/0002-test-dns-regression-for-empty-hostname.patch)
===================================================================
--- testing-x86_64/0002-test-dns-regression-for-empty-hostname.patch	                        (rev 0)
+++ testing-x86_64/0002-test-dns-regression-for-empty-hostname.patch	2017-03-03 09:23:09 UTC (rev 289913)
@@ -0,0 +1,55 @@
+From 683cf19b56dad3bc7b5915e2765b3e3c325c2dfe Mon Sep 17 00:00:00 2001
+From: Azat Khuzhin <a3at.mail at 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
+

Copied: libevent/repos/testing-x86_64/0003-evdns-name_parse-fix-remote-stack-overread.patch (from rev 289912, libevent/trunk/0003-evdns-name_parse-fix-remote-stack-overread.patch)
===================================================================
--- testing-x86_64/0003-evdns-name_parse-fix-remote-stack-overread.patch	                        (rev 0)
+++ testing-x86_64/0003-evdns-name_parse-fix-remote-stack-overread.patch	2017-03-03 09:23:09 UTC (rev 289913)
@@ -0,0 +1,115 @@
+From 96f64a022014a208105ead6c8a7066018449d86d Mon Sep 17 00:00:00 2001
+From: Azat Khuzhin <a3at.mail at gmail.com>
+Date: Mon, 1 Feb 2016 17:32:09 +0300
+Subject: [PATCH] evdns: name_parse(): fix remote stack overread
+
+ at 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
+

Copied: libevent/repos/testing-x86_64/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch (from rev 289912, libevent/trunk/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch)
===================================================================
--- testing-x86_64/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch	                        (rev 0)
+++ testing-x86_64/0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch	2017-03-03 09:23:09 UTC (rev 289913)
@@ -0,0 +1,88 @@
+From 329acc18a0768c21ba22522f01a5c7f46cacc4d5 Mon Sep 17 00:00:00 2001
+From: Azat Khuzhin <a3at.mail at gmail.com>
+Date: Sun, 31 Jan 2016 00:57:16 +0300
+Subject: [PATCH] evutil_parse_sockaddr_port(): fix buffer overflow
+
+ at 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
+

Copied: libevent/repos/testing-x86_64/PKGBUILD (from rev 289912, libevent/trunk/PKGBUILD)
===================================================================
--- testing-x86_64/PKGBUILD	                        (rev 0)
+++ testing-x86_64/PKGBUILD	2017-03-03 09:23:09 UTC (rev 289913)
@@ -0,0 +1,54 @@
+# $Id$
+# Maintainer: Tom Gundersen <teg at jklm.no>
+# Contributor: Judd <jvinet at zeroflux.org>
+
+pkgname=libevent
+pkgver=2.0.22
+pkgrel=3
+pkgdesc="An event notification library"
+arch=('i686' 'x86_64')
+url="http://libevent.org/"
+license=('BSD')
+depends=('openssl')
+optdepends=('python2: to use event_rpcgen.py')
+source=(https://github.com/libevent/libevent/releases/download/release-$pkgver-stable/$pkgname-$pkgver-stable.tar.gz{,.asc}
+        openssl_1.1.patch
+        0001-evdns-fix-searching-empty-hostnames.patch
+        0002-test-dns-regression-for-empty-hostname.patch
+        0003-evdns-name_parse-fix-remote-stack-overread.patch
+        0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch)
+sha256sums=('71c2c49f0adadacfdbe6332a372c38cf9c8b7895bb73dabeaa53cdcc1d4e1fa3'
+            'SKIP'
+            '1c0e3a47e5739ce6f05cfdaeaf1bb33eb7c6c89003538f680586e50cbd2abb48'
+            '66ca7cd16a2260537e1f7d7d22ace9c50bcc54f5f47af41361f1771de6b37526'
+            'b76aaa4730fe377f49077a428645e6e5335a5fe5600fece1e0dd4503749e25d5'
+            'e2bbd44121f4f5c70ba891e4dc9f150254babae0c647bb47792571a6e88c0614'
+            'c02932ec76925d9c470a7b955add045f59dbef3dcc85b46020bda61151b22533')
+validpgpkeys=('B35BF85BF19489D04E28C33C21194EBB165733EA')
+
+prepare() {
+  cd ${pkgname}-${pkgver}-stable
+  patch -Np1 -i ../0001-evdns-fix-searching-empty-hostnames.patch
+  patch -Np1 -i ../0002-test-dns-regression-for-empty-hostname.patch
+  patch -Np1 -i ../0003-evdns-name_parse-fix-remote-stack-overread.patch
+  patch -Np1 -i ../0004-evutil_parse_sockaddr_port-fix-buffer-overflow.patch
+  #patch -Np1 -i ../openssl_1.1.patch
+}
+
+build() {
+  cd ${pkgname}-${pkgver}-stable
+  ./autogen.sh
+  ./configure --prefix=/usr --sysconfdir=/etc --disable-libevent-regress
+  make
+}
+
+check() {
+  cd ${pkgname}-${pkgver}-stable
+  make -j1 check
+}
+
+package() {
+  cd ${pkgname}-${pkgver}-stable
+  make DESTDIR="${pkgdir}" install
+  install -Dm 644 LICENSE "${pkgdir}"/usr/share/licenses/libevent/LICENSE
+}

Copied: libevent/repos/testing-x86_64/openssl_1.1.patch (from rev 289912, libevent/trunk/openssl_1.1.patch)
===================================================================
--- testing-x86_64/openssl_1.1.patch	                        (rev 0)
+++ testing-x86_64/openssl_1.1.patch	2017-03-03 09:23:09 UTC (rev 289913)
@@ -0,0 +1,190 @@
+From 7fb978bf21e21a1de36777b45ea984bb1d5c52dd Mon Sep 17 00:00:00 2001
+From: Kurt Roeckx <kurt at roeckx.be>
+Date: Mon, 19 Sep 2016 22:05:15 +0200
+Subject: [PATCH] Make it build using OpenSSL 1.1.0
+
+---
+ bufferevent_openssl.c                | 62 +++++++++++++++++-------------------
+ openssl-compat.h                     | 33 +++++++++++++++++++
+ 5 files changed, 102 insertions(+), 63 deletions(-)
+ create mode 100644 openssl-compat.h
+
+diff --git a/bufferevent_openssl.c b/bufferevent_openssl.c
+index 017bfce..b8a0fe0 100644
+--- a/bufferevent_openssl.c
++++ b/bufferevent_openssl.c
+@@ -66,6 +66,7 @@
+ #include <openssl/bio.h>
+ #include <openssl/ssl.h>
+ #include <openssl/err.h>
++#include "openssl-compat.h"
+ 
+ /*
+  * Define an OpenSSL bio that targets a bufferevent.
+@@ -109,10 +110,8 @@ print_err(int val)
+ static int
+ bio_bufferevent_new(BIO *b)
+ {
+-	b->init = 0;
+-	b->num = -1;
+-	b->ptr = NULL; /* We'll be putting the bufferevent in this field.*/
+-	b->flags = 0;
++	BIO_set_init(b, 0);
++	BIO_set_data(b, NULL); /* We'll be putting the bufferevent in this field.*/
+ 	return 1;
+ }
+ 
+@@ -122,12 +121,10 @@ bio_bufferevent_free(BIO *b)
+ {
+ 	if (!b)
+ 		return 0;
+-	if (b->shutdown) {
+-		if (b->init && b->ptr)
+-			bufferevent_free(b->ptr);
+-		b->init = 0;
+-		b->flags = 0;
+-		b->ptr = NULL;
++	if (BIO_get_shutdown(b)) {
++		if (BIO_get_init(b) && BIO_get_data(b))
++			bufferevent_free(BIO_get_data(b));
++		BIO_free(b);
+ 	}
+ 	return 1;
+ }
+@@ -143,10 +140,10 @@ bio_bufferevent_read(BIO *b, char *out, int outlen)
+ 
+ 	if (!out)
+ 		return 0;
+-	if (!b->ptr)
++	if (!BIO_get_data(b))
+ 		return -1;
+ 
+-	input = bufferevent_get_input(b->ptr);
++	input = bufferevent_get_input(BIO_get_data(b));
+ 	if (evbuffer_get_length(input) == 0) {
+ 		/* If there's no data to read, say so. */
+ 		BIO_set_retry_read(b);
+@@ -162,13 +159,13 @@ bio_bufferevent_read(BIO *b, char *out, int outlen)
+ static int
+ bio_bufferevent_write(BIO *b, const char *in, int inlen)
+ {
+-	struct bufferevent *bufev = b->ptr;
++	struct bufferevent *bufev = BIO_get_data(b);
+ 	struct evbuffer *output;
+ 	size_t outlen;
+ 
+ 	BIO_clear_retry_flags(b);
+ 
+-	if (!b->ptr)
++	if (!BIO_get_data(b))
+ 		return -1;
+ 
+ 	output = bufferevent_get_output(bufev);
+@@ -194,15 +191,15 @@ bio_bufferevent_write(BIO *b, const char *in, int inlen)
+ static long
+ bio_bufferevent_ctrl(BIO *b, int cmd, long num, void *ptr)
+ {
+-	struct bufferevent *bufev = b->ptr;
++	struct bufferevent *bufev = BIO_get_data(b);
+ 	long ret = 1;
+ 
+ 	switch (cmd) {
+ 	case BIO_CTRL_GET_CLOSE:
+-		ret = b->shutdown;
++		ret = BIO_get_shutdown(b);
+ 		break;
+ 	case BIO_CTRL_SET_CLOSE:
+-		b->shutdown = (int)num;
++		BIO_set_shutdown(b, (int)num);
+ 		break;
+ 	case BIO_CTRL_PENDING:
+ 		ret = evbuffer_get_length(bufferevent_get_input(bufev)) != 0;
+@@ -231,23 +228,24 @@ bio_bufferevent_puts(BIO *b, const char *s)
+ }
+ 
+ /* Method table for the bufferevent BIO */
+-static BIO_METHOD methods_bufferevent = {
+-	BIO_TYPE_LIBEVENT, "bufferevent",
+-	bio_bufferevent_write,
+-	bio_bufferevent_read,
+-	bio_bufferevent_puts,
+-	NULL /* bio_bufferevent_gets */,
+-	bio_bufferevent_ctrl,
+-	bio_bufferevent_new,
+-	bio_bufferevent_free,
+-	NULL /* callback_ctrl */,
+-};
++static BIO_METHOD *methods_bufferevent;
+ 
+ /* Return the method table for the bufferevents BIO */
+ static BIO_METHOD *
+ BIO_s_bufferevent(void)
+ {
+-	return &methods_bufferevent;
++	if (methods_bufferevent == NULL) {
++		methods_bufferevent = BIO_meth_new(BIO_TYPE_LIBEVENT, "bufferevent");
++		if (methods_bufferevent == NULL)
++			return NULL;
++		BIO_meth_set_write(methods_bufferevent, bio_bufferevent_write);
++		BIO_meth_set_read(methods_bufferevent, bio_bufferevent_read);
++		BIO_meth_set_puts(methods_bufferevent, bio_bufferevent_puts);
++		BIO_meth_set_ctrl(methods_bufferevent, bio_bufferevent_ctrl);
++		BIO_meth_set_create(methods_bufferevent, bio_bufferevent_new);
++		BIO_meth_set_destroy(methods_bufferevent, bio_bufferevent_free);
++	}
++	return methods_bufferevent;
+ }
+ 
+ /* Create a new BIO to wrap communication around a bufferevent.  If close_flag
+@@ -260,9 +258,9 @@ BIO_new_bufferevent(struct bufferevent *bufferevent, int close_flag)
+ 		return NULL;
+ 	if (!(result = BIO_new(BIO_s_bufferevent())))
+ 		return NULL;
+-	result->init = 1;
+-	result->ptr = bufferevent;
+-	result->shutdown = close_flag ? 1 : 0;
++	BIO_set_init(result, 1);
++	BIO_set_data(result, bufferevent);
++	BIO_set_shutdown(result, close_flag ? 1 : 0);
+ 	return result;
+ }
+ 
+diff --git a/openssl-compat.h b/openssl-compat.h
+new file mode 100644
+index 0000000..e47bac6
+--- /dev/null
++++ b/openssl-compat.h
+@@ -0,0 +1,33 @@
++#ifndef OPENSSL_COMPAT_H
++#define OPENSSL_COMPAT_H
++
++#if OPENSSL_VERSION_NUMBER < 0x10100000L
++
++static BIO_METHOD *BIO_meth_new(int type, const char *name)
++{
++       BIO_METHOD *biom = calloc(1, sizeof(BIO_METHOD));
++
++       if (biom != NULL) {
++               biom->type = type;
++               biom->name = name;
++       }
++       return biom;
++}
++
++#define BIO_meth_set_write(b, f) b->bwrite = f
++#define BIO_meth_set_read(b, f) b->bread = f
++#define BIO_meth_set_puts(b, f) b->bputs = f
++#define BIO_meth_set_ctrl(b, f) b->ctrl = f
++#define BIO_meth_set_create(b, f) b->create = f
++#define BIO_meth_set_destroy(b, f) b->destroy = f
++
++#define BIO_set_init(b, val) b->init = val
++#define BIO_set_data(b, val) b->ptr = val
++#define BIO_set_shutdown(b, val) b->shutdown = val
++#define BIO_get_init(b) b->init
++#define BIO_get_data(b) b->ptr
++#define BIO_get_shutdown(b) b->shutdown
++
++#endif /* OPENSSL_VERSION_NUMBER < 0x10100000L */
++
++#endif /* OPENSSL_COMPAT_H */



More information about the arch-commits mailing list