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

Lexer heap buffer overflow #1191

Closed
rol1510 opened this issue Jan 17, 2024 · 4 comments
Closed

Lexer heap buffer overflow #1191

rol1510 opened this issue Jan 17, 2024 · 4 comments
Assignees
Milestone

Comments

@rol1510
Copy link
Contributor

rol1510 commented Jan 17, 2024

Found this heap-buffer-overflow while working on the fuzzer ci.

Steps to reproduce:

  1. Build the quick-lint-js fuzzers with CC=clang CXX=clang++ CFLAGS="-fsanitize=address,undefined -stdlib=libstdc++" CXXFLAGS=-fsanitize=address,undefined cmake -G Ninja -DCMAKE_BUILD_TYPE=Release ..
  2. create the empty directory "corpus"
  3. Download this file crash.txt and place it in the corpus directory.
  4. run ./build-fuzz/fuzz/quick-lint-js-fuzz-lex corpus/
  5. You should see the following ASAN message:
==1644==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x621000002507 at pc 0x55be9eea0c1f bp 0x7fffbc794530 sp 0x7fffbc794528
READ of size 16 at 0x621000002507 thread T0
    #0 0x55be9eea0c1e in quick_lint_js::Keyword_Lexer::key_strings_equal(char8_t const*, char8_t const*, unsigned long) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x1b3c1e) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #1 0x55be9eea03ee in quick_lint_js::Lexer::identifier_token_type(std::basic_string_view<char8_t, std::char_traits<char8_t> >) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x1b33ee) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #2 0x55be9ee5aad7 in quick_lint_js::Lexer::try_parse_current_token() (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x16dad7) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #3 0x55be9ee57fde in quick_lint_js::Lexer::parse_current_token() (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x16afde) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #4 0x55be9ee26d47 in LLVMFuzzerTestOneInput (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x139d47) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #5 0x55be9ed59b53 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x6cb53) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #6 0x55be9ed59279 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x6c279) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #7 0x55be9ed5ac08 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile> >&) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x6dc08) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #8 0x55be9ed5b0f2 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile> >&) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x6e0f2) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #9 0x55be9ed49cf2 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x5ccf2) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #10 0x55be9ed729f2 in main (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x859f2) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #11 0x7ff3dd9781c9  (/lib/x86_64-linux-gnu/libc.so.6+0x271c9) (BuildId: 51657f818beb1ae70372216a99b7412b8a100a20)
    #12 0x7ff3dd978284 in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x27284) (BuildId: 51657f818beb1ae70372216a99b7412b8a100a20)
    #13 0x55be9ed3e900 in _start (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x51900) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)

0x621000002507 is located 7 bytes to the right of 4096-byte region [0x621000001500,0x621000002500)
allocated by thread T0 here:
    #0 0x55be9ee2450d in operator new(unsigned long) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x13750d) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #1 0x55be9eea3f6d in quick_lint_js::Flexible_Array<char, quick_lint_js::Linked_Bump_Allocator::Chunk_Header>* quick_lint_js::Flexible_Array<char, quick_lint_js::Linked_Bump_Allocator::Chunk_Header>::allocate_and_construct_header<quick_lint_js::Flexible_Array<char, quick_lint_js::Linked_Bump_Allocator::Chunk_Header>*&>(quick_lint_js::Memory_Resource*, unsigned long, quick_lint_js::Flexible_Array<char, quick_lint_js::Linked_Bump_Allocator::Chunk_Header>*&) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x1b6f6d) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #2 0x55be9eea3d5b in quick_lint_js::Linked_Bump_Allocator::append_chunk(unsigned long, unsigned long) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x1b6d5b) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #3 0x55be9eea3a27 in quick_lint_js::Linked_Bump_Allocator::allocate_bytes(unsigned long, unsigned long) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x1b6a27) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #4 0x55be9ee6e8b9 in quick_lint_js::Lexer::parse_identifier_slow(char8_t const*, char8_t const*, quick_lint_js::Lexer::Identifier_Kind) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x1818b9) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #5 0x55be9ee622fc in quick_lint_js::Lexer::parse_identifier(char8_t const*, quick_lint_js::Lexer::Identifier_Kind) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x1752fc) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #6 0x55be9ee66126 in quick_lint_js::Lexer::reparse_as_regexp() (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x179126) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #7 0x55be9ee629b8 in quick_lint_js::Lexer::test_for_regexp(char8_t const*) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x1759b8) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #8 0x55be9ee5c76c in quick_lint_js::Lexer::try_parse_current_token() (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x16f76c) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #9 0x55be9ee57fca in quick_lint_js::Lexer::parse_current_token() (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x16afca) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #10 0x55be9ee26d47 in LLVMFuzzerTestOneInput (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x139d47) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #11 0x55be9ed59b53 in fuzzer::Fuzzer::ExecuteCallback(unsigned char const*, unsigned long) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x6cb53) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #12 0x55be9ed59279 in fuzzer::Fuzzer::RunOne(unsigned char const*, unsigned long, bool, fuzzer::InputInfo*, bool, bool*) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x6c279) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #13 0x55be9ed5ac08 in fuzzer::Fuzzer::ReadAndExecuteSeedCorpora(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile> >&) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x6dc08) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #14 0x55be9ed5b0f2 in fuzzer::Fuzzer::Loop(std::vector<fuzzer::SizedFile, std::allocator<fuzzer::SizedFile> >&) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x6e0f2) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #15 0x55be9ed49cf2 in fuzzer::FuzzerDriver(int*, char***, int (*)(unsigned char const*, unsigned long)) (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x5ccf2) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #16 0x55be9ed729f2 in main (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x859f2) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4)
    #17 0x7ff3dd9781c9  (/lib/x86_64-linux-gnu/libc.so.6+0x271c9) (BuildId: 51657f818beb1ae70372216a99b7412b8a100a20)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/mnt/g/repos/quick-lint-js/build-fuzz/fuzz/quick-lint-js-fuzz-lex+0x1b3c1e) (BuildId: 2608e54ff4ea687b215dde8163c80509c663dcf4) in quick_lint_js::Keyword_Lexer::key_strings_equal(char8_t const*, char8_t const*, unsigned long)
Shadow bytes around the buggy address:
  0x0c427fff8450: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fff8460: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fff8470: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fff8480: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x0c427fff8490: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x0c427fff84a0:[fa]fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fff84b0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fff84c0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fff84d0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fff84e0: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x0c427fff84f0: 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
==1644==ABORTING
MS: 0 ; base unit: 0000000000000000000000000000000000000000
0x11,0x47,0x2a,0x2a,0x2f,0x5c,0x75,0x5c,0x2a,0x47,0x2a,0x2a,0x2f,0x5c,0x75,0x5c,0x2a,0x2f,0x5c,0x75,0x5c,0x2a,0x2f,0x5c,0x75,0x5c,0x2a,0x47,0x2a,0x2a,0x2f,0x5c,0x75,0x5c,0x2a,0x2f,0x5c,0x75,0x5c,0x75,0x2a,0x2a,0x2f,0x38,0x3c,0x0,0x0,0x0,0x75,0x2a,0x2f,0x5c,0x75,0x0,0x0,0x2f,0x5c,0x75,0x5c,0x75,0x0,0x0,0x0,0x0,0x0,0x0,0x2a,0x2a,0x2f,0x36,0x2f,0x5c,0x75,0x5c,0x75,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x2a,0x2f,0x5c,0x75,0x5c,0x2a,0x47,0x2a,0x2a,0x2f,0x5c,0x75,0x5c,0x2a,0x2f,0x5c,0x75,0x5c,0x75,0x2a,0x2a,0x2f,0x38,0x3c,0x0,0x0,0x0,0x75,0x2a,0x2f,0x5c,0x75,0x0,0x0,0x75,0x2a,0x2f,0x5c,0x75,0x0,0x0,0x2f,0x5c,0x75,0x5c,0x75,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x75,0x2a,0x2a,0x2f,0x38,0x71,0x2a,0x2f,0x34,0x71,
\021G**/\\u\\*G**/\\u\\*/\\u\\*/\\u\\*G**/\\u\\*/\\u\\u**/8<\000\000\000u*/\\u\000\000/\\u\\u\000\000\000\000\000\000**/6/\\u\\u\377\377\377\377\377\377\377\377\377\377\377*/\\u\\*G**/\\u\\*/\\u\\u**/8<\000\000\000u*/\\u\000\000u*/\\u\000\000/\\u\\uUUUUUUUUUUUu**/8q*/4q
artifact_prefix='./'; Test unit written to ./crash-fd5dfa97fcd291bce68ca883e5c43217ec3a0508
Base64: EUcqKi9cdVwqRyoqL1x1XCovXHVcKi9cdVwqRyoqL1x1XCovXHVcdSoqLzg8AAAAdSovXHUAAC9cdVx1AAAAAAAAKiovNi9cdVx1//////////////8qL1x1XCpHKiovXHVcKi9cdVx1KiovODwAAAB1Ki9cdQAAdSovXHUAAC9cdVx1VVVVVVVVVVVVVVV1KiovOHEqLzRx
@rol1510
Copy link
Contributor Author

rol1510 commented Jan 17, 2024

./quick-lint-js crash.txt works. Only the fuzzer is affected.

@strager
Copy link
Collaborator

strager commented Feb 25, 2024

Thanks for reporting! There is a real bug which affects the main program as well.

@strager strager self-assigned this Feb 25, 2024
@strager strager added this to the 3.2 milestone Feb 25, 2024
@strager
Copy link
Collaborator

strager commented Feb 25, 2024

Fixed in Git commit 02a1c89.

@strager strager closed this as completed Feb 25, 2024
@strager
Copy link
Collaborator

strager commented Mar 4, 2024

Fix released in version 3.2.0.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants