{"record":{"id":"17530a535a2dc17d","repo":"NationalSecurityAgency/ghidra","slug":"s-s","errorCode":null,"errorMessage":"%s: %s","messagePattern":"%s: %s","errorType":"console","errorClass":null,"httpStatus":null,"severity":"critical","filePath":"GPL/DemanglerGnu/src/demangler_gnu_v2_24/c/cplus-dem.c","lineNumber":5303,"sourceCode":"\n\t\t\t\tfflush (stdout);\n\t\t\t}\n\t\t\tif (c == EOF)\n\t\t\t\tbreak;\n\t\t\tputchar (c);\n\t\t\tif (c == '\\n')\n\t\t\tfflush (stdout);\n\t\t}\n\t}\n\n\treturn (0);\n}\n\nstatic void\nfatal (str)\n     const char *str;\n{\n  fprintf (stderr, \"%s: %s\\n\", program_name, str);\n  exit (1);\n}\n\nPTR\nxmalloc (size)\n  size_t size;\n{\n  register PTR value = (PTR) malloc (size);\n  if (value == 0)\n    fatal (\"virtual memory exhausted\");\n  return value;\n}\n\nPTR\nxrealloc (ptr, size)\n  PTR ptr;\n  size_t size;\n{","sourceCodeStart":5285,"sourceCodeEnd":5321,"githubUrl":"https://github.com/NationalSecurityAgency/ghidra/blob/d5f144c24d6bc53c9cbf4448c6d11143e7696206/GPL/DemanglerGnu/src/demangler_gnu_v2_24/c/cplus-dem.c#L5285-L5321","documentation":"cplus-dem's fatal(str) prints '<program_name>: <str>' to stderr and calls exit(1). It is the library's unrecoverable-error path; the one in-tree caller shown is xmalloc, which calls fatal(\"virtual memory exhausted\") when malloc returns 0. So in practice this message means an allocation failed and the process is terminating immediately.","triggerScenarios":"Any allocation inside the demangler (xmalloc/xrealloc family) returning NULL/0, which routes to fatal(). With the standard caller this means the process ran out of memory while demangling (e.g. an adversarial/pathological mangled name causing huge allocation, or the host is genuinely OOM).","commonSituations":"Processing an extremely large or pathological mangled name that triggers a huge allocation; running the demangler on an untrusted input stream without memory limits; host under memory pressure or container memory cgroup hit; a bug causing unbounded allocation.","solutions":["Run the demangler under a memory limit (ulimit -v, or container cgroup) to bound exposure, then reject inputs that exceed it.","Inspect/sanitize the input mangled name for pathological patterns before demangling (size caps, depth caps).","Increase available memory / reduce concurrent load if the host is genuinely constrained.","Update the demangler/libiberty; some historical unbounded-allocation bugs in demangling are fixed in newer versions."],"exampleFix":"// before - run demangler on unbounded untrusted input\n$ cat huge_symbols.txt | while read s; do c++filt \"$s\"; done\n\n// after - cap per-invocation memory and input size\n$ ulimit -v 262144   # 256 MB virtual cap\n$ awk 'length($0) < 4096' huge_symbols.txt | while read s; do c++filt \"$s\"; done","handlingStrategy":"fallback","validationCode":"// Cap per-invocation memory and input size before demangling\n// (shell) ulimit -v 262144  # 256 MB\n// (input gate) skip lines longer than a safe bound before piping to the demangler\nif (strlen(mangled) > MAX_SAFE_NAME) { /* skip or truncate */ }","typeGuard":"boolean isPlausiblySafeInput(String s) {\n    return s != null && s.length() < 4096 && s.chars().filter(c -> c == 'N').count() < 1000; // crude depth/size guard\n}","tryCatchPattern":"// fatal() calls exit(1); cannot be caught inside the demangler process.\n// Run it as a child and treat non-zero exit / 'virtual memory exhausted' as a hard reject:\nint rc = run_child_with_limits({\"c++filt\", symbol}, memLimitBytes);\nif (rc != 0) {\n    /* skip this symbol; treat as untrusted/pathological */\n}","preventionTips":["Run the demangler under a memory cap (ulimit -v or container cgroup).","Cap input name length and template-nesting depth before demangling.","Process untrusted symbol streams one-at-a-time so one bad input cannot abort a batch.","Keep the demangler/libiberty updated to pick up allocation-bug fixes."],"tags":["demangler","memory","oom","allocation","crash"],"backgroundTag":null,"analyzedSha":"d5f144c24d6bc53c9cbf4448c6d11143e7696206","analyzedAt":"2026-08-14T01:00:57.564Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}