Skip to main content
Vulnerability Database/CVE-2026-81884

CVE-2026-81884: radare2 Mach-O Parser Buffer Overflow

CVE-2026-81884 is a buffer overflow in radare2 Mach-O LC_DATA_IN_CODE parser that causes heap out-of-bounds reads when processing crafted files. This article covers technical details, affected versions, and mitigation steps.

Updated:

CVE-2026-81884 Overview

CVE-2026-81884 is an out-of-bounds read vulnerability [CWE-125] in radare2, a UNIX-like reverse engineering framework and command-line toolset. The flaw affects versions prior to 6.2.0 and resides in the Mach-O LC_DATA_IN_CODE load command parser. The parser trusted the dataoff and datasize fields from the file and permitted a final partial record to be processed. When datasize was not a multiple of the data_in_code_entry structure size, the last loop iteration read past the allocated heap buffer. Exploitation requires opening a crafted Mach-O file while the non-default bin.verbose option is enabled.

Critical Impact

A crafted Mach-O binary can trigger a heap out-of-bounds read in radare2, potentially terminating the analyst's process. No memory disclosure to the attacker has been demonstrated.

Affected Products

  • radare2 versions prior to 6.2.0
  • Mach-O parser component in libr/bin/format/mach0/mach0.c
  • Deployments where bin.verbose is enabled during binary analysis

Discovery Timeline

  • 2026-09-22 - CVE-2026-81884 published to NVD
  • 2026-09-23 - Last updated in NVD database
  • radare2 6.2.0 - Patched release published on GitHub

Technical Details for CVE-2026-81884

Vulnerability Analysis

The vulnerability lives in the Mach-O LC_DATA_IN_CODE load command handler within libr/bin/format/mach0/mach0.c. When the bin.verbose option is enabled, radare2 parses the data-in-code table to log each entry. The parser reads dataoff and datasize directly from the file header without validating that the values fit within the mapped buffer or that datasize aligns to the struct data_in_code_entry boundary. The loop increments by 8 bytes per iteration until j < datasize. When datasize is not a multiple of 8, the final iteration reads bytes beyond the heap allocation returned by malloc(datasize). The result is a heap out-of-bounds read that can terminate the radare2 process.

Root Cause

The root cause is missing input validation on attacker-controlled Mach-O metadata. The parser did not enforce that datasize <= ST32_MAX, that the (dataoff, datasize) range fit within the file, or that partial trailing records were rejected. Combined with a byte-granular loop increment, any misaligned datasize produced an out-of-bounds read.

Attack Vector

Exploitation is local and requires user interaction. An analyst must open a crafted Mach-O file in radare2 with the non-default bin.verbose option enabled. There is no network vector and no privilege escalation path. The observed impact is limited to process crash or availability loss during analysis.

c
// Patch excerpt: libr/bin/format/mach0/mach0.c
sdb_set (mo->kv, cmd_flagname, "data_in_code", 0);
if (mo->verbose) {
    ut8 buf[8];
    if (r_buf_read_at (mo->b, off + 8, buf, sizeof (buf)) != sizeof (buf)) {
        break;
    }
    ut32 dataoff = r_read_ble32 (buf, mo->big_endian);
    ut32 datasize = r_read_ble32 (buf + 4, mo->big_endian);
    R_LOG_INFO ("data-in-code at 0x%x size %d", dataoff, datasize);
    if (datasize > ST32_MAX || !fits_in (mo->size, dataoff, datasize)) {
        R_LOG_WARN ("Invalid LC_DATA_IN_CODE range");
        break;
    }
    ut8 *db = (ut8 *)malloc (datasize);
    if (db) {
        if (r_buf_read_at (mo->b, dataoff, db, (int)datasize) == (int)datasize) {
            const ut64 entry_size = sizeof (struct data_in_code_entry);
            // ... iterate by entry_size instead of 8 bytes
        }
    }
}

Source: radare2 commit a73de09. The fix validates the read length, bounds-checks datasize against ST32_MAX and the file size, and iterates by the entry structure size to prevent partial-record reads.

Detection Methods for CVE-2026-81884

Indicators of Compromise

  • Unexpected crashes or SIGSEGV termination of radare2 or r2 processes during Mach-O analysis.
  • Log entries containing data-in-code at 0x... size ... immediately preceding a crash.
  • Presence of Mach-O sample files with LC_DATA_IN_CODE load commands where datasize is not a multiple of 8.

Detection Strategies

  • Inspect Mach-O samples for LC_DATA_IN_CODE load commands and validate that datasize aligns to the data_in_code_entry structure and that (dataoff, datasize) fits within the file.
  • Monitor analyst workstations and automated malware pipelines for repeated radare2 process crashes tied to a specific sample hash.
  • Track radare2 binary versions across analyst systems and flag any installations older than 6.2.0.

Monitoring Recommendations

  • Enable core dump collection on triage sandboxes to correlate radare2 crashes with the sample that triggered them.
  • Alert on execution of radare2 with -e bin.verbose=true against unvetted samples in shared analysis environments.
  • Ingest package manager and build system inventories to confirm radare2 6.2.0 or later is deployed everywhere.

How to Mitigate CVE-2026-81884

Immediate Actions Required

  • Upgrade radare2 to version 6.2.0 or later on all analyst workstations, CI pipelines, and automated malware triage systems.
  • Disable the bin.verbose option when analyzing untrusted Mach-O samples on unpatched installations.
  • Isolate untrusted Mach-O analysis to sandboxed virtual machines or containers where a crash cannot affect other workloads.

Patch Information

The fix is committed as a73de09fea7516f65c14917d66113316ec7e7d6e and shipped in radare2 release 6.2.0. Additional context is available in the GitHub Security Advisory GHSA-c2g2-2mc7-3x5w, the issue discussion, and the pull request.

Workarounds

  • Leave bin.verbose at its default disabled state until upgrading to 6.2.0.
  • Pre-validate Mach-O samples with a separate tool to reject files whose LC_DATA_IN_CODEdatasize is not a multiple of 8 or exceeds the file size.
  • Run radare2 under a resource-limited, non-privileged user account so process termination has minimal blast radius.
bash
# Verify installed radare2 version and disable bin.verbose
r2 -v
r2 -e bin.verbose=false -A ./sample.macho

Disclaimer: This content was generated using AI. While we strive for accuracy, please verify critical information with official sources.

Experience the Most Advanced Cybersecurity Platform

See how the world’s most intelligent, autonomous cybersecurity platform can protect your organization today and into the future.