vstakhov / libucl

Universal configuration library parser
BSD 2-Clause "Simplified" License
1.63k stars 140 forks source link

heap-buffer overflow in ucl_util.c #292

Closed gabe-sherman closed 6 months ago

gabe-sherman commented 6 months ago

A heap-buffer overflow occurs in the below program when provided with malformed input. This behavior occurs at line 3164 in ucl_util.c

#include <stdio.h>
#include <stdarg.h>
#include <string.h>
#include <stdlib.h>
#include "ucl.h"

int main(int argc, char *argv[])
{
    long size;
    FILE *f = fopen(argv[1], "rb");
    fseek(f, 0, SEEK_END);
    size = ftell(f);
    rewind(f);
    unsigned char *data = malloc((size_t)size+1);         
    fread(data, (size_t)size, 1, f);
    data[size] = '\0';

    struct ucl_parser* v0 = ucl_parser_new(UCL_PARSER_DISABLE_MACRO);

    bool v1 = ucl_parser_add_chunk_priority(v0, data, size, 0);
    if (v1 == false) exit(EXIT_FAILURE);

    bool v2 = ucl_parser_insert_chunk(v0, data, size);
    if (v2 == false) exit(EXIT_FAILURE);

    bool v3 = ucl_parser_add_chunk_full(v0, data, size, 0, 0, 0);

    return 0;
}

Test Environment

Ubuntu 22.04, 64bit

How to trigger

./filename poc

Version

Latest: 51c5e2f0526c41efc5e919e0b834a87b1976f33c

Poc File

https://github.com/FuturesLab/POC/blob/main/ucl/poc-12

Address Sanitizer Output

=================================================================
==996467==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000158 at pc 0x55555577262f bp 0x7fffffffaa00 sp 0x7fffffffa9f8
READ of size 8 at 0x602000000158 thread T0
    #0 0x55555577262e in ucl_array_append /home/gabesherman/harness_test/AutoHarn-Evaluation/ucl/lib_asan/src/ucl_util.c:3163:2
    #1 0x5555557064f4 in ucl_parser_get_container /home/gabesherman/harness_test/AutoHarn-Evaluation/ucl/lib_asan/src/ucl_parser.c:1717:8
    #2 0x5555556f0294 in ucl_parse_value /home/gabesherman/harness_test/AutoHarn-Evaluation/ucl/lib_asan/src/ucl_parser.c:1773:10
    #3 0x5555556d2ff5 in ucl_state_machine /home/gabesherman/harness_test/AutoHarn-Evaluation/ucl/lib_asan/src/ucl_parser.c:2539:29
    #4 0x5555556cd8c2 in ucl_parser_add_chunk_full /home/gabesherman/harness_test/AutoHarn-Evaluation/ucl/lib_asan/src/ucl_parser.c:3027:12
    #5 0x5555556ad2a7 in main /home/gabesherman/harness_test/AutoHarn-Results/ucl/autoharn-12/reproducer.c:26:15
    #6 0x7ffff7c29d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16
    #7 0x7ffff7c29e3f in __libc_start_main csu/../csu/libc-start.c:392:3
    #8 0x5555555ef414 in _start (/home/gabesherman/harness_test/AutoHarn-Results/ucl/autoharn-12/reproducer+0x9b414) (BuildId: 9c0c07f1da3fcc0d952c9a9e50fda8685914fe5b)

0x60200000015b is located 0 bytes to the right of 11-byte region [0x602000000150,0x60200000015b)
allocated by thread T0 here:
    #0 0x55555567225e in __interceptor_malloc (/home/gabesherman/harness_test/AutoHarn-Results/ucl/autoharn-12/reproducer+0x11e25e) (BuildId: 9c0c07f1da3fcc0d952c9a9e50fda8685914fe5b)
    #1 0x555555705710 in ucl_copy_or_store_ptr /home/gabesherman/harness_test/AutoHarn-Evaluation/ucl/lib_asan/src/ucl_parser.c:605:10
    #2 0x5555556f51ed in ucl_parse_value /home/gabesherman/harness_test/AutoHarn-Evaluation/ucl/lib_asan/src/ucl_parser.c:1973:20
    #3 0x5555556d2ff5 in ucl_state_machine /home/gabesherman/harness_test/AutoHarn-Evaluation/ucl/lib_asan/src/ucl_parser.c:2539:29
    #4 0x5555556cd8c2 in ucl_parser_add_chunk_full /home/gabesherman/harness_test/AutoHarn-Evaluation/ucl/lib_asan/src/ucl_parser.c:3027:12
    #5 0x5555556ad2a7 in main /home/gabesherman/harness_test/AutoHarn-Results/ucl/autoharn-12/reproducer.c:26:15
    #6 0x7ffff7c29d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16

SUMMARY: AddressSanitizer: heap-buffer-overflow /home/gabesherman/harness_test/AutoHarn-Evaluation/ucl/lib_asan/src/ucl_util.c:3163:2 in ucl_array_append
Shadow bytes around the buggy address:
  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 fa fa fa 00 04 fa fa 00 01 fa fa 00 01
  0x0c047fff8010: fa fa 05 fa fa fa 00 fa fa fa 00 01 fa fa 06 fa
=>0x0c047fff8020: fa fa 07 fa fa fa 00 01 fa fa 00[03]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
  0x0c047fff8070: 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
==996467==ABORTING
vstakhov commented 6 months ago

I believe these changes covers this crash as well.