ANT-2026-GY2SF1XW · grok

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 Ada Logics.

ANT-2026-GY2SF1XW: Heap-buffer-overflow in FileFormatMJ2Decompress.cpp:593

During MJ2 header parsing, read_stts() populates a std::vector based on the stts box entry count (tts_decompact, line 480). Later, read_stco() iterates over stco chunk offset entries and writes into that same vector (stco_decompact, line 593). No check enforces that the stco entry count is bounded by the number of samples already allocated from stts. A crafted MJ2 file with more stco entries than stts samples causes a 4-byte out-of-bounds heap write with attacker-controlled offset values. Any application using Grok to decode untrusted MJ2 files is affected.

Target

Project: grok
Location: FileFormatMJ2Decompress.cpp:593

Technical Details

ASAN: WRITE of size 4 at 0x6c7124fe02a0, located 4 bytes after a 12-byte heap region. The 12-byte region holds a single mj2_sample element allocated by vector::push_back in tts_decompact. stco_decompact then indexes past the vector's end — it trusts the stco box's own entry count rather than the actual size of the sample vector it is writing into, producing an OOB write into heap redzone/adjacent allocation.

Crash trace (truncated — full trace in attached crash.log):

INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 1531295879
INFO: Loaded 1 modules   (62708 inline 8-bit counters): 62708 [0x55f34f9a0840, 0x55f34f9afd34), 
INFO: Loaded 1 PC tables (62708 PCs): 62708 [0x55f34f9afd38,0x55f34faa4c78), 
/out/grk_decompress_fuzzer: Running 1 inputs 1 time(s) each.
Running: /tmp/poc
EXIT_CODE:1


=== ASAN Report ===
=================================================================
==27==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x6c7124fe02a0 at pc 0x55f34f15ada6 bp 0x7ffc7cec8950 sp 0x7ffc7cec8948
WRITE of size 4 at 0x6c7124fe02a0 thread T0
    #0 0x55f34f15ada5 in stco_decompact /src/grok/src/lib/core/fileformat/decompress/FileFormatMJ2Decompress.cpp:593:43
    #1 0x55f34f15ada5 in grk::FileFormatMJ2Decompress::read_stco(unsigned char*, unsigned int) /src/grok/src/lib/core/fileformat/decompress/FileFormatMJ2Decompress.cpp:616:3
    #2 0x55f34f3919cf in operator() /usr/local/bin/../include/c++/v1/__functional/function.h:274:12
    #3 0x55f34f3919cf in operator() /usr/local/bin/../include/c++/v1/__functional/function.h:772:10
    #4 0x55f34f3919cf in grk::FileFormatJP2Family::readHeaderProcedure() /src/grok/src/lib/core/fileformat/FileFormatJP2Family.cpp:367:15
    #5 0x55f34f38ff94 in grk::FileFormatJP2Family::readHeader(_grk_header_info*, grk::GrkImage*) /src/grok/src/lib/core/fileformat/FileFormatJP2Family.cpp:117:9
    #6 0x55f34f15afd4 in grk::FileFormatMJ2Decompress::readHeader(_grk_header_info*) /src/grok/src/lib/core/fileformat/decompress/FileFormatMJ2Decompress.cpp:640:34
    #7 0x55f34f0a3f6e in LLVMFuzzerTestOneInput /src/grok/./tests/fuzzers/grk_decompress_fuzzer.cpp:51:7
    [... 29 more frames — full trace in crash.log]

Reproduction

  1. Craft an MJ2 container with an stts box declaring a small sample count (e.g., 1 sample → 12-byte vector)
  2. Include a subsequent stco box declaring a larger chunk offset count
  3. Deliver file to victim; Grok's readHeader parses stts first (allocates small vector), then stco
  4. stco_decompact writes attacker-controlled 32-bit offset values past the end of the sample vector

[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-GY2SF1XW.


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

SECURITY RESEARCH FIRM ANALYSIS

Triage and disclosure were performed by Ada Logics.

Verdict
true positive
Severity
high
TIMELINE

Dates from discovery through public reveal.

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

SHA-3-512 hash:

9724c7cfaf8b05bf517732e8d02a0166a2bb18e06f9a955c626aa0048c550b41f66800681544d5026a1f1bb45bf6c492499566d9a90eb5cdd9989b8a8bf3edca

Committed 2026-06-06 00:20 PT

Revealed 2026-08-17 17:17 PT

Verify (download preimage.json)

Show preimage JSON
{
  "ant_id": "ANT-2026-GY2SF1XW",
  "bug_class": "Heap-buffer-overflow",
  "claude_severity": "high",
  "commit_sha": null,
  "created_at": "2026-03-24T18:29:25+00:00",
  "description": "During MJ2 header parsing, read_stts() populates a std::vector<mj2_sample> based on the stts box entry count (tts_decompact, line 480). Later, read_stco() iterates over stco chunk offset entries and writes into that same vector (stco_decompact, line 593). No check enforces that the stco entry count is bounded by the number of samples already allocated from stts. A crafted MJ2 file with more stco entries than stts samples causes a 4-byte out-of-bounds heap write with attacker-controlled offset values. Any application using Grok to decode untrusted MJ2 files is affected.",
  "discovered_at": null,
  "location": "FileFormatMJ2Decompress.cpp:593",
  "poc_sha256": null,
  "preimage_version": 1,
  "project": "grok",
  "reproduction": [
    "1. Craft an MJ2 container with an stts box declaring a small sample count (e.g., 1 sample → 12-byte vector)",
    "2. Include a subsequent stco box declaring a larger chunk offset count",
    "3. Deliver file to victim; Grok's readHeader parses stts first (allocates small vector), then stco",
    "4. stco_decompact writes attacker-controlled 32-bit offset values past the end of the sample vector"
  ],
  "technical_details": "ASAN: WRITE of size 4 at 0x6c7124fe02a0, located 4 bytes after a 12-byte heap region. The 12-byte region holds a single mj2_sample element allocated by vector::push_back in tts_decompact. stco_decompact then indexes past the vector's end — it trusts the stco box's own entry count rather than the actual size of the sample vector it is writing into, producing an OOB write into heap redzone/adjacent allocation.",
  "title": "Heap-buffer-overflow in FileFormatMJ2Decompress.cpp:593",
  "vendor_severity": "high"
}