Bug 1316 - Possible heap read buffer overflow in SVN head
Possible heap read buffer overflow in SVN head
Status: RESOLVED FIXED
Product: unbound
Classification: Unclassified
Component: server
unspecified
x86_64 Linux
: P5 enhancement
Assigned To: unbound team
Depends on:
Blocks:
  Show dependency treegraph
 
Reported: 2017-06-21 12:55 CEST by Erik
Modified: 2017-06-22 08:51 CEST (History)
3 users (show)

See Also:


Attachments
Make file and crashing program (10.00 KB, application/x-compressed-tar)
2017-06-21 12:55 CEST, Erik
Details
The AFL fuzz target (1.49 KB, text/x-csrc)
2017-06-21 22:54 CEST, Erik
Details

Note You need to log in before you can comment on or make changes to this bug.
Description Erik 2017-06-21 12:55:11 CEST
Created attachment 411 [details]
Make file and crashing program

I'm trying to fuzz test the DNS packet parsing code in unbound. I've written a small test program that reads a data file provided by the fuzzer and then passes it to unbound's `reply_info_parse` function.

Within about 30 minutes of setting this up, I found the heap read overflow.

To reproduce this, grab the attached tarball, extract the two files, and drop them in the top level directory of the current SVN source tree. Then run:

    ./configure
    ./mk-fuzz-target.mk clean
    ./mk-fuzz-target.mk parse-reply-crash
    ./parse-reply-crash

The final line (running the crashing program) should produce something like:


> ./parse-reply-crash
len     : 26
sbuffer : 0x60400000dfd0
=================================================================
==12549==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000effa at pc 0x557eebb507e8 bp 0x7ffe102fbc60 sp 0x7ffe102fbc58
READ of size 1 at 0x60300000effa thread T0
    #0 0x557eebb507e7 in sldns_read_uint16 sldns/sbuffer.h:41
    #1 0x557eebb55acb in parse_edns_options util/data/msgparse.c:946
    #2 0x557eebb56288 in parse_extract_edns util/data/msgparse.c:1023
    #3 0x557eebb59cf4 in reply_info_parse util/data/msgreply.c:467
    #4 0x557eeba3aa9c in main /home/erikd/Git/FuzzingSetup/unbound-svn/parse-reply-crash.c:50
    #5 0x7f3f0182e2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)
    #6 0x557eeba3a7c9 in _start (/home/erikd/Git/FuzzingSetup/unbound-svn/parse-reply-crash+0x477c9)

0x60300000effa is located 0 bytes to the right of 26-byte region [0x60300000efe0,0x60300000effa)
allocated by thread T0 here:
    #0 0x7f3f02a54d28 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.3+0xc1d28)
    #1 0x557eebaef9d8 in sldns_buffer_new_frm_data sldns/sbuffer.c:55
    #2 0x557eeba3aa16 in main /home/erikd/Git/FuzzingSetup/unbound-svn/parse-reply-crash.c:42
    #3 0x7f3f0182e2b0 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x202b0)

SUMMARY: AddressSanitizer: heap-buffer-overflow sldns/sbuffer.h:41 in sldns_read_uint16
Shadow bytes around the buggy address:
  0x0c067fff9da0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9db0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9dc0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9dd0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9de0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x0c067fff9df0: fa fa fa fa fa fa fa fa fa fa fa fa 00 00 00[02]
  0x0c067fff9e00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9e10: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9e20: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9e30: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c067fff9e40: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Heap right redzone:      fb
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack partial redzone:   f4
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==12549==ABORTING
Comment 1 Erik 2017-06-21 12:56:08 CEST
There is still a possibility that I'm doing something incorrect by simply passing random string into that function.
Comment 2 Erik 2017-06-21 12:58:16 CEST
Its actually not a `.tar.gz` file, its just a tar file.
Comment 3 Wouter Wijngaards 2017-06-21 13:52:08 CEST
Hi Erik,

Thank you very much for the report.

I miscalculated the size of the rdata by 2, below is the patch that adjusts it.  (In the deployed unbound the buffer is large enough that these read won't cause issues).  With the patch, the crash is removed.

Index: util/data/msgparse.c
===================================================================
--- util/data/msgparse.c	(revision 4238)
+++ util/data/msgparse.c	(working copy)
@@ -1018,7 +1018,7 @@
 	edns->opt_list = NULL;
 
 	/* take the options */
-	rdata_len = found->rr_first->size;
+	rdata_len = found->rr_first->size-2;
 	rdata_ptr = found->rr_first->ttl_data+6;
 	if(!parse_edns_options(rdata_ptr, rdata_len, edns, region))
 		return 0;
Comment 4 Manu Bretelle 2017-06-21 18:37:15 CEST
Erik, are you planning to upstream the fuzzer? This would be great to have in trunk.
Comment 5 Erik 2017-06-21 22:11:09 CEST
The fuzzer is American Fuzzy Lop. I gave a presentation about it at Linux.Conf.Au last year. The video is here : https://www.youtube.com/watch?v=y0hyqzR6hIY .
Comment 6 Erik 2017-06-21 22:54:24 CEST
Created attachment 413 [details]
The AFL fuzz target
Comment 7 Erik 2017-06-21 22:55:31 CEST
I'm using American Fuzzy Lop (http://lcamtuf.coredump.cx/afl/) mainly because its the fuzzer I have most experience with and it has a nice curses UI. However for fuzzing these DNS packet parsers the LLVM Fuzzer (http://llvm.org/docs/LibFuzzer.html) would also be a fine choice.

For fuzzing `reply_info_parse` I'm using the attached program. To fuzz with AFL, you would need a program like this for each parser you want to fuzz.
Comment 8 Manu Bretelle 2017-06-21 23:37:43 CEST
Sorry, I did not mean the fuzzer per se, but the programs you put together so it can be re-used in the future.
Comment 9 Erik 2017-06-21 23:53:11 CEST
So far its only one program, the one in the second attachment.
Comment 10 Wouter Wijngaards 2017-06-22 08:51:18 CEST
Hi Manu,

Something like that is not really part of this project (but feel free to exchange test suites).

Best regards, Wouter