Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

heap-buffer overflow #16

Closed
dimbleby opened this issue Dec 29, 2020 · 1 comment · Fixed by #17
Closed

heap-buffer overflow #16

dimbleby opened this issue Dec 29, 2020 · 1 comment · Fixed by #17
Labels
bug Something isn't working

Comments

@dimbleby
Copy link
Contributor

I thought I'd see how this parser handled being fuzzed. I didn't get very far: it looks as though every file provokes invalid memory access! The pointer being dereferenced here is not valid.

Certainly the empty file is sufficient to provoke this error.

==21234==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6020000000ee at pc 0x00000057f42f bp 0x7ffe873e9090 sp 0x7ffe873e9088
READ of size 2 at 0x6020000000ee thread T0
    #0 0x57f42e in (anonymous namespace)::Scanner::scan(TSLexer*, bool const*) /data/developer/tree-sitter/test/fixtures/grammars/yaml/src/scanner.cc:660:23
    #1 0x5c42bd in ts_parser__lex (/data/developer/tree-sitter/out/yaml_fuzzer+0x5c42bd)
    #2 0x5ae757 in ts_parser__advance (/data/developer/tree-sitter/out/yaml_fuzzer+0x5ae757)
    #3 0x5a838c in ts_parser_parse (/data/developer/tree-sitter/out/yaml_fuzzer+0x5a838c)
    #4 0x5b9d52 in ts_parser_parse_string_encoding (/data/developer/tree-sitter/out/yaml_fuzzer+0x5b9d52)
    #5 0x5b9a13 in ts_parser_parse_string (/data/developer/tree-sitter/out/yaml_fuzzer+0x5b9a13)
    #6 0x5751da in LLVMFuzzerTestOneInput (/data/developer/tree-sitter/out/yaml_fuzzer+0x5751da)
    #7 0x42fe1f in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/data/developer/tree-sitter/out/yaml_fuzzer+0x42fe1f)
    #8 0x43424f in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::vector<std::string, fuzzer::fuzzer_allocator<std::string> > const&) (/data/developer/tree-sitter/out/yaml_fuzzer+0x43424f)
    #9 0x434748 in fuzzer::Fuzzer::Loop(std::vector<std::string, fuzzer::fuzzer_allocator<std::string> > const&) (/data/developer/tree-sitter/out/yaml_fuzzer+0x434748)
    #10 0x429535 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/data/developer/tree-sitter/out/yaml_fuzzer+0x429535)
    #11 0x41ebb2 in main (/data/developer/tree-sitter/out/yaml_fuzzer+0x41ebb2)
    #12 0x7f88680be554 in __libc_start_main (/lib64/libc.so.6+0x22554)
    #13 0x41ebdd in _start (/data/developer/tree-sitter/out/yaml_fuzzer+0x41ebdd)

0x6020000000ee is located 2 bytes to the left of 2-byte region [0x6020000000f0,0x6020000000f2)
allocated by thread T0 here:
    #0 0x570818 in operator new(unsigned long) (/data/developer/tree-sitter/out/yaml_fuzzer+0x570818)
    #1 0x594910 in void std::vector<short, std::allocator<short> >::_M_realloc_insert<short>(__gnu_cxx::__normal_iterator<short*, std::vector<short, std::allocator<short> > >, short&&) /opt/rh/devtoolset-8/root/usr/lib/gcc/x86_64-redhat-li
nux/8/../../../../include/c++/8/bits/vector.tcc:427:33
    #2 0x579d89 in (anonymous namespace)::Scanner::deserialize(char const*, unsigned int) /data/developer/tree-sitter/test/fixtures/grammars/yaml/src/scanner.cc:175:17
    #3 0x578d04 in (anonymous namespace)::Scanner::Scanner() /data/developer/tree-sitter/test/fixtures/grammars/yaml/src/scanner.cc:145:5
    #4 0x578c39 in tree_sitter_yaml_external_scanner_create /data/developer/tree-sitter/test/fixtures/grammars/yaml/src/scanner.cc:946:14
    #5 0x59eb7b in ts_parser_set_language (/data/developer/tree-sitter/out/yaml_fuzzer+0x59eb7b)
    #6 0x5750f1 in LLVMFuzzerTestOneInput (/data/developer/tree-sitter/out/yaml_fuzzer+0x5750f1)
    #7 0x42fe1f in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/data/developer/tree-sitter/out/yaml_fuzzer+0x42fe1f)
    #8 0x43424f in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::vector<std::string, fuzzer::fuzzer_allocator<std::string> > const&) (/data/developer/tree-sitter/out/yaml_fuzzer+0x43424f)
    #9 0x434748 in fuzzer::Fuzzer::Loop(std::vector<std::string, fuzzer::fuzzer_allocator<std::string> > const&) (/data/developer/tree-sitter/out/yaml_fuzzer+0x434748)
    #10 0x429535 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/data/developer/tree-sitter/out/yaml_fuzzer+0x429535)
    #11 0x41ebb2 in main (/data/developer/tree-sitter/out/yaml_fuzzer+0x41ebb2)
    #12 0x7f88680be554 in __libc_start_main (/lib64/libc.so.6+0x22554)

SUMMARY: AddressSanitizer: heap-buffer-overflow /data/developer/tree-sitter/test/fixtures/grammars/yaml/src/scanner.cc:660:23 in (anonymous namespace)::Scanner::scan(TSLexer*, bool const*)
Shadow bytes around the buggy address:
  0x0c047fff7fc0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fd0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7fe0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff7ff0: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c047fff8000: fa fa 00 00 fa fa 00 fa fa fa 00 fa fa fa fd fa
=>0x0c047fff8010: fa fa 00 00 fa fa 01 fa fa fa 02 fa fa[fa]02 fa
  0x0c047fff8020: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8030: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8040: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8050: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c047fff8060: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
  Shadow gap:              cc
==21234==ABORTING
@dimbleby
Copy link
Contributor Author

I don't understand the code to know whether this is what's wanted, but the following fix certainly sidesteps the issue, and doesn't immediately fall over...

-    int16_t prt_ind = *ind_ptr;
+    int16_t prt_ind = ind_len_stk.size() > 1 ? *ind_ptr : 0;

@ikatyang ikatyang added the bug Something isn't working label Jan 1, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging a pull request may close this issue.

2 participants