vstakhov / libucl

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

Segmentation fault in ucl_emitter.c #304

Open gabe-sherman opened 4 months ago

gabe-sherman commented 4 months ago

A segmentation fault occurs in the below program. This behavior occurs at line 272 in ucl_emitter.c.

#include "ucl.h"
#include <stdbool.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <math.h>
typedef uint8_t   u8;   
typedef uint16_t  u16;  
typedef uint32_t  u32;  
typedef uint64_t  u64;
typedef unsigned int usize;
typedef int8_t  i8;
typedef int16_t i16;
typedef int32_t i32;
typedef int64_t i64;
typedef int isize;
typedef float f32;
typedef double f64;
i32 GENERATED_hopper_callback_14(i64 elt, void *ud) {
    return *(i32  *)calloc(1, sizeof(i32 ));
}
int main(int argc, char** argv) {
    enum ucl_type v0 = { 1,  }; // type_
    struct ucl_object_s *v1 = ucl_object_typed_new(1); // obj
    if (v1 == NULL) return 0;
    struct ucl_object_s *v3 = v1; // obj
    enum ucl_emitter v4 = { 2,  }; // emit_type
    u8 v5_tmp[] = {69, 0, }; // file_buf
    u8 *v5 = malloc(sizeof v5_tmp);
    memcpy(v5, v5_tmp, sizeof v5_tmp);
    char* path_v6 = argv[1];
    FILE *f_v6 = fopen(path_v6, "wb");
    fwrite(v5, sizeof v5_tmp, 1, f_v6);
    int v6 = fileno(f_v6); // fd
    struct ucl_emitter_functions *v7; //= ucl_object_emit_fd_funcs(v6); // emitter
    if (v7 == NULL) return 0;
    struct ucl_emitter_functions v9_tmp[] = {{ NULL, NULL, &GENERATED_hopper_callback_14, NULL, NULL, NULL,  }, }; // emitter
    struct ucl_emitter_functions *v9 = malloc(sizeof v9_tmp);
    memcpy(v9, v9_tmp, sizeof v9_tmp);
    v7 = v9;
    struct ucl_emitter_functions *v11 = v7; // emitter
    enum ucl_type v12 = { 2,  }; // type_
    struct ucl_object_s *v13 = ucl_object_typed_new(v12); // obj
    if (v13 == NULL) return 0;
    struct ucl_emitter_context *v16 = ucl_object_emit_streamline_new(v13, v4, v11); // ctx
    if (v16 == NULL) return 0;
    ucl_object_emit_streamline_start_container(v16, v1); // $target
}

Test Environment

Ubuntu 22.04, 64bit

How to trigger

./filename poc

POC File

https://github.com/FuturesLab/POC/blob/main/ucl/hop-poc01

Version

Latest: 084de92f8c7109e89f0ccee6b7ecd463a787cfdd

Address Sanitizer Output

==1628280==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x000000000000 bp 0x7fffffffcfa0 sp 0x7fffffffcc58 T0)
==1628280==Hint: pc points to the zero page.
==1628280==The signal is caused by a READ memory access.
==1628280==Hint: address points to the zero page.
    #0 0x0  (<unknown module>)
    #1 0x5555557a359a in ucl_emit_config_start_array /home/gabesherman/harness_test/AutoHarn-Evaluation/ucl/lib_asan/src/ucl_emitter.c:539:1
    #2 0x55555575a482 in ucl_object_emit_streamline_start_container /home/gabesherman/harness_test/AutoHarn-Evaluation/ucl/lib_asan/src/ucl_emitter_streamline.c:114:4
    #3 0x5555556ae452 in main /home/gabesherman/harness_test/AutoHarn-Results/ucl/hopper-01/reproducer.c:48:5
    #4 0x7ffff7c29d8f in __libc_start_call_main csu/../sysdeps/nptl/libc_start_call_main.h:58:16

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV (<unknown module>) 
==1628280==ABORTING
vstakhov commented 4 months ago

I think this is fp: emitter function can not return this and you have managed to cheat compiler from blaming about incompatible function type by using memcpy.