Skip to content

Commit 329acc1

Browse files
committed
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
1 parent 49bd790 commit 329acc1

File tree

1 file changed

+3
-3
lines changed

1 file changed

+3
-3
lines changed

Diff for: evutil.c

+3-3
Original file line numberDiff line numberDiff line change
@@ -2058,12 +2058,12 @@ evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int *
20582058

20592059
cp = strchr(ip_as_string, ':');
20602060
if (*ip_as_string == '[') {
2061-
int len;
2061+
size_t len;
20622062
if (!(cp = strchr(ip_as_string, ']'))) {
20632063
return -1;
20642064
}
2065-
len = (int) ( cp-(ip_as_string + 1) );
2066-
if (len > (int)sizeof(buf)-1) {
2065+
len = ( cp-(ip_as_string + 1) );
2066+
if (len > sizeof(buf)-1) {
20672067
return -1;
20682068
}
20692069
memcpy(buf, ip_as_string+1, len);

0 commit comments

Comments
 (0)