Skip to content
master
Switch branches/tags

Name already in use

A tag already exists with the provided branch name. Many Git commands accept both tag and branch names, so creating this branch may cause unexpected behavior. Are you sure you want to create this branch?
security_advisories/ReadStat-7bced5b/
security_advisories/ReadStat-7bced5b/

Latest commit

 

Git stats

Files

Permalink
Failed to load latest commit information.
Type
Name
Latest commit message
Commit time
 
 
 
 

Multiple vulnerabilities in ReadStat-7bced5b (CVE-2018-11364)

We discovered multiple vulnerabilities in ReadStat (git repository:https://github.com/WizardMac/ReadStat, Latest commit 7bced5b on May 8, 2018).

git log

commit 7bced5b279486b92f362d97aa671241e787a809a
Author: Evan Miller <emmiller@gmail.com>
Date:   Tue May 8 07:23:27 2018 -0400

I modify the src/fuzz/Makefile (see: https://github.com/ChijinZ/security_advisories/blob/master/ReadStat-7bced5b/Makefile) so that I can generate libfuzzer-style entries to src/spss/readstat_sav_read.c and src/sas/readstat_sas7bcat_read.c

Memory Leaks

When the testcase (see: https://github.com/ChijinZ/security_advisories/blob/master/ReadStat-7bced5b/crash-sav-read) was input, a crash was triggered in ReadStat/src/spss/readstat_sav_read.c:894:

iconv_t converter = iconv_open(dst_charset, src_charset);

LeakSanitizer provided imformation as below:

==9990==ERROR: LeakSanitizer: detected memory leaks

Direct leak of 112 byte(s) in 1 object(s) allocated from:
    #0 0x4e2ef8 in __interceptor_malloc /home/ubuntu/llvm/llvm-6.0.0.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:88
    #1 0x7f3db68be3e0 in __gconv_open /build/glibc-Cl5G7W/glibc-2.23/iconv/gconv_open.c:114
    #2 0x7f3db68bde29 in iconv_open /build/glibc-Cl5G7W/glibc-2.23/iconv/iconv_open.c:71
    #3 0x7f3db7ba9e51 in sav_parse_machine_integer_info_record path/to/ReadStat/src/spss/readstat_sav_read.c:894:29
    #4 0x7f3db7ba4866 in sav_parse_records_pass1 path/to/ReadStat/src/spss/readstat_sav_read.c:1170:30
    #5 0x7f3db7ba31f6 in readstat_parse_sav path/to/ReadStat/src/spss/readstat_sav_read.c:1443:19
    #6 0x51b1a8 in LLVMFuzzerTestOneInput (path/to/ReadStat/src/fuzz/fuzz_format_sav+0x51b1a8)
    #7 0x5258d4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) path/to/libfuzzer/libFuzzer/Fuzzer/./FuzzerLoop.cpp:451:13
    #8 0x525b01 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long) path/to/libfuzzer/libFuzzer/Fuzzer/./FuzzerLoop.cpp:408:3
    #9 0x51b4e1 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) path/to/libfuzzer/libFuzzer/Fuzzer/./FuzzerDriver.cpp:268:6
    #10 0x51e2b8 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) path/to/libfuzzer/libFuzzer/Fuzzer/./FuzzerDriver.cpp:585:9
    #11 0x51b260 in main path/to/libfuzzer/libFuzzer/Fuzzer/./FuzzerMain.cpp:20:10
    #12 0x7f3db68bd82f in __libc_start_main /build/glibc-Cl5G7W/glibc-2.23/csu/../csu/libc-start.c:291

Indirect leak of 32640 byte(s) in 1 object(s) allocated from:
    #0 0x4e2ef8 in __interceptor_malloc /home/ubuntu/llvm/llvm-6.0.0.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:88
    #1 0x7f3db68be44b in __gconv_open /build/glibc-Cl5G7W/glibc-2.23/iconv/gconv_open.c:164
    #2 0x7f3db68bde29 in iconv_open /build/glibc-Cl5G7W/glibc-2.23/iconv/iconv_open.c:71
    #3 0x7f3db7ba9e51 in sav_parse_machine_integer_info_record path/to/ReadStat/src/spss/readstat_sav_read.c:894:29
    #4 0x7f3db7ba4866 in sav_parse_records_pass1 path/to/ReadStat/src/spss/readstat_sav_read.c:1170:30
    #5 0x7f3db7ba31f6 in readstat_parse_sav path/to/ReadStat/src/spss/readstat_sav_read.c:1443:19
    #6 0x51b1a8 in LLVMFuzzerTestOneInput (path/to/ReadStat/src/fuzz/fuzz_format_sav+0x51b1a8)
    #7 0x5258d4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) path/to/libfuzzer/libFuzzer/Fuzzer/./FuzzerLoop.cpp:451:13
    #8 0x525b01 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long) path/to/libfuzzer/libFuzzer/Fuzzer/./FuzzerLoop.cpp:408:3
    #9 0x51b4e1 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) path/to/libfuzzer/libFuzzer/Fuzzer/./FuzzerDriver.cpp:268:6
    #10 0x51e2b8 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) path/to/libfuzzer/libFuzzer/Fuzzer/./FuzzerDriver.cpp:585:9
    #11 0x51b260 in main path/to/libfuzzer/libFuzzer/Fuzzer/./FuzzerMain.cpp:20:10
    #12 0x7f3db68bd82f in __libc_start_main /build/glibc-Cl5G7W/glibc-2.23/csu/../csu/libc-start.c:291

Indirect leak of 208 byte(s) in 1 object(s) allocated from:
    #0 0x4e2ef8 in __interceptor_malloc /home/ubuntu/llvm/llvm-6.0.0.src/projects/compiler-rt/lib/asan/asan_malloc_linux.cc:88
    #1 0x7f3db68c7314 in __gconv_lookup_cache /build/glibc-Cl5G7W/glibc-2.23/iconv/gconv_cache.c:372

SUMMARY: AddressSanitizer: 32960 byte(s) leaked in 3 allocation(s).

INFO: a leak has been found in the initial corpus.

INFO: to ignore leaks on libFuzzer side use -detect_leaks=0.

Infinite Loop

The testcase (see: https://github.com/ChijinZ/security_advisories/blob/master/ReadStat-7bced5b/crash-sas7bcat) caused an infinite loop in src/sas/readstat_sas7bcat_read.c: 288 to 309:

while (next_page > 0 && next_page_pos > 0) {
    if (io->seek(ctx->header_size+(next_page-1)*ctx->page_size+next_page_pos, READSTAT_SEEK_SET, io->io_ctx) == -1) {
        retval = READSTAT_ERROR_SEEK;
        goto cleanup;
    }
    if (io->read(chain_link, sizeof(chain_link), io->io_ctx) < sizeof(chain_link)) {
        retval = READSTAT_ERROR_READ;
        goto cleanup;
    }
    next_page = sas_read4(&chain_link[0], ctx->bswap);
    next_page_pos = sas_read2(&chain_link[4], ctx->bswap);
    chain_link_len = sas_read2(&chain_link[6], ctx->bswap);
    if (buffer_offset + chain_link_len > buffer_len) {
        retval = READSTAT_ERROR_PARSE;
        goto cleanup;
    }
    if (io->read(buffer + buffer_offset, chain_link_len, io->io_ctx) < chain_link_len) {
        retval = READSTAT_ERROR_READ;
        goto cleanup;
    }
    buffer_offset += chain_link_len;
}

libFuzzer provided information as bellow:

==29158== ERROR: libFuzzer: timeout after 121 seconds
    #0 0x4eee23 in __sanitizer_print_stack_trace /home/ubuntu/llvm/llvm-6.0.0.src/projects/compiler-rt/lib/asan/asan_stack.cc:38
    #1 0x524978 in fuzzer::Fuzzer::AlarmCallback() path/to/libfuzzer/libFuzzer/Fuzzer/./FuzzerLoop.cpp:234:7
    #2 0x7f44ed6ca38f  (/lib/x86_64-linux-gnu/libpthread.so.0+0x1138f)
    #3 0x4e19a8 in __asan_memcpy /home/ubuntu/llvm/llvm-6.0.0.src/projects/compiler-rt/lib/asan/asan_interceptors_memintrinsics.cc:23
    #4 0x538e4c in rt_read_handler path/to/ReadStat/src/test/test_buffer_io.c:43:9
    #5 0x7f44edc82cb6 in sas7bcat_read_block path/to/ReadStat/src/sas/readstat_sas7bcat_read.c:304:13
    #6 0x7f44edc8109a in readstat_parse_sas7bcat path/to/ReadStat/src/sas/readstat_sas7bcat_read.c:442:23
    #7 0x51b1a8 in LLVMFuzzerTestOneInput (path/to/ReadStat/src/fuzz/fuzz_format_sas7bcat+0x51b1a8)
    #8 0x5258d4 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) path/to/libfuzzer/libFuzzer/Fuzzer/./FuzzerLoop.cpp:451:13
    #9 0x525b01 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long) path/to/libfuzzer/libFuzzer/Fuzzer/./FuzzerLoop.cpp:408:3
    #10 0x51b4e1 in fuzzer::RunOneTest(fuzzer::Fuzzer*, char const*, unsigned long) path/to/libfuzzer/libFuzzer/Fuzzer/./FuzzerDriver.cpp:268:6
    #11 0x51e2b8 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) path/to/libfuzzer/libFuzzer/Fuzzer/./FuzzerDriver.cpp:585:9
    #12 0x51b260 in main path/to/libfuzzer/libFuzzer/Fuzzer/./FuzzerMain.cpp:20:10
    #13 0x7f44ec9e482f in __libc_start_main /build/glibc-Cl5G7W/glibc-2.23/csu/../csu/libc-start.c:291
    #14 0x41ecc8 in _start (path/to/ReadStat/src/fuzz/fuzz_format_sas7bcat+0x41ecc8)

SUMMARY: libFuzzer: timeout