summaryrefslogtreecommitdiff
path: root/evutil.c
diff options
context:
space:
mode:
authorAzat Khuzhin <a3at.mail@gmail.com>2016-01-31 00:57:16 +0300
committerAzat Khuzhin <a3at.mail@gmail.com>2016-02-01 16:37:16 +0300
commit329acc18a0768c21ba22522f01a5c7f46cacc4d5 (patch)
tree2e464b81ff67438884a2ba7151becbe1186bb7c7 /evutil.c
parent49bd79047bc9aca3ca43fb79eac3901e7805c0df (diff)
downloadlibevent-329acc18a0768c21ba22522f01a5c7f46cacc4d5.tar.gz
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
Diffstat (limited to 'evutil.c')
-rw-r--r--evutil.c6
1 files changed, 3 insertions, 3 deletions
diff --git a/evutil.c b/evutil.c
index 79d825d9..495bfcc0 100644
--- a/evutil.c
+++ b/evutil.c
@@ -2058,12 +2058,12 @@ evutil_parse_sockaddr_port(const char *ip_as_string, struct sockaddr *out, int *
cp = strchr(ip_as_string, ':');
if (*ip_as_string == '[') {
- int len;
+ size_t len;
if (!(cp = strchr(ip_as_string, ']'))) {
return -1;
}
- len = (int) ( cp-(ip_as_string + 1) );
- if (len > (int)sizeof(buf)-1) {
+ len = ( cp-(ip_as_string + 1) );
+ if (len > sizeof(buf)-1) {
return -1;
}
memcpy(buf, ip_as_string+1, len);