ANT-2026-7ZJGE8XJ · upx

heap-buffer-overflow high

Severity Claude high · Security research firm high · Maintainer -

Discovered by Claude Mythos Preview

REPORT

Anthropic's analysis, sealed at approval. Disclosure to the maintainer was performed by Trail of Bits.

ANT-2026-7ZJGE8XJ: Heap buffer overflow in un_shlib_1 readx due to attacker-controlled offsets exceeding ibuf size

Attacker-controlled offset values are not validated against the size of ibuf before use in readx, allowing out-of-bounds heap access.

Target

Project: upx
Location: un_shlib_1 / readx
Discovery: static analysis — not yet dynamically reproduced

Technical Details

The root cause is a missing bounds check: offsets derived from attacker-supplied input are used to index into ibuf without verifying they fall within the allocated buffer size, resulting in a heap buffer overflow.

Reproduction

This finding was identified by static analysis and has not yet been dynamically reproduced. The Technical Details section above describes the code path; a trigger input is not included.

[No reproducer or sanitizer output attached — request from security-cvd@anthropic.com if needed.]

Acknowledgement

This vulnerability was discovered by Claude, Anthropic's AI assistant, and triaged by the Anthropic security team in collaboration with Anthropic Research. Please direct questions to security-cvd@anthropic.com and reference ANT-2026-7ZJGE8XJ.


Reference: ANT-2026-7ZJGE8XJ
Anthropic CVD Policy: https://www.anthropic.com/coordinated-vulnerability-disclosure

SECURITY RESEARCH FIRM ANALYSIS

Triage and disclosure were performed by Trail of Bits. The writeup below is the document the firm sent to the maintainer.

Verdict
true positive
Severity
high

This issue tracker is ONLY used for reporting bugs. Please use stackoverflow for supporting issues.

From Anthropic "Trail of Bits" report:

Vulnerability Header

Executive Summary

A heap buffer overflow exists in UPX's PackLinuxElf64::un_shlib_1 function when testing or decompressing a crafted UPX-packed ELF shared library. The len variable, computed from attacker-controlled values yct_off/xct_off and sz_elf_hdrs, can exceed the allocated ibuf buffer size, causing fi->readx() to write past the end of the heap buffer.

Root Cause Analysis

Technical Description

In p_lx_elf.cpp:7143, the variable len is computed as:

unsigned const len = (yct_off ? yct_off : xct_off) - sz_elf_hdrs;

Both yct_off and xct_off are derived from attacker-controlled fields in the compressed ELF file. The ibuf buffer was allocated earlier at line 7795 with size blocksize + OVERHEAD. There is no validation that sz_elf_hdrs + len <= ibuf.getSize() before the read at line 7146:

fi->readx(&ibuf[sz_elf_hdrs], len);

When a crafted ELF file provides values where (yct_off or xct_off) - sz_elf_hdrs exceeds the remaining space in ibuf, the readx call writes 2680 bytes past the end of a 2508-byte heap allocation.

First Faulty Condition

Missing bounds check on len at p_lx_elf.cpp:7143-7146. The code should verify that sz_elf_hdrs + len <= ibuf.getSize() before reading into the buffer.

Proposed Fix

Add a bounds check before the readx call (see patch.diff):

if ((upx_uint64_t)sz_elf_hdrs + len > ibuf.getSize())
    throwCantUnpack("bad xct_off or yct_off");

Validated: the PoC is rejected with CantUnpackException (no ASAN crash) after applying the patch.

Exploitability Assessment

Attack Vector & Reachability

This bug is triggered when UPX processes a crafted UPX-packed ELF shared library via upx -t <file> (test) or upx -d <file> -o <out> (decompress). The oss-fuzz harness invokes the real upx_main code path with these flags, so fuzz-harness reachability matches real-world reachability for this issue.

Reachability verdict (fuzz harness): CONFIRMED

Reachability verdict (real world): CONFIRMED — requires the user to run UPX on an attacker-supplied packed binary.

Prerequisite checks before the vulnerable code is reached: - File is accepted as an ELF64 input and routed to PackLinuxElf64. - The un_shlib_1 unpacking path is selected (packed shared-library handling). - The code takes the "new style" path (sz_block1 == sz_elf_hdrs) before computing len and calling readx.

The Attack Sequence

  1. An attacker crafts a UPX-packed ELF shared library with header/offset values that make len = (yct_off ? yct_off : xct_off) - sz_elf_hdrs exceed the remaining space in ibuf.
  2. A victim runs upx -t or upx -d on the file.
  3. UPX enters PackLinuxElf64::un_shlib_1 and calls fi->readx(&ibuf[sz_elf_hdrs], len) without validating that sz_elf_hdrs + len fits in ibuf.
  4. This results in an out-of-bounds heap write of attacker-controlled bytes.

Technical Primitive

The attacker gets a heap buffer overflow WRITE of ~2680 bytes. The write size is partially controlled (via xct_off/yct_off values), and the written data comes from fi->readx() which reads from the attacker-controlled input file. This gives a write primitive with attacker-controlled content and partially controlled size.

Mitigation Analysis

Reproduction Steps

# Build UPX fuzzers with ASAN
cd /path/to/oss-fuzz
python3 infra/helper.py build_fuzzers --sanitizer address upx

# Run the PoC (either entrypoint reproduces the same bug)
build/out/upx/decompress_packed_file_fuzzer <path-to-poc.bin>
build/out/upx/test_packed_file_fuzzer <path-to-poc.bin>

Relationship to Parent Bug

This is an independent vulnerability from the parent Bug 083. The parent bug is a heap-buffer-overflow in PackLinuxElf64::un_DT_INIT at line 7664, caused by missing bounds checking on a relocation pointer. This sibling crashes in a completely different function (PackLinuxElf64::un_shlib_1 at line 7146) with a different root cause (unchecked readx length). The parent patch does not fix this bug, and this bug requires its own separate patch.

Please tell us details about your environment.

poc.bin.gz

TIMELINE

Dates from discovery through public reveal.

  1. 2026-03-20 Sent to maintainer
  2. 2026-03-29 Reported to tracker
  3. 2026-05-09 Maintainer acknowledged
  4. 2026-06-08 Patch released
  5. 2026-08-17 Publicly revealed
PROVENANCE

SHA-3-512 hash:

b7ab0621ca0f2e9f852dbfe0c12f5084584ce339b9e7407cd6c274db98dcfddae815f3f084c802aa925d46ef55a4b68b2263f3325e28bf73b421d181bb5e2b03

Committed 2026-05-07 00:01 PT

Revealed 2026-08-17 13:03 PT

Verify (download preimage.json)

Show preimage JSON
{
  "ant_id": "ANT-2026-7ZJGE8XJ",
  "bug_class": "Heap Buffer Overflow",
  "claude_severity": "high",
  "commit_sha": null,
  "created_at": "2026-03-29T20:43:29+00:00",
  "description": "Attacker-controlled offset values are not validated against the size of ibuf before use in readx, allowing out-of-bounds heap access.",
  "discovered_at": null,
  "location": "un_shlib_1 / readx",
  "poc_sha256": null,
  "preimage_version": 1,
  "project": "UPX",
  "reproduction": null,
  "technical_details": "The root cause is a missing bounds check: offsets derived from attacker-supplied input are used to index into ibuf without verifying they fall within the allocated buffer size, resulting in a heap buffer overflow.",
  "title": "Heap buffer overflow in un_shlib_1 readx due to attacker-controlled offsets exceeding ibuf size",
  "vendor_severity": "high"
}