GROK-0012
low confirmedHTJ2K SIMD decoder: MagSgn frwd_read 16-byte vector load over-reads the 8-byte-padded code-block buffer
⚠ Harness reproduced — not real-world verified. Reproduce through the public API, a real application, or a platform decoder before treating this as verified.
Classification
| Target | Grok |
|---|---|
| Component | Tier-1 / MQ / HT block coding |
| Location | src/lib/core/t1/part15/coding/ojph_block_decoder_avx2.cpp · frwd_read (avx2 line 620 / ssse3 line 617):avx2:620, ssse3:617 |
| Vuln class | oob-read |
| CVE | — |
| CVSS | 4 (CVSS:3.1/AV:L/AC:H/PR:N/UI:R/S:U/C:L/I:N/A:L) |
| Discovered | 2026-06-16 |
Verification
| Evidence | Static only (not real-world verified) |
|---|---|
| Harness fired | ❌ no |
| Protocol | 1.0 |
| Sanitizer | none |
| Crash type | heap-buffer-overflow (read, <=6 bytes) |
Disclosure
| Reported to | Grok maintainers — support@grokcompression.com (private email; listed as a source-confirmed lead, not yet runtime-verified) |
|---|---|
| Reported | 2026-06-23 |
| Vendor ack | — |
| Embargo until | — |
| Public | 2026-06-24 |
| Patched in | — |
Writeup
Summary
The SIMD HTJ2K block decoders (the default x86-64 dispatch: AVX2, else SSSE3) read the
compressed MagSgn data with a 16-byte vector load _mm_loadu_si128((__m128i*)msp->data)
(ojph_block_decoder_avx2.cpp:620, ojph_block_decoder_ssse3.cpp:617) before any size guard. Grok
allocates the compressed code-block buffer with only 8 bytes of trailing pad
(grk_cblk_dec_compressed_data_pad_ht = 8, CoderOJPH.cpp:215-225), but the SIMD reader’s own
comment documents it “can go beyond the end of buffer by up to 16 bytes.” When the MagSgn segment is
exhausted, msp->data freezes at base + 8 + (lcup - scup) and the 16-byte load reaches
base + L + 24 - scup; the buffer ends at base + 16 + L, so the over-read is 8 - scup bytes —
1–6 bytes for the attacker-controlled scup ∈ {2..7} (validated only as scup >= 2).
The scalar decoder (ojph_block_decoder32.cpp) is NOT affected — it dereferences *(ui32*) only
while size>3 and stops at base+8+(lcup-scup), in-bounds with the 8-byte pad. This is a SIMD-only
regression caused by the pad (8) being smaller than the SIMD look-ahead (16).
Reproduction
Decode an HTJ2K (Part-15) J2K whose cleanup-pass scup (read from coded_data[lcup-1..lcup-2]) is
< 8 and whose MagSgn segment is small/exhausted, on a default x86-64 build (AVX2/SSSE3). The
over-read materializes in frwd_read. (Triggering a specific scup<8 is data-dependent; an HT
fuzz campaign or a hand-tuned code-block is the reliable route — see nextSteps.)
Root cause
grk_cblk_dec_compressed_data_pad_ht = 8 < the 16-byte trailing slack the SIMD frwd_read assumes.
Verification evidence
Confirmed by source: over-read = 8 - scup bytes (max 6 at scup=2); present on the default AVX2 +
SSSE3 dispatch; absent from the verified-safe scalar path. The decoder’s own comment documents the
16-byte look-ahead vs the 8-byte pad.
Runtime status (2026-06-16): not yet ASAN-reproduced. Triggering needs an HTJ2K code-block whose
cleanup-pass scup decodes to < 8 and whose MagSgn segment is exhausted — a data-dependent property
of the compressed block that a normal grk_compress-produced HT codestream does not generally
satisfy. Producing it requires a hand-tuned HT code-block or (more practically) a coverage-guided HT
fuzz campaign — the recommended route. Remains confirmed by source pending that.
Impact
Heap out-of-bounds read of up to ~6 bytes in the HTJ2K MagSgn decoder on the default x86-64 SIMD
path, reachable from a crafted HT code-block. The over-read bytes are masked into the bit accumulator
and influence decoded output (minor info-leak flavor) and can fault on a hardened allocator / page
boundary. No OOB write; small bounded extent. Severity low (CVSS 4.0). Fix: raise
grk_cblk_dec_compressed_data_pad_ht to 16 (and the matching alloc/zero in CoderOJPH.cpp) to match
the SIMD reader’s documented look-ahead. NOTE: if lengths2 != 0 is ever passed (currently always 0,
so SPP/MRP are dead), the same 16-byte load in the SPP sigprop reader over-reads a full 8 bytes —
fix the pad regardless.