Skip to content

[Bug] Heap-buffer-overflow in count_transforms during closure transformation #381

@oneafter

Description

@oneafter

Description

We discovered a Heap-buffer-overflow vulnerability in the Lily interpreter. The crash occurs in count_transforms when the emitter is performing closure transformation (perform_closure_transform).

The ASAN report indicates a READ violation of size 2 (reading a uint16), occurring 68 bytes past a small (16-byte) heap allocation.

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
  • Function: count_transforms
  • Location: src/lily_emitter.c:1341 (called by perform_closure_transform at line 1565)
  • Root Cause Analysis: The function count_transforms likely iterates over bytecode or a list of upvalues/transforms.
// src/lily_emitter.c:1341
// Likely reading a uint16 opcode or index
uint16_t value = buffer[index];

The ASAN report shows the access is significantly out of bounds (68 bytes after a 16-byte region). This suggests that count_transforms is either iterating way past the end of the bytecode buffer, or it is using an invalid index derived from a corrupted state during the closure analysis phase. The small allocation size (16 bytes) suggests the buffer might have been reallocated or is a small temporary array that wasn't sized correctly for the number of transforms being processed.

Reproduce

  1. Build lily with Release optimization and ASAN enabled.
  2. Run with the crashing file:
./build/lily repro.lily
ASAN report
==10063==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x5020000011a4 at pc 0x5605928c903c bp 0x7ffe36d54bb0 sp 0x7ffe36d54ba8
READ of size 2 at 0x5020000011a4 thread T0
    #0 0x5605928c903b in count_transforms /src/lily/src/lily_emitter.c:1341:17
    #1 0x5605928c903b in perform_closure_transform /src/lily/src/lily_emitter.c:1565:33
    #2 0x5605928c903b in finish_block_code /src/lily/src/lily_emitter.c:820:9
    #3 0x5605928caa37 in lily_emit_leave_lambda_block /src/lily/src/lily_emitter.c:908:5
    #4 0x560592928388 in lily_parser_lambda_eval /src/lily/src/lily_parser.c:3450:5
    #5 0x5605928d4cf7 in eval_lambda_to_parse /src/lily/src/lily_emitter.c:3002:31
    #6 0x5605928d4cf7 in eval_tree /src/lily/src/lily_emitter.c:4878:9
    #7 0x5605928ea49d in eval_call_arg /src/lily/src/lily_emitter.c:4014:5
    #8 0x5605928e3e54 in run_call /src/lily/src/lily_emitter.c:4161:13
    #9 0x5605928e3e54 in eval_call /src/lily/src/lily_emitter.c:4377:5
    #10 0x5605928cfe46 in eval_tree /src/lily/src/lily_emitter.c
    #11 0x5605928cece6 in lily_eval_expr /src/lily/src/lily_emitter.c:4906:5
    #12 0x560592932339 in parser_loop /src/lily/src/lily_parser.c:5950:17
    #13 0x560592930be9 in lily_parse_content /src/lily/src/lily_parser.c:6562:9
    #14 0x5605928a137e in main /src/lily/run/lily.c:103:18
    #15 0x7fd6958491c9  (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
    #16 0x7fd69584928a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
    #17 0x5605927bf624 in _start (/src/lily/build_afl/lily+0x4f624) (BuildId: ec5f784cf13dad836217a07e33a2c98d8b7f8bb4)

0x5020000011a4 is located 68 bytes after 16-byte region [0x502000001150,0x502000001160)
allocated by thread T0 here:
    #0 0x56059285f870 in realloc (/src/lily/build_afl/lily+0xef870) (BuildId: ec5f784cf13dad836217a07e33a2c98d8b7f8bb4)
    #1 0x5605928a35e5 in lily_realloc /src/lily/src/lily_alloc.c:14:20
    #2 0x5605928b3a54 in lily_u16_write_2 /src/lily/src/lily_buffer_u16.c:31:19
    #3 0x5605928c6e53 in perform_closure_transform /src/lily/src/lily_emitter.c:1458:5
    #4 0x5605928c6e53 in finish_block_code /src/lily/src/lily_emitter.c:820:9
    #5 0x5605928caa37 in lily_emit_leave_lambda_block /src/lily/src/lily_emitter.c:908:5
    #6 0x560592928388 in lily_parser_lambda_eval /src/lily/src/lily_parser.c:3450:5
    #7 0x5605928d4cf7 in eval_lambda_to_parse /src/lily/src/lily_emitter.c:3002:31
    #8 0x5605928d4cf7 in eval_tree /src/lily/src/lily_emitter.c:4878:9
    #9 0x5605928ea49d in eval_call_arg /src/lily/src/lily_emitter.c:4014:5
    #10 0x5605928e3e54 in run_call /src/lily/src/lily_emitter.c:4161:13
    #11 0x5605928e3e54 in eval_call /src/lily/src/lily_emitter.c:4377:5
    #12 0x5605928cfe46 in eval_tree /src/lily/src/lily_emitter.c
    #13 0x5605928cece6 in lily_eval_expr /src/lily/src/lily_emitter.c:4906:5
    #14 0x560592932339 in parser_loop /src/lily/src/lily_parser.c:5950:17
    #15 0x560592930be9 in lily_parse_content /src/lily/src/lily_parser.c:6562:9
    #16 0x5605928a137e in main /src/lily/run/lily.c:103:18
    #17 0x7fd6958491c9  (/lib/x86_64-linux-gnu/libc.so.6+0x2a1c9) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
    #18 0x7fd69584928a in __libc_start_main (/lib/x86_64-linux-gnu/libc.so.6+0x2a28a) (BuildId: 274eec488d230825a136fa9c4d85370fed7a0a5e)
    #19 0x5605927bf624 in _start (/src/lily/build_afl/lily+0x4f624) (BuildId: ec5f784cf13dad836217a07e33a2c98d8b7f8bb4)

SUMMARY: AddressSanitizer: heap-buffer-overflow /src/lily/src/lily_emitter.c:1341:17 in count_transforms
Shadow bytes around the buggy address:
  0x502000000f00: fa fa 00 03 fa fa 00 fa fa fa 00 03 fa fa 00 00
  0x502000000f80: fa fa 00 00 fa fa 00 00 fa fa 00 fa fa fa 00 01
  0x502000001000: fa fa 00 01 fa fa 00 00 fa fa 02 fa fa fa 05 fa
  0x502000001080: fa fa 00 02 fa fa 00 00 fa fa 00 00 fa fa 00 00
  0x502000001100: fa fa fd fd fa fa 00 02 fa fa 00 00 fa fa fa fa
=>0x502000001180: fa fa fa fa[fa]fa fa fa fa fa fa fa fa fa fa fa
  0x502000001200: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x502000001280: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x502000001300: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x502000001380: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x502000001400: 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
==10063==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