# ImageSharp: Tiled fax TIFF: tile buffer sized by TileWidth but fax decompressor writes scanlines of ImageWidth — heap OOB write

Tiled fax-compressed TIFF in ImageSharp sizes tile buffers by TileWidth but the T4/T6/MH decompressor writes ImageWidth-wide scanlines, causing heap OOB write and crash.

- Payout: Research
- Severity: high
- Program: ImageSharp
- Found by: KimiSecurityTeam
- Disclosed: 2026-10-07
- CVE: CVE-2026-106118
- Write-up quality: 8/10
- Original: https://github.com/advisories/GHSA-v76p-62qx-wwq2
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-v76p-62qx-wwq2
- Tags: area:os domain:desktop domain:oss impact:dos impact:rce kind:research platform:ghsa sev:high tech:dotnet technique:source-review vuln:dos vuln:memory-corruption

**Target:** TiffDecoderCore.DecodeTilesChunky / T4-T6-MH fax decompressor
**Root cause:** Tile buffer is allocated from TileWidth*bpp*TileLength, but TiffDecompressorsFactory drops isTiled/tileWidth/tileHeight and constructs the fax decompressor with frame.Width, so each row advances ImageWidth bits with no bounds check against the tile buffer.
**Steps:**
1. Craft a tiled TIFF with TileWidth=16, TileLength=16, Compression=3 (T4), ImageWidth=4,000,000, rows of 400 makeup codes + EOL.
2. Call `Image.Load(stream)` on the file (default config).
3. DecodeTilesChunky allocates a 32-byte tile buffer from TileWidth.
4. CreateDecompressor receives frame.Width; factory ignores tile params.
5. T4 decompressor writes ~2,048,000 bytes per tile into the 32-byte buffer via `BitWriterUtils.WriteBits`, triggering AccessViolationException / abort.
**How found:** Code review of the tiled decode path: noticed tile buffer sized from TileWidth while the decompressor factory signature accepts tile params but passes only frame.Width to T4/T6/MH, then confirmed the write sink advances this.width bits per row unchecked.
**Exploitation:** Attacker supplies a crafted tiled fax TIFF to any service calling Image.Load; per-tile OOB length and row width are attacker-tunable, giving deterministic DoS and a heap-corruption surface potentially leading to code execution.
**Insight:** When a factory takes tile/strip parameters but the concrete decompressor only receives width, check whether the caller's buffer is sized by tile dimensions while the writer uses frame dimensions — the mismatch is a direct OOB write.

