Security
Headlines
HeadlinesLatestCVEs

Headline

CVE-2021-44974: CENSUS | IT Security Works

radareorg radare2 version 5.5.2 is vulnerable to NULL Pointer Dereference via libr/bin/p/bin_symbols.c binary symbol parser.

CVE
#vulnerability#mac#buffer_overflow

POSTED BY: Angelos T. Kalaitzidis / 24.05.2022

Multiple vulnerabilities in radare2

CENSUS identified a number of NULL pointer dereference and Heap buffer overflow bugs in the radare2 project code. Radare2 is a popular reverse engineering framework. CENSUS has verified that release 5.6.0 of radare2 carries the appropriate fixes to remediate all of the identified issues.

CVE-2022-0419 Vulnerability Details

Function load_buffer of radare2/libr/bin/p/bin_xnu_kernelcache.c uses a pointer (obj) which remains initialized to NULL, when a call to function get_prelink_info_range_from_mach0() fails (i.e. returns NULL). The code snippet below shows this problematic code path:

static bool load_buffer(RBinFile *bf, void **bin_obj, RBuffer *buf, ut64 loadaddr, Sdb *sdb) {
    ...
189 RKernelCacheObj *obj = NULL; // 1

191 RPrelinkRange *prelink_range = get_prelink_info_range_from_mach0 (main_mach0);
192 if (!prelink_range) {
193     goto beach;              // 2
194 }
....
243 beach:
244 r_buf_free (fbuf);
245 obj->cache_buf = NULL;       // 3
244 MACH0_(mach0_free) (main_mach0);
245 return false;

When get_prelink_info_range_from_mach0() returns NULL, obj remains NULL and the code branches to line 243. There an access to the obj pointer is made on line 245, resulting to a NULL pointer dereference and a program crash.

The issue has been patched in version 5.6.0 of radare2.

CVE-2021-44975 Vulnerability Details

The objc_build_refs function is responsible for building the references of a mach-o file as its name suggests. The function can be found out at /radare2/libr/core/anal_objc.c

static bool objc_build_refs(RCoreObjc *objc) {
    ...

    size_t ss_selrefs = objc->_selrefs->vsize;

    size_t maxsize = R_MAX (ss_const, ss_selrefs); // 1
    maxsize = R_MIN (maxsize, objc->file_size);    

    ut8 *buf = calloc (1, maxsize);                
    if (!buf) {
        return false;
    }

    ...
    if (!r_io_read_at (objc->core->io, va_selrefs, buf, ss_selrefs)) { // 2
        eprintf ("aao: Cannot read the whole selrefs section\n");
        return false;
    }
    ...
    free (buf);
    return true;
}

At comment #1 the maxsize quantity is calculated based on the largest value between ss_const and ss_selrefs (see R_MAX macro). Lets consider that the largest of the two is ss_selrefs. Then maxsize is recalculated based on the lowest value (see R_MIN macro) between the previously calculated maxsize and objc->file_size. Therefore, there may be a case where ss_selrefs will be greater than objc->file_size and in that case maxsize will be equal to objc->file_size.

In the above case, buffer buf is dynamically allocated with maxsize (i.e. objc->file_size) bytes. However the r_io_read_at() operation at comment #2 will copy ss_selrefs bytes to the buffer, resulting to a heap buffer overflow as ss_selrefs would be greater than objc->file_size.

A similar vulnerability also exists in other code of the same function:

    size_t ss_const = objc->_const->vsize;
....
    if (!r_io_read_at (objc->core->io, objc->_const->vaddr, buf, ss_const)) {
        eprintf ("aao: Cannot read the whole const section %zu\n", ss_const);
        return false;
    }

Again, ss_const can be greater than objc->file_size resulting to a heap buffer overflow.

Version 5.6.0 of radare2 comes with the appropriate fix for these issues.

CVE-2021-44974 Vulnerability Details

A NULL pointer dereference vulnerability exists in the symbols() function of /radare2/libr/bin/bin_symbols.c.

static RList *symbols(RBinFile *bf) {
    RCoreSymCacheElement *element = bf->o->bin_obj;
    ...
    // Parse symbols to a hash table
    for (i = 0; i < element->hdr->n_symbols; i++) {
        RCoreSymCacheElementSymbol *sym = &element->symbols[i]; // 1
        ht_uu_find (hash, sym->paddr, &found);                  
        if (found) {
            continue;
        }
        RBinSymbol *s = bin_symbol_from_symbol (element, sym);
        if (s) {
            r_list_append (res, s);
        }
    }
    ht_uu_free (hash);
    return res;
}

As illustrated in the code snippet above, the element pointer points to adversary-controlled data (as bf->o->bin_obj essentially points to data of the binary file). The element->symbols array, is an array of symbols for an object of the file that is being loaded for analysis. In the case where the pointer element->symbols[0] is NULL (which is possible as we are talking about adversary-controlled data) the sym pointer would also be set to NULL (see comment #1). Then in the next line sym is accessed through the sym->paddr expression and this leads to a NULL pointer dereference and a program crash.

This issue has been patched in version 5.5.4 of radare2.

Recommendation

CENSUS advises users to use a radare2 version greater or equal to 5.6.0, as this version carries appropriate patches that remediate correctly all of the aforementioned issues.

Disclosure Timeline

Vendor Contact:

December 7, 2021

CVE Allocation:

December 13, 2021

Vendor Fix Released:

February 2, 2022

Public Advisory:

May 24, 2022

  • Tags: advisories , memory corruption , NULL pointer dereference , buffer overflow , radare2

Related news

CVE-2021-44975: Heap buffer overflows in function objc_build_refs while parsing mach-o files. · Issue #19476 · radareorg/radare2

radareorg radare2 5.5.2 is vulnerable to Buffer Overflow via /libr/core/anal_objc.c mach-o parser.

CVE-2022-0419: NULL Pointer Dereference in radare2

NULL Pointer Dereference in GitHub repository radareorg/radare2 prior to 5.6.0.

CVE: Latest News

CVE-2023-50976: Transactions API Authorization by oleiman · Pull Request #14969 · redpanda-data/redpanda