← Back to Feed CACHED · 2026-05-17 09:42:19 · cache_key CVE-2025-29912
CVE-2025-5222 · CWE-120 · Disclosed 2025-05-27

A stack buffer overflow was found in Internationl components for unicode

ASSESSED — NOISGATE V0.5
Vendor
Reassessed
Verdict:
01 · The Real Story

This is a bad gearbox in the shop forklift, not a hole in the perimeter fence

CVE-2025-5222 is a stack overflow in ICU's genrb tool, specifically SRBRoot::addTag in parse.cpp, triggered while converting crafted resource-bundle input. The bug was reproduced on ICU 76.0.1; NVD later mapped affected upstream trains as releases before 77.1 and before 78.1 depending on branch, and multiple distros backported the fix into older package lines rather than bumping to those upstream versions.

The vendor's 7.0 HIGH is technically defensible if you score the memory-corruption outcome in a vacuum, but it overstates day-two enterprise risk. The attack is *local*, *high complexity*, and *user-interaction dependent*, and it hits a command-line build/localization tool rather than a long-running network-facing service; in most estates that means exposure is concentrated in developer workstations, build runners, and software packaging pipelines.

"This is a build-tool overflow, not an internet foothold: real risk is narrow and mostly local to dev and CI systems."
02 · The Attack Path

4 steps from start to impact.

STEP 01

Land crafted localization input

The attacker needs a malicious ICU resource-bundle source file that will be fed to genrb. In practice that usually means a poisoned third-party localization file, dependency source tree, or build artifact rather than direct exploitation of a production daemon.
Conditions required:
  • Attacker can supply or influence ICU resource-bundle input
  • Target organization uses ICU genrb in packaging, build, or localization workflows
Where this breaks in practice:
  • Most enterprises never run genrb on endpoints outside dev/build roles
  • Input usually comes from trusted internal repos, not arbitrary internet users
Detection/coverage: SCA/SBOM tools can flag vulnerable ICU packages, but they usually cannot tell whether genrb is actually used in that environment.
STEP 02

Trigger the vulnerable parser via genrb

The attacker then needs a user, CI job, or packaging pipeline to invoke genrb on the crafted file. The overflow sits in SRBRoot::addTag; upstream fixed it by replacing a fixed-size char subtag[1024] buffer with CharString handling in commit 2c667e3.
Conditions required:
  • A human or automated build process runs genrb
  • The installed ICU build predates the fix or lacks a distro backport
Where this breaks in practice:
  • This is not a drive-by bug; something must deliberately execute the tool
  • Modern build pipelines often isolate untrusted jobs or reject unexpected resource files
Detection/coverage: Package/version scanners catch known-vulnerable builds; source-based custom builds require file/commit inspection.
STEP 03

Convert overflow into code execution

Successful exploitation requires turning the stack corruption into reliable execution under the privileges of the invoking user or CI runner. Ubuntu explicitly notes compiler hardening likely reduces many cases to a crash or DoS, which is a meaningful real-world brake on weaponization.
Conditions required:
  • Target binary is exploitable despite compiler and platform hardening
  • Attacker can shape memory state well enough for post-overflow control
Where this breaks in practice:
  • CVSS already marks this AC:H, and distro hardening raises the bar further
  • A failed exploit often just kills the tool instead of yielding code execution
Detection/coverage: EDR may catch child-process anomalies or crash telemetry, but there is no broad signature-based network detection because this is a local tool flaw.
STEP 04

Operate within the local blast radius

If exploitation works, the attacker gets execution in the security context of the build user, developer account, or packaging runner. The impact can still matter on high-trust build systems, but it does not magically jump from a tool invocation to enterprise-wide compromise without follow-on weaknesses.
Conditions required:
  • Invoking account has meaningful local or pipeline privileges
  • Attacker can leverage local execution for credential theft, artifact tampering, or lateral movement
Where this breaks in practice:
  • Blast radius is usually one workstation, one build container, or one runner
  • MFA, repo protections, EDR, and runner isolation limit post-exploitation payoff
Detection/coverage: CI logs, EDR on build hosts, and artifact-signing anomalies are the most realistic follow-on detection points.
03 · Intelligence Metadata

The supporting signals.

In-the-wild statusNo authoritative evidence of active exploitation found in CISA KEV or vendor advisories during this review.
KEV statusNot KEV-listed as of this assessment; CISA's catalog is the authoritative check.
Proof-of-concept availabilityThere is at least a public reproduction/backport path: upstream fix commit 2c667e3 and a public Debian packaging repo from berkley4 carrying the fix for ICU 74.2.
EPSS0.00033 from the supplied intel; secondary feeds report roughly the 14th percentile, which is consistent with a low-likelihood local-tool issue.
CVSS vector meaningAV:L/AC:H/PR:N/UI:R is the whole story: local only, hard to exploit, needs someone or something to run the tool.
Affected versionsConfirmed on ICU 76.0.1; NVD change history later associated vulnerable upstream ranges with releases before 77.1 and before 78.1 by branch.
Fixed versionsUpstream fix landed in commit 2c667e3; practical fixes include upstream 77.1/78.1 and distro backports such as Debian 67.1-7+deb11u1, Debian 72.1-3+deb12u1, and RHEL/OL9 67.1-10.el9_6.
Exposure/scanning realityThis is not internet-scannable in the usual Shodan/Censys sense because the vulnerable surface is the local genrb executable, not a listening service.
Disclosure datePublicly disclosed on 2025-05-27; upstream fix commit predates that, dated 2025-01-22.
Reporting / provenanceCVE was published by Red Hat; the code fix was committed upstream by Frank Tang in the unicode-org/icu repository.
04 · The Call

noisgate verdict.

Final Verdict
DOWNGRADED to LOW (3.1/10)

The single biggest severity reducer is that this bug lives in genrb, a local command-line build tool, not a remotely reachable service. That sharply limits reachable population and turns exploitation into a supply-chain or workstation problem, not a broad enterprise intrusion path.

HIGH This is not a perimeter-facing vulnerability
HIGH Local/UI/high-complexity prerequisites materially reduce enterprise-wide urgency
MEDIUM Reliable code-exec versus crash-only outcomes across hardened distro builds

Why this verdict

  • Down from vendor HIGH because attacker position is local: the chain starts at AV:L, which implies the adversary already has code delivery into a workstation, build host, or CI context.
  • Further down because it needs execution of a specific tool: the vulnerable component is genrb, so only systems that actually compile ICU resource bundles are in scope; that is a small subset of a 10,000-host estate.
  • Further down because real deployments add friction: AC:H + UI:R + compiler hardening mean many environments are more likely to see a crash than clean weaponization, and EDR/runner isolation should constrain the payoff.

Why not higher?

This is not unauthenticated remote, not broadly exposed, and not a common server-side runtime path. Most enterprises can remove 95%+ of the estate from concern immediately because ordinary user endpoints and production servers never invoke genrb.

Why not lower?

It is still a memory-corruption bug with plausible local code execution under the invoking account. On developer laptops, packaging hosts, and CI runners that ingest third-party source or localization files, that can become a meaningful foothold or artifact-tampering opportunity.

05 · Compensating Control

What to do — in priority order.

  1. Constrain genrb to trusted build contexts — Run ICU resource compilation only on managed developer workstations and isolated CI runners, not on general-purpose servers. For a LOW verdict there is no formal mitigation deadline, but do this as backlog hygiene in the same maintenance cycle where you review build-tool exposure.
  2. Isolate untrusted builds — If you build third-party or community code, keep those jobs in disposable containers/VMs with no long-lived secrets and no signing keys. That shrinks the local blast radius even if genrb is triggered before the patch lands.
  3. Protect artifact-signing and CI credentials — Keep signing keys, package publishing tokens, and repo credentials out of the same execution context as untrusted build jobs. This matters more than the overflow itself because the realistic damage path is CI or developer-account abuse.
  4. Inventory actual genrb usage — Prioritize hosts with icu-devtools, package-build roles, or source trees invoking genrb; most other systems can be deprioritized. For LOW, do this during routine vulnerability triage rather than emergency response.
What doesn't work
  • A perimeter firewall does not help because there is no network listener to shield.
  • WAF rules do not help because exploitation is not delivered over HTTP to a service endpoint.
  • Blindly chasing every host with libicu installed overstates risk; the meaningful exposure is where genrb is present and actually used.
06 · Verification

Crowdsourced verification payload.

Run this on the target Linux host or build runner that has ICU installed. Invoke it as sudo bash check-cve-2025-5222.sh for package-based checks, or bash check-cve-2025-5222.sh /path/to/icu-source to inspect a source tree directly; root is recommended so RPM changelog queries work reliably.

noisgate-verify.sh
BASHREAD-ONLYSAFE
#!/usr/bin/env bash
# check-cve-2025-5222.sh
# Detect likely exposure to CVE-2025-5222 on Linux hosts.
# Output: VULNERABLE / PATCHED / UNKNOWN
# Exit codes: 0=PATCHED, 1=VULNERABLE, 2=UNKNOWN

set -u

SOURCE_ROOT="${1:-}"

patched() {
  echo "PATCHED"
  exit 0
}

vulnerable() {
  echo "VULNERABLE"
  exit 1
}

unknown() {
  echo "UNKNOWN"
  exit 2
}

# 1) Source-tree check: look for upstream fix pattern in parse.cpp
if [ -n "$SOURCE_ROOT" ]; then
  PARSE_CPP=""
  if [ -f "$SOURCE_ROOT/icu4c/source/tools/genrb/parse.cpp" ]; then
    PARSE_CPP="$SOURCE_ROOT/icu4c/source/tools/genrb/parse.cpp"
  elif [ -f "$SOURCE_ROOT/source/tools/genrb/parse.cpp" ]; then
    PARSE_CPP="$SOURCE_ROOT/source/tools/genrb/parse.cpp"
  fi

  if [ -n "$PARSE_CPP" ]; then
    if grep -q 'CharString[[:space:]]\+subtag;' "$PARSE_CPP"; then
      patched
    fi
    if grep -q 'char[[:space:]]\+subtag\[1024\];' "$PARSE_CPP"; then
      vulnerable
    fi
    unknown
  fi
fi

# 2) Debian/Ubuntu package checks
if command -v dpkg-query >/dev/null 2>&1; then
  if dpkg-query -W -f='${Status}' icu-devtools 2>/dev/null | grep -q 'install ok installed'; then
    ver="$(dpkg-query -W -f='${Version}' icu-devtools 2>/dev/null)"
    # Debian 11 backport
    if dpkg --compare-versions "$ver" ge '67.1-7+deb11u1'; then
      patched
    fi
    # Debian 12 / Ubuntu-derived 72.x line backport
    if dpkg --compare-versions "$ver" ge '72.1-3+deb12u1'; then
      patched
    fi
    # Upstream fixed lines commonly seen in custom packages
    if dpkg --compare-versions "$ver" ge '77.1'; then
      patched
    fi
    vulnerable
  fi

  # Fallback if icu-devtools is absent but libicu is present
  for pkg in libicu72 libicu74 libicu76 libicu77 libicu78 libicu67; do
    if dpkg-query -W -f='${Status}' "$pkg" 2>/dev/null | grep -q 'install ok installed'; then
      ver="$(dpkg-query -W -f='${Version}' "$pkg" 2>/dev/null)"
      if dpkg --compare-versions "$ver" ge '72.1-3+deb12u1'; then
        patched
      fi
      if dpkg --compare-versions "$ver" ge '77.1'; then
        patched
      fi
      vulnerable
    fi
  done
fi

# 3) RPM-based checks: changelog marker is safer than upstream version guessing because of backports
if command -v rpm >/dev/null 2>&1; then
  if rpm -q icu >/dev/null 2>&1; then
    if rpm -q --changelog icu 2>/dev/null | grep -q 'ICU-22973'; then
      patched
    fi
    if rpm -q --changelog icu 2>/dev/null | grep -q 'CVE-2025-5222'; then
      patched
    fi
    vulnerable
  fi

  for pkg in libicu libicu-devel icu; do
    if rpm -q "$pkg" >/dev/null 2>&1; then
      if rpm -q --changelog "$pkg" 2>/dev/null | grep -q 'ICU-22973'; then
        patched
      fi
      if rpm -q --changelog "$pkg" 2>/dev/null | grep -q 'CVE-2025-5222'; then
        patched
      fi
      vulnerable
    fi
  done
fi

# 4) Binary-only fallback
if command -v genrb >/dev/null 2>&1; then
  # Binary present but package/source evidence unavailable
  unknown
fi

unknown
07 · Bottom Line

If you remember one thing.

TL;DR
Monday morning, do not treat this like a perimeter emergency. First identify the small population that actually runs ICU genrb—developer workstations, package builders, and CI runners—and document everything else as out-of-scope. For a LOW verdict there is no noisgate mitigation SLA and no noisgate remediation SLA; treat it as backlog hygiene, fold the patch into routine ICU/toolchain updates, and prioritize only those build environments that process third-party or untrusted localization content.

Sources

  1. NVD CVE record
  2. Upstream ICU fix commit 2c667e3
  3. Red Hat bug 2368600
  4. Red Hat RHSA-2025:12083
  5. Debian LTS advisory DLA-4217-1
  6. Debian security tracker
  7. Ubuntu CVE page
  8. Public Debian packaging repo carrying the fix
Peer Review

What defenders are saying.

Submit a review attribution: handle + country only
0 flags selected · stored anonymously
Validation Results

Crowdsourced verification outputs.

Results submitted by users who ran the verification payload against their environment.