Follow @Openwall on Twitter for new release announcements and other news
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Date: Sat, 21 Mar 2015 22:03:02 +0100
From: Szabolcs Nagy <nsz@...t70.net>
To: Konstantin Serebryany <konstantin.s.serebryany@...il.com>,
	Rich Felker <dalias@...c.org>, musl@...ts.openwall.com
Subject: Re: buffer overflow in regcomp and a way to find more of those

i wrote some trivial test cases for

__dn_expand
__dns_parse
__pleval
fnmatch
inet_pton
strptime

to try out the concept, i've seen one crash so far:
a bus error when fuzzing inet_pton

probably a stack corruption that overwrites the location
where %rbp is stored and then the memory access relative
to rbp crashes

the fuzzing goes like:

./a.out -seed=1753234605
...
#8388608	cov: 546	bits: 0	exec/s: 838860
#16777216	cov: 546	bits: 0	exec/s: 798915
#27461772	NEW: 548 B: 0 L: 16 S: 22 I: 0	8283::2:2.8.83.3	16: 56 50 56 51 58 58 50 58 50 46 56 46 56 51 46 51 
#27469404	NEW: 549 B: 0 L: 24 S: 23 I: 2	8283::2:283:2.8.83.2.833	24: 56 50 56 51 58 58 50 58 50 56 51 58 50 46 56 46 56 51 46 50 46 56 51 51 
Bus error (core dumped)

is there a way to get a reproducer after such a crash?

in this case i fortunately had the core dump
and i can see the inet_pton argument in %r14
but it would be nice if there were occasional
saved check points from where i can restart
the fuzzer.

i dont yet see the bug and cannot reproduce the
issue outside the fuzzer (but i didnt try very hard)

attached the fuzz test case and the code that should
reproduce the issue, gdb session below

Core was generated by `./a.out -seed=1753234605'.
Program terminated with signal SIGBUS, Bus error.
#0  0x000000000047a05b in inet_pton (af=<optimized out>, s=<optimized out>, a0=0x20000ffffe000) at src/network/inet_pton.c:65
65			*a++ = ip[j]>>8;
(gdb) bt
#0  0x000000000047a05b in inet_pton (af=<optimized out>, s=<optimized out>, a0=0x20000ffffe000) at src/network/inet_pton.c:65
#1  0x0000000000400769 in TestOneInput ()
#2  0x000000000040c6f3 in fuzzer::Fuzzer::RunOneMaximizeTotalCoverage(std::vector<unsigned char, std::allocator<unsigned char> > const&) ()
#3  0x000000000040c412 in fuzzer::Fuzzer::RunOne(std::vector<unsigned char, std::allocator<unsigned char> > const&) ()
#4  0x000000000040cc7c in fuzzer::Fuzzer::MutateAndTestOne(std::vector<unsigned char, std::allocator<unsigned char> >*) ()
#5  0x000000000040cffb in fuzzer::Fuzzer::Loop(unsigned long) ()
#6  0x0000000000400d4c in fuzzer::FuzzerDriver(int, char**, void (*)(unsigned char const*, unsigned long)) ()
#7  0x00000000004007dc in main ()
(gdb) disass inet_pton,+40
Dump of assembler code from 0x479b40 to 0x479b68:
   0x0000000000479b40 <inet_pton+0>:	push   %rbp
   0x0000000000479b41 <inet_pton+1>:	push   %r15
   0x0000000000479b43 <inet_pton+3>:	push   %r14
   0x0000000000479b45 <inet_pton+5>:	push   %r13
   0x0000000000479b47 <inet_pton+7>:	push   %r12
   0x0000000000479b49 <inet_pton+9>:	push   %rbx
   0x0000000000479b4a <inet_pton+10>:	sub    $0x28,%rsp
   0x0000000000479b4e <inet_pton+14>:	mov    %rdx,%r13
   0x0000000000479b51 <inet_pton+17>:	mov    %rsi,%r14
   0x0000000000479b54 <inet_pton+20>:	mov    %edi,%ebp
   0x0000000000479b56 <inet_pton+22>:	mov    $0x6de364,%edi
   0x0000000000479b5b <inet_pton+27>:	callq  0x4007f0 <__sanitizer_cov_with_check>
   0x0000000000479b60 <inet_pton+32>:	cmp    $0xa,%ebp
   0x0000000000479b63 <inet_pton+35>:	jne    0x479ba6 <inet_pton+102>
   0x0000000000479b65 <inet_pton+37>:	mov    $0x6de3c8,%edi
End of assembler dump.
(gdb) disass /m 0x000000000047a020,+64 
Dump of assembler code from 0x47a020 to 0x47a060:
62			for (j=0; j<7-i; j++) ip[brk+j] = 0;
   0x000000000047a02a <inet_pton+1258>:	callq  0x4007f0 <__sanitizer_cov_with_check>
   0x000000000047a02f <inet_pton+1263>:	xor    %ebx,%ebx
   0x000000000047a031 <inet_pton+1265>:	mov    0x8(%rsp),%rbp
   0x000000000047a036 <inet_pton+1270>:	mov    0x4(%rsp),%r15d
   0x000000000047a03b <inet_pton+1275>:	jmp    0x47a04d <inet_pton+1293>
   0x000000000047a03d <inet_pton+1277>:	nopl   (%rax)

63		}
64		for (j=0; j<8; j++) {
   0x000000000047a040 <inet_pton+1280>:	inc    %rbx
   0x000000000047a043 <inet_pton+1283>:	mov    $0x6de46c,%edi
   0x000000000047a048 <inet_pton+1288>:	callq  0x4007f0 <__sanitizer_cov_with_check>
   0x000000000047a04d <inet_pton+1293>:	mov    $0x6de468,%edi

65			*a++ = ip[j]>>8;
   0x000000000047a052 <inet_pton+1298>:	callq  0x4007f0 <__sanitizer_cov_with_check>
   0x000000000047a057 <inet_pton+1303>:	mov    0x11(%rsp,%rbx,2),%al
=> 0x000000000047a05b <inet_pton+1307>:	mov    %al,0x0(%rbp,%rbx,2)

66			*a++ = ip[j];
   0x000000000047a05f <inet_pton+1311>:	mov    0x10(%rsp,%rbx,2),%al
   0x000000000047a063 <inet_pton+1315>:	mov    %al,0x1(%rbp,%rbx,2)

End of assembler dump.
(gdb) i reg
rax            0x7fffffffdf00	140737488346880
rbx            0x0	0
rcx            0x0	0
rdx            0x0	0
rsi            0x7fffffffdfb2	140737488347058
rdi            0x6de468	7201896
rbp            0x20000ffffe000	0x20000ffffe000
rsp            0x7fffffffdf80	0x7fffffffdf80
r8             0x7fffffffdf3a	140737488346938
r9             0x0	0
r10            0x0	0
r11            0x246	582
r12            0x10	16
r13            0x7	7
r14            0x6e2dc3	7220675
r15            0x1	1
rip            0x47a05b	0x47a05b <inet_pton+1307>
eflags         0x10202	[ IF RF ]
cs             0x33	51
ss             0x2b	43
ds             0x0	0
es             0x0	0
fs             0x63	99
gs             0x0	0
(gdb) p (char*)0x6e2dc3
$3 = 0x6e2dc3 "2.8288;3:33::2.82.83333"
(gdb) 

View attachment "inet_pton_fuzz.c" of type "text/x-csrc" (223 bytes)

View attachment "inet_pton_reporoduce.c" of type "text/x-csrc" (137 bytes)

Powered by blists - more mailing lists

Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.