maxmind / geoip-api-c

DEPRECATED GeoIP Legacy C API
Other
371 stars 129 forks source link

Memory corruption in get_index_size (GeoIP.c), SIGSEGV #87

Closed stze closed 7 years ago

stze commented 7 years ago

Opening the following sample input file with GeoIP_open results in a crash (SIGSEGV). The input file is fuzzed with american fuzzy lop http://lcamtuf.coredump.cx/afl/.

sample file hexdump:

00000000  01 00 00 02 00 00 03 00  01 00 05 00 00 06 00 00  |................|
00000010  36 ff ff ff 00 ff 07 00                           |6.......|
00000018

How to reproduce:

#include "GeoIP.h"

int main(int argc, char **argv)
{
    GeoIP *gi;

    gi = GeoIP_open(argv[1], GEOIP_STANDARD | GEOIP_CHECK_CACHE);

    exit(0);
}

compile and execute (named test) ...

$ ./test <above sample input file>

gdb:

Program terminated with signal SIGSEGV, Segmentation fault.
#0  get_index_size (gi=<optimized out>, buf=<optimized out>) at GeoIP.c:941
941     index_size = segment * (ssize_t)gi->record_length * 2;
(gdb) bt
#0  get_index_size (gi=<optimized out>, buf=<optimized out>) at GeoIP.c:941
#1  GeoIP_open (filename=0x7fffaa5af8fd "findings/crashes/id:000000,sig:11,src:000000,op:flip32,pos:17", 
    flags=2) at GeoIP.c:1589
#2  0x00000000004013a2 in main (argc=<optimized out>, argv=<optimized out>) at test/test-fuzz.c:27

valgrind:

==4171== Memcheck, a memory error detector
==4171== Copyright (C) 2002-2015, and GNU GPL'd, by Julian Seward et al.
==4171== Using Valgrind-3.12.0 and LibVEX; rerun with -h for copyright info
==4171== Command: ./foo findings/crashes/id:000000,sig:11,src:000000,op:flip32,pos:17
==4171== 
==4171== Invalid read of size 4
==4171==    at 0x403F95: get_index_size (GeoIP.c:941)
==4171==    by 0x403F95: GeoIP_open (GeoIP.c:1589)
==4171==    by 0x4013A1: main (test-fuzz.c:27)
==4171==  Address 0x0 is not stack'd, malloc'd or (recently) free'd
==4171== 
==4171== 
==4171== Process terminating with default action of signal 11 (SIGSEGV): dumping core
==4171==  Access not within mapped region at address 0x0
==4171==    at 0x403F95: get_index_size (GeoIP.c:941)
==4171==    by 0x403F95: GeoIP_open (GeoIP.c:1589)
==4171==    by 0x4013A1: main (test-fuzz.c:27)
==4171==  If you believe this happened as a result of a stack
==4171==  overflow in your program's main thread (unlikely but
==4171==  possible), you can try to increase the size of the
==4171==  main thread stack using the --main-stacksize= flag.
==4171==  The main thread stack size used in this run was 8388608.
==4171== 
==4171== HEAP SUMMARY:
==4171==     in use at exit: 726 bytes in 3 blocks
==4171==   total heap usage: 3 allocs, 0 frees, 726 bytes allocated
==4171== 
==4171== 174 (112 direct, 62 indirect) bytes in 1 blocks are definitely lost in loss record 2 of 3
==4171==    at 0x4C2AF1F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==4171==    by 0x403B63: GeoIP_open (GeoIP.c:1514)
==4171==    by 0x4013A1: main (test-fuzz.c:27)
==4171== 
==4171== LEAK SUMMARY:
==4171==    definitely lost: 112 bytes in 1 blocks
==4171==    indirectly lost: 62 bytes in 1 blocks
==4171==      possibly lost: 0 bytes in 0 blocks
==4171==    still reachable: 552 bytes in 1 blocks
==4171==         suppressed: 0 bytes in 0 blocks
==4171== Reachable blocks (those to which a pointer was found) are not shown.
==4171== To see them, rerun with: --leak-check=full --show-leak-kinds=all
==4171== 
==4171== For counts of detected and suppressed errors, rerun with: -v
==4171== ERROR SUMMARY: 2 errors from 2 contexts (suppressed: 0 from 0)

Regards, Stephan

oschwald commented 7 years ago

Thanks for the report! We will look into it.