Package: libevent / 2.0.21-stable-2+deb8u1

Metadata

Package Version Patches format
libevent 2.0.21-stable-2+deb8u1 3.0 (quilt)

Patch series

view the series file
Patch File delta Description
build_with_no_undefined.patch | (download)

Makefile.am | 5 0 + 5 - 0 !
Makefile.in | 8 3 + 5 - 0 !
2 files changed, 3 insertions(+), 10 deletions(-)

 always build with -no-undefined

This seems to be the easiest way to patch the build-system, so that
all libs get linked to _core and -no-undefined gets passed to libtool.

Will discuss with upstream what's the reason for this not being the
default.


dh autoreconf | (download)

test/Makefile.am | 6 5 + 1 - 0 !
1 file changed, 5 insertions(+), 1 deletion(-)

 update config.* to fix ftbfs on ppc64el
   * Update config.* to fix FTBFS on ppc64el. Closes: #750693
20d6d445.patch | (download)

buffer.c | 71 62 + 9 - 0 !
configure.in | 1 1 + 0 - 0 !
evbuffer-internal.h | 14 13 + 1 - 0 !
3 files changed, 76 insertions(+), 10 deletions(-)

---
0001 evdns fix searching empty hostnames.patch | (download)

evdns.c | 5 4 + 1 - 0 !
1 file changed, 4 insertions(+), 1 deletion(-)

 [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

0002 test dns regression for empty hostname.patch | (download)

test/regress_dns.c | 21 21 + 0 - 0 !
1 file changed, 21 insertions(+)

 [patch] test/dns: regression for empty hostname

Refs: #332

Conflicts:
	test/regress_dns.c

0003 evdns name_parse fix remote stack overread.patch | (download)

evdns.c | 2 1 + 1 - 0 !
1 file changed, 1 insertion(+), 1 deletion(-)

 [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

0004 evutil_parse_sockaddr_port fix buffer overflow.patch | (download)

evutil.c | 6 3 + 3 - 0 !
1 file changed, 3 insertions(+), 3 deletions(-)

 [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