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

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

CVE-2026-81881 is a buffer overflow in radare2's Mach-O Swift field-metadata parser that allows out-of-bounds memory reads. This article covers the technical details, affected versions, and mitigation strategies.

Updated:

CVE-2026-81881 Overview

CVE-2026-81881 is an out-of-bounds read vulnerability [CWE-125] in radare2, a UNIX-like reverse engineering framework and command-line toolset. The flaw resides in the Mach-O Swift field-metadata parser. A relative Swift field pointer could be lower than the field-metadata section base, causing a subtraction to produce a negative logical index. The parser then read four bytes immediately before the allocated field-metadata buffer. Parsing a crafted Mach-O file triggers the condition. The issue is fixed in radare2 version 6.2.0.

Critical Impact

The bug can cause incorrect metadata processing or process termination when a user opens a crafted Mach-O file in radare2. No attacker-observable memory disclosure has been demonstrated.

Affected Products

  • radare2 versions prior to 6.2.0
  • radare2 Mach-O binary parser (libr/bin/format/objc/mach0_classes.c)
  • Swift type and class metadata processing paths

Discovery Timeline

  • 2026-09-22 - CVE-2026-81881 published to NVD
  • 2026-09-23 - Last updated in NVD database

Technical Details for CVE-2026-81881

Vulnerability Analysis

The vulnerability affects the Swift metadata processing routine in radare2's Mach-O loader. When parsing Swift type and class metadata, the code computes a logical index from the difference between a relative Swift field pointer (st.fields) and the base address of the field-metadata section (st.fieldmd.addr). The prior implementation assumed st.fields >= st.fieldmd.addr without validating the relationship. When the field pointer sits below the section base, the subtraction yields a negative value that is cast into a signed integer index. That index is then multiplied by four and dereferenced, causing the parser to read four bytes immediately before the allocated st.fieldmd_data buffer.

Root Cause

The root cause is a missing bounds check combined with signed integer arithmetic on untrusted offsets. The original loop computed j = (st.fields - st.fieldmd.addr) / 4 without verifying that st.fields was greater than or equal to st.fieldmd.addr. The subsequent index d = 6 + j + i was compared only against dmax, not against a lower bound or the maximum representable index. Reading swift_read_s32_le(st.fieldmd_data, d - 1) with a negative or attacker-controlled d results in an out-of-bounds read [CWE-125].

Attack Vector

Exploitation requires local access and user interaction: an analyst must open the crafted Mach-O file in radare2. The impact is limited to availability, with process termination or corrupted metadata output as the observable outcome. No memory disclosure has been demonstrated.

c
// Patch excerpt from libr/bin/format/objc/mach0_classes.c
// Source: https://github.com/radareorg/radare2/commit/1da6e782df220edf56138ef5fe4f33745b04db74
-	if (st.fields != UT64_MAX) {
+	if (st.fields != UT64_MAX && st.fields >= st.fieldmd.addr) {
+		const ut64 fieldmd_delta = st.fields - st.fieldmd.addr;
+		const ut64 dmax = st.fieldmd.size / sizeof (ut32);
+		const ut64 max_idx = (ut64)SZT_MAX / sizeof (ut32);
+		const ut64 j = fieldmd_delta / sizeof (ut32);
 		int i;
-		size_t dmax = st.fieldmd.size / 4;
 		for (i = 0; i < 128; i += 3) {
-			const int j = (st.fields - st.fieldmd.addr) / 4;
-			const int d = 6 + j + i;
-			if (d >= dmax) {
+			const ut64 d = 6 + j + i;
+			if (fieldmd_delta >= st.fieldmd.size || d >= dmax || d > max_idx) {
 				break;
 			}
-			ut64 field_name_addr = st.fieldmd.addr + (d * 4) + swift_read_s32_le (st.fieldmd_data, d);
-			ut64 field_type_addr = st.fieldmd.addr + (d * 4) + swift_read_s32_le (st.fieldmd_data, d - 1) - 4;
+			const size_t idx = (size_t)d;
+			const ut64 field_addr = st.fieldmd.addr + (d * sizeof (ut32));
+			ut64 field_name_addr = field_addr + swift_read_s32_le (st.fieldmd_data, idx);
+			ut64 field_type_addr = field_addr + swift_read_s32_le (st.fieldmd_data, idx - 1) - 4;

The patch enforces st.fields >= st.fieldmd.addr, promotes the arithmetic to unsigned 64-bit values, and adds an explicit upper bound (max_idx) tied to SZT_MAX.

Detection Methods for CVE-2026-81881

Indicators of Compromise

  • Unexpected crashes or aborts of the radare2, r2, or rabin2 binaries while loading Mach-O samples.
  • Sanitizer reports (AddressSanitizer, MemorySanitizer) flagging out-of-bounds reads in mach0_classes.c near swift_read_s32_le.
  • Mach-O files whose Swift field-metadata section pointers reference addresses lower than the declared section base.

Detection Strategies

  • Scan analyst workstations for radare2 installations below version 6.2.0 and inventory build sources (package manager, git checkout, container images).
  • Run malware triage samples through a hardened radare2 build compiled with AddressSanitizer to surface the specific out-of-bounds read.
  • Add YARA or file-triage rules that flag Mach-O binaries with anomalous Swift fieldmd layouts prior to opening them in production tooling.

Monitoring Recommendations

  • Monitor endpoint telemetry on reverse-engineering workstations for repeated abnormal exits of radare2 processes.
  • Alert on radare2 execution against files sourced from untrusted email, chat, or download paths.
  • Track package inventory to confirm radare2 updates propagate across analyst VMs, sandboxes, and CI pipelines used for automated Mach-O analysis.

How to Mitigate CVE-2026-81881

Immediate Actions Required

  • Upgrade radare2 to version 6.2.0 or later on all analyst workstations, sandboxes, and automation hosts. See the Radare2 Release 6.2.0 notes.
  • Rebuild any downstream tools, containers, or forensic images that bundle radare2 to pick up the fixed library.
  • Restrict opening untrusted Mach-O samples to isolated virtual machines until the upgrade is complete.

Patch Information

The fix is applied in commit 1da6e782df220edf56138ef5fe4f33745b04db74 and is included in radare2 6.2.0. Additional context is available in Radare2 Issue #26229 and GitHub Security Advisory GHSA-q4w7-225g-64j9.

Workarounds

  • Avoid analyzing untrusted Mach-O binaries with vulnerable radare2 builds; use disposable analysis VMs when unavoidable.
  • Disable automated Mach-O ingestion pipelines that invoke rabin2 or r2 on unvetted samples until upgraded.
  • Compile radare2 with AddressSanitizer for triage environments so any residual out-of-bounds read aborts before producing misleading output.
bash
# Upgrade radare2 from source to the fixed release
git clone https://github.com/radareorg/radare2.git
cd radare2
git checkout 6.2.0
sys/install.sh
r2 -v   # confirm version reports 6.2.0 or later

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.