Bug 2438909 (CVE-2026-2341) - CVE-2026-2341 libiberty: libiberty: Application crash via crafted C++ symbol demangling
Summary: CVE-2026-2341 libiberty: libiberty: Application crash via crafted C++ symbol ...
Keywords:
Status: NEW
Alias: CVE-2026-2341
Product: Security Response
Classification: Other
Component: vulnerability-draft
Version: unspecified
Hardware: All
OS: Linux
unspecified
unspecified
Target Milestone: ---
Assignee: Product Security DevOps Team
QA Contact:
URL:
Whiteboard:
Depends On: 2438912 2438914 2438917 2438918 2438919 2438913 2438915 2438916
Blocks:
TreeView+ depends on / blocked
 
Reported: 2026-02-11 13:17 UTC by OSIDB Bzimport
Modified: 2026-02-11 14:25 UTC (History)
1 user (show)

Fixed In Version:
Clone Of:
Environment:
Last Closed:
Embargoed:


Attachments (Terms of Use)

Description OSIDB Bzimport 2026-02-11 13:17:16 UTC
Summary: Stack-based buffer overflow in libiberty C++ demangler via unbounded VLA allocation when DMGL_NO_RECURSE_LIMIT flag is set

Requirements to exploit:

1. Target application requirements:

The target application must link against libiberty and call one of the
vulnerable demangling functions: cplus_demangle_v3(), cplus_demangle(),
or __cxa_demangle()
The application must pass the DMGL_NO_RECURSE_LIMIT flag (0x40000 or
1 << 18) in the options parameter
Without this flag, a built-in guard rejects symbols that would cause
excessive stack allocation
2. Attacker capabilities:

The attacker must be able to supply a crafted mangled C++ symbol name
to the vulnerable application
The malicious symbol must be at least ~111,000 characters to exceed
the default 8 MB stack limit (72 bytes per character of stack allocation)
The symbol must begin with "_Z" (Itanium C++ ABI mangling prefix) to
reach the vulnerable code path
3. Common attack vectors:

Malicious ELF object files: Symbol names in .symtab or .dynsym sections
are demangled by nm, objdump, addr2line, and readelf
Malicious PE/COFF files: Windows binaries processed by cross-platform
binutils tools
Malicious Mach-O files: macOS binaries with crafted symbol tables
Direct input: c++filt reads symbol names from stdin or command-line
arguments
Debug information: DWARF debug info containing mangled names
Core dumps: Post-mortem analysis tools demangling symbols from crashed
processes
4. Affected tools (when compiled with DMGL_NO_RECURSE_LIMIT):

c++filt: Historically used DMGL_NO_RECURSE_LIMIT as default
nm: Demangles symbols when displaying symbol tables
objdump: Demangles symbols in disassembly output
addr2line: Demangles function names in stack traces
readelf: Demangles symbols in ELF analysis
GDB: Uses libiberty for C++ symbol demangling
Custom applications: Any software using libiberty's demangler API
5. Exploitation constraints:

The attacker does NOT need code execution - only the ability to provide
a crafted input file or string
No authentication or privileges required
User interaction required (victim must process the malicious input)
The vulnerability triggers during stack allocation, before any parsing,
so the symbol content after "_Z" is irrelevant
Component affected: libiberty (cp-demangle.c)

Version affected: All versions (vulnerability exists in current trunk)

Patch available: yes

Proposed patch:

— a/libiberty/cp-demangle.c
+++ b/libiberty/cp-demangle.c
@@ -6876,8 +6876,7 @@ d_demangle_callback (const char *mangled, int options,

/* PR 87675 - Check for a mangled string that is so long
that we do not have enough stack space to demangle it. */

if (((options & DMGL_NO_RECURSE_LIMIT) == 0)
/* This check is a bit arbitrary, since what we really want to do is to
+ if (/* This check is a bit arbitrary, since what we really want to do is to
compare the sizes of the di.comps and di.subs arrays against the
amount of stack space remaining. But there is no portable way to do
this, so instead we use the recursion limit as a guide to the maximum
This patch removes the DMGL_NO_RECURSE_LIMIT bypass from the stack size guard,
making the check unconditional. The flag's intended purpose is to disable
recursion depth limits during parsing, not to allow unbounded stack allocations
before parsing begins.

Version fixed (if any already): N/A

CVSS: 6.2 (Medium) - CVSS:3.1/AV:L/AC:L/PR:N/UI:R/S:U/C:N/I:N/A:H

Based on: Local attack vector (requires processing malicious file), low
complexity, no privileges required, user interaction required (user must run
tool on malicious input), no confidentiality/integrity impact, high availability
impact (crash/DoS).

Impact: Moderate. The vulnerability causes a denial of service (application
crash) when processing maliciously crafted symbol names. On systems without
stack guard pages, there is potential for arbitrary write via stack pivot,
which could elevate this to Important.

Embargo: no

Reason: This is a moderate severity DoS vulnerability with straightforward
mitigation (avoid DMGL_NO_RECURSE_LIMIT flag or validate symbol length before
demangling). Minimal delay to public disclosure is appropriate.

Acknowledgement: Nathaniel Oh (@calysteon)

Steps to reproduce:

Prerequisites:

GCC compiler with AddressSanitizer support
GCC/binutils source tree (tested on trunk as of February 2026)
Step 1: Clone or obtain the GCC source tree

git clone git://gcc.gnu.org/git/gcc.git
cd gcc

Step 2: Build libiberty with AddressSanitizer instrumentation

cd libiberty
make clean
CFLAGS="-fsanitize=address -g -O0" ./configure
make -j$(nproc)
cd ..

Step 3: Save the proof-of-concept code to poc_demangler_stack_overflow.c

(See "Proof-of-concept source code" section below)

Step 4: Compile the proof-of-concept

gcc -fsanitize=address -g -O0 \
-I include -I libiberty \
poc_demangler_stack_overflow.c libiberty/libiberty.a \
-o poc_demangler_stack_overflow

Step 5: Run the proof-of-concept

./poc_demangler_stack_overflow

Step 6: Observe the ASan crash output

Expected output:
---------------------------------------------------------------
Symbol length : 200002 bytes
Estimated VLA : 25.9 MB on stack
Calling cplus_demangle_v3(..., DMGL_NO_RECURSE_LIMIT)
AddressSanitizer:DEADLYSIGNAL
=================================================================
==PID==ERROR: AddressSanitizer: stack-overflow on address 0x...
#0 ... in __asan_alloca_poison
#1 ... in d_demangle cp-demangle.c:6967
#2 ... in cplus_demangle_v3 cp-demangle.c:7124
#3 ... in main poc_demangler_stack_overflow.c:92
SUMMARY: AddressSanitizer: stack-overflow cp-demangle.c:6967 in d_demangle
==PID==ABORTING
---------------------------------------------------------------

Mitigation:

For application developers using libiberty:

1. Do not use the DMGL_NO_RECURSE_LIMIT flag unless absolutely necessary.

2. If DMGL_NO_RECURSE_LIMIT is required, validate input symbol length before
calling demangling functions:

#define MAX_SAFE_SYMBOL_LEN 1024
if (strlen(symbol) > MAX_SAFE_SYMBOL_LEN)

{ // Reject or truncate the symbol return NULL; }
result = cplus_demangle_v3(symbol, options | DMGL_NO_RECURSE_LIMIT);

3. Consider using setrlimit(RLIMIT_STACK, ...) to increase stack size if
processing untrusted symbols is unavoidable (not recommended for
security-sensitive contexts).

For library maintainers:

Apply the proposed patch above to remove the DMGL_NO_RECURSE_LIMIT bypass
from the stack size guard.

Comment 2 Siddhesh Poyarekar 2026-02-11 13:45:50 UTC
This is a bogus CVE, compiler (and linker) crashes may be bugs but they're not security issues. Please see the security policies of the projects for information:

https://gcc.gnu.org/git/?p=gcc.git;a=blob_plain;f=SECURITY.txt
https://sourceware.org/git/?p=binutils-gdb.git;a=blob_plain;f=binutils/SECURITY.txt;hb=HEAD


Note You need to log in before you can comment on or make changes to this bug.