aboutsummaryrefslogtreecommitdiffstats
path: root/main/libevent/CVE-2016-10197.patch
blob: ca8de2aadbc311b3062eb406391fbbfa9653558a (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
Source: https://github.com/libevent/libevent/commit/ec65c42052d95d2c23d1d837136d1cf1d9ecef9e

commit ec65c42052d95d2c23d1d837136d1cf1d9ecef9e
Author: Azat Khuzhin <a3at.mail@gmail.com>
Date:   Fri Mar 25 00:33:47 2016 +0300

    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

diff --git a/evdns.c b/evdns.c
index 905ff6b5..e9dbc35c 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 */