Skip to content

SEGV in ucl_object_emit with crafted input in ZEROCOPY mode #323

@zakkanijia

Description

@zakkanijia

Description

A SEGV fault occurs in ucl_object_emit when parsing and emitting an object created in UCL_PARSER_ZEROCOPY mode, if the input UCL contains a key with an embedded null byte (\u0000).

Tested on :

libucl version: Latest commit [3e7f023](https://github.com/vstakhov/libucl/commit/3e7f023e184e06f30fb5792dacd9dd0f8b692f1b)

Reproduction

Given the following input file poc_input.ucl:

"AAAAA\u0000BBBB": "testvalue"

And the following driver:

#include <stdio.h>
#include <ucl.h>

int main() {
    struct ucl_parser *parser = ucl_parser_new(UCL_PARSER_ZEROCOPY);

    if (!ucl_parser_add_file(parser, "poc_input.ucl")) {
        fprintf(stderr, "Parse error: %s\n", ucl_parser_get_error(parser));
        return 1;
    }

    ucl_object_t *obj = ucl_parser_get_object(parser);
    if (obj) {
        char *out = ucl_object_emit(obj, UCL_EMIT_JSON);
        printf("Parsed object: %s\n", out);
        free(out);
        ucl_object_unref(obj);
    }

    ucl_parser_free(parser);
    return 0;
}

Compiling with AddressSanitizer and running leads to the following crash:

AddressSanitizer:DEADLYSIGNAL
=================================================================
==609527==ERROR: AddressSanitizer: SEGV on unknown address 0x72da8cca0014 (pc 0x0000004cc866 bp 0x7fff7e069a10 sp 0x7fff7e069830 T0)
==609527==The signal is caused by a READ memory access.
    #0 0x4cc866 in ucl_elt_string_write_json /libucl/src/ucl_emitter_utils.c:112:7
    #1 0x4c8f48 in ucl_emitter_common_elt /libucl/src/ucl_emitter.c:467:4
    #2 0x4cb5bc in ucl_emitter_common_start_object /libucl/src/ucl_emitter.c:370:5
    #3 0x4c91c6 in ucl_emitter_common_elt /libucl/src/ucl_emitter.c:477:3
    #4 0x4c632c in ucl_emit_json_elt /libucl/src/ucl_emitter.c:537:1
    #5 0x4c787f in ucl_object_emit_full /libucl/src/ucl_emitter.c:709:3
    #6 0x4c7411 in ucl_object_emit_len /libucl/src/ucl_emitter.c:680:3
    #7 0x4c723e in ucl_object_emit /libucl/src/ucl_emitter.c:661:9
    #8 0x4c6231 in main /libucl/tests/fuzzers/ucl_poc.c:17:21
    #9 0x72da8ca29d8f in __libc_start_call_main ../sysdeps/nptl/libc_start_call_main.h:58:16
    #10 0x72da8ca29e3f in __libc_start_main ../csu/libc-start.c:392:3
    #11 0x41e3b4 in _start (/libucl/ucl_poc+0x41e3b4)

AddressSanitizer can not provide additional info.
SUMMARY: AddressSanitizer: SEGV /libucl/src/ucl_emitter_utils.c:112:7 in ucl_elt_string_write_json
==609527==ABORTING

Notes

  • This issue only triggers when using UCL_PARSER_ZEROCOPY.
  • The embedded null byte in the key is not handled correctly during emission.
  • The bug occurs in ucl_elt_string_write_json, which assumes the key is a valid null-terminated C string.

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