# ImageSharp: HistogramEqualization uses an unvalidated luminance as an unchecked histogram index

Positive-infinity float samples in a crafted TIFF decode to non-finite HalfVector4 luminance, used unchecked as a histogram index in HistogramEqualization, crashing the process.

- Payout: Research
- Severity: high
- Program: ImageSharp
- Found by: MegaManSec
- Disclosed: 2026-10-07
- CVE: CVE-2026-106113
- Write-up quality: 7/10
- Original: https://github.com/advisories/GHSA-j3p4-wp97-rph4
- Library page: https://bugbountylibrary.com/r/ghsa%3AGHSA-j3p4-wp97-rph4
- Tags: area:os domain:desktop domain:oss impact:dos kind:research platform:ghsa sev:high tech:dotnet technique:source-review vuln:dos vuln:memory-corruption

**Target:** SixLabors.ImageSharp TIFF decoder + HistogramEqualization processor
**Root cause:** ColorNumerics.GetBT709Luminance can return a non-finite/out-of-range value for HalfVector4 pixels decoded from IEEE float TIFF samples (e.g. +Infinity); GrayscaleLevelsRowOperation.Invoke uses it directly as an Unsafe.Add offset into the histogram without bounds validation.
**Steps:**
1. Craft a valid 8x1 uncompressed TIFF with BitsPerSample=32, SampleFormat=3 (IEEE float), SamplesPerPixel=1, StripByteCounts=width*4, and pixel samples set to `float.PositiveInfinity`.
2. Load via `Image.Load<HalfVector4>(tiff)`; decoded pixel becomes `<Infinity, Infinity, Infinity, 1>`.
3. Call `image.Mutate(x => x.HistogramEqualization())`.
4. Observe `AccessViolationException` in `GrayscaleLevelsRowOperation.Invoke` (exit 133/134); control with sample `0.5` completes normally.
**How found:** Reporter reasoned that TIFF IEEE float samples can carry non-finite values into HalfVector4 components, then traced the histogram-equalization path to an unchecked Unsafe.Add offset derived from luminance, and confirmed with a minimal crafted TIFF across multiple releases.
**Exploitation:** Attacker supplies a malicious 32-bit float TIFF to an app that decodes it as Image<HalfVector4> and runs HistogramEqualization; the non-finite luminance indexes outside the histogram buffer, causing an out-of-bounds write/read and process termination (DoS). No code execution or data exfil demonstrated.
**Insight:** When a pixel format can hold non-finite floats (Half/float TIFF, EXR), any downstream code that converts pixel values to integer indices (histograms, LUTs, binning) is a candidate for OOB; test with +Inf/NaN samples rather than only extreme finite values.

## Proof of concept (copied exactly from the original report)

**Dockerfile building and running the PoC**

```
FROM mcr.microsoft.com/dotnet/sdk:8.0
WORKDIR /work
COPY j3p4.csproj Program.cs ./
RUN printf '%s\n' '<Project Sdk="Microsoft.NET.Sdk"><PropertyGroup><TargetFramework>net8.0</TargetFramework></PropertyGroup><ItemGroup><PackageReference Include="SixLabors.ImageSharp" Version="4.1.1" /></ItemGroup></Project>' > fetch.csproj \
    && dotnet restore fetch.csproj --nologo \
    && rm fetch.csproj \
    && dotnet build j3p4.csproj -c Release --nologo -v quiet
ENTRYPOINT ["dotnet", "/work/bin/Release/net8.0/j3p4.dll"]
```

**Docker run commands for exploit and control**

```
docker build -t imagesharp-j3p4-poc .
docker run --rm imagesharp-j3p4-poc exploit
docker run --rm imagesharp-j3p4-poc control
```

