CVE-2022-32200 (C, published 2022-06-02T14:16Z)
Description: value: libdwarf 0.4.0 has a heap-based buffer over-read in _dwarf_check_string_valid in dwarf_util.c.
Severity: MEDIUM (CVSS v3 base score: 7.8)
Weakness: CWE-125 \u2014 Out-of-bounds Read
The product reads data past the end, or before the beginning, of the intended buffer.
Repository: https://github.com/davea42/libdwarf-code
Files changed:
src/lib/libdwarf/dwarf_global.c
Commit message: Fixes vulnerability DW202205-001
Reports error instead of crashing the when reading
a specially crafted (corrupted) .debug_pubnames
or .debug_pubtypes section.
	modified:   src/lib/libdwarf/dwarf_global.c


Vulnerable code:

    /*  Points to the context for the current set of global names, and
        contains information to identify the compilation-unit that the
        set refers to. */

        if ((pubnames_like_ptr + (DWARF_HALF_SIZE) ) >
            pubnames_like_ptr = pubnames_like_ptr +
                strlen((char *) pubnames_like_ptr) + 1;

Fixed code:
#if 0
/*  Debugging only. Requires start. can calulate one of len, end */
static void
debug_print_range(const char *msg,
    int lineno,
    void *start, signed long len,
    void *end)
{

    char *st = (char *)start;
    char *en = (char *)end;
    signed long le = len;

    if (len) {
        if (en) {
            le = (long)(en-st);
        } else {
            en= start+len;
        }
    } else if (en) {
        le = (long)(en-st);
    }
    printf("RANGEdebug %s  st=0x%lx le=%ld en=0x%lx line %d\n",
        msg,(unsigned long)st,le,(unsigned long)en,lineno);
}
#endif

    /*  Points to the context for the current set of global names,
        and contains information to identify the compilation-unit
        that the set refers to. */
    /*  The count is just to improve the error message
        a few lines above. */
    Dwarf_Unsigned context_count = 0;

        {
            Dwarf_Small * localend =pubnames_like_ptr + length;

            if ((length > section_length) ||
                (localend > section_end_ptr)){
                /*  The length field  is corrupted */
                dwarfstring m;

                dwarfstring_constructor(&m);
                dwarfstring_append_printf_u(&m,
                    "DW_DLE_PUBNAMES_LENGTH_BAD (or similar) "
                    "A DWARF length field in cu context %u ",
                    context_count);
                dwarfstring_append_printf_s(&m,"of section %s ",
                    (char *)secname);
                dwarfstring_append_printf_u(&m,"of "
                    "%u bytes ",length);
                dwarfstring_append_printf_u(&m,
                    "runs off the end of "
                    "the %u bytes of the real section",
                    section_length);
                _dwarf_error_string(dbg, error,length_err_num,
                    dwarfstring_string(&m));
                dwarfstring_destructor(&m);
                dealloc_globals_chain(dbg,head_chain);
                if (!pubnames_context_on_list) {
                    dwarf_dealloc(dbg,pubnames_context,
                        context_DLA_code);
                }
                return DW_DLV_ERROR;
            }
        }
        /*  The count is just to improve the error message
            a few lines above. */
        ++context_count;
        if ((pubnames_like_ptr + (DWARF_HALF_SIZE) ) >=
            Dwarf_Unsigned nstrlen = 0;
            nstrlen = strlen((char *)pubnames_like_ptr);
            pubnames_like_ptr += nstrlen + 1;