Skip to content

[Bug] Heap-buffer-overflow (Underflow) in patch_line_end during error reporting #382

@oneafter

Description

@oneafter

Description

We discovered a Heap-buffer-overflow vulnerability in the Lily interpreter. The crash occurs in the patch_line_end function, which is invoked when the interpreter attempts to generate an error message/traceback.

The ASAN report indicates a READ violation of size 1, occurring 1 byte before an allocated heap region (Buffer Underflow).

Environment

  • OS: Linux x86_64
  • Complier: Clang
  • Build Configuration: Release mode with ASan enabled.

Vulnerability Details

  • Target: Lily (jcowgar/lily)
  • Vulnerability Type: CWE-125: Out-of-bounds Read (Underflow)
  • Function: patch_line_end
  • Location: src/lily_build_error.c:108
  • Root Cause Analysis: The crash happens within the error handling subsystem (lily_error_message -> add_context -> patch_line_end).
    The function patch_line_end likely attempts to trim trailing characters (like newlines) from a string buffer allocated in lily_new_lex_state. The ASAN report shows an access at offset -1 (1 byte before the region). This suggests the code performs a check similar to if (buffer[pos - 1] == ...) without verifying that pos > 0 or ptr > buffer_start. This creates a crash scenario specifically when an error occurs on an empty line or at the very beginning of a buffer.

Reproduce

  1. Build lily with Release optimization and ASAN enabled.
  2. Run with the crashing file:
./build/lily repro.lily
ASAN report
==3025==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x50c0000001bf at pc 0x55ea2798ed54 bp 0x7ffe900ddab0 sp 0x7ffe900ddaa8
READ of size 1 at 0x50c0000001bf thread T0
    #0 0x55ea2798ed53 in patch_line_end /src/lily/src/lily_build_error.c:108:9
    #1 0x55ea2798ed53 in add_context /src/lily/src/lily_build_error.c:136:5
    #2 0x55ea2798ed53 in add_frontend_trace /src/lily/src/lily_build_error.c:182:9
    #3 0x55ea2798ed53 in build_error /src/lily/src/lily_build_error.c:225:13
    #4 0x55ea2798ed53 in lily_error_message /src/lily/src/lily_build_error.c:259:5
    #5 0x55ea2797944e in main /src/lily/run/lily.c:106:15
    #6 0x7efcf0d171c9  (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
    #7 0x7efcf0d1728a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
    #8 0x55ea27897624 in _start (/src/lily/build_afl/lily+0x4f624) (BuildId: ec5f784cf13dad836217a07e33a2c98d8b7f8bb4)

0x50c0000001bf is located 1 bytes before 128-byte region [0x50c0000001c0,0x50c000000240)
allocated by thread T0 here:
    #0 0x55ea27937453 in malloc (/src/lily/build_afl/lily+0xef453) (BuildId: ec5f784cf13dad836217a07e33a2c98d8b7f8bb4)
    #1 0x55ea2797b533 in lily_malloc /src/lily/src/lily_alloc.c:5:20
    #2 0x55ea279dbca6 in lily_new_lex_state /src/lily/src/lily_lexer.c:40:19
    #3 0x55ea279fb8cf in lily_new_state /src/lily/src/lily_parser.c:190:19
    #4 0x55ea2797930f in main /src/lily/run/lily.c:90:25
    #5 0x7efcf0d171c9  (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
    #6 0x7efcf0d1728a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
    #7 0x55ea27897624 in _start (/src/lily/build_afl/lily+0x4f624) (BuildId: ec5f784cf13dad836217a07e33a2c98d8b7f8bb4)

SUMMARY: AddressSanitizer: heap-buffer-overflow /src/lily/src/lily_build_error.c:108:9 in patch_line_end
Shadow bytes around the buggy address:
  0x50bfffffff00: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x50bfffffff80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x50c000000000: fa fa fa fa fa fa fa fa 00 00 00 00 00 00 00 00
  0x50c000000080: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa
  0x50c000000100: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
=>0x50c000000180: fa fa fa fa fa fa fa[fa]00 00 00 00 00 00 00 00
  0x50c000000200: 00 00 00 00 00 00 00 00 fa fa fa fa fa fa fa fa
  0x50c000000280: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
  0x50c000000300: fa fa fa fa fa fa fa fa fd fd fd fd fd fd fd fd
  0x50c000000380: fd fd fd fd fd fd fd fd fa fa fa fa fa fa fa fa
  0x50c000000400: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
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
==3025==ABORTING

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions