Share
## https://sploitus.com/exploit?id=E83D35A6-9C47-58A3-80BC-279B00AB3E86
# CVE-2026-5201

**Heap-based buffer overflow in gdk-pixbuf JPEG loader**

Hi, I'm [Kağan Çapar](https://github.com/kagancapar). I discovered a heap-based buffer overflow vulnerability in gdk-pixbuf's JPEG image loader that affects virtually all Linux desktop environments. The vulnerability was assigned **CVE-2026-5201** and acknowledged by [Red Hat](https://access.redhat.com/security/cve/CVE-2026-5201) with a CVSS score of **7.5 (Important)**.

This repository contains my full analysis, a reproducer I wrote from scratch, and the crash evidence from a live Ubuntu 24.04 LTS system.

| | |
|---|---|
| **CVE** | [CVE-2026-5201](https://vulners.com/cve/CVE-2026-5201) |
| **CWE** | [CWE-122](https://cwe.mitre.org/data/definitions/122.html) — Heap-based Buffer Overflow |
| **CVSS v3** | **7.5** (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H) |
| **Affected** | gdk-pixbuf (all versions before fix) |
| **Vendor** | GNOME |
| **Fix** | [gdk-pixbuf@6cce931](https://gitlab.gnome.org/GNOME/gdk-pixbuf/-/commit/6cce9311e70b969cbcc6e3e1e74ae1756ed02d5b) |
| **Tracker** | [GNOME #304](https://gitlab.gnome.org/GNOME/gdk-pixbuf/-/issues/304) |
| **Bugzilla** | [Red Hat #2453291](https://bugzilla.redhat.com/show_bug.cgi?id=2453291) |

## Summary

I found a heap-based buffer overflow in gdk-pixbuf's JPEG image loader (`io-jpeg.c`). The direct file loading path (`gdk_pixbuf__jpeg_image_load`) does not validate the number of color components before allocating a pixel buffer. A specially crafted 122-byte JPEG with 9 components declared in the SOF header but only 3 scanned in SOS causes gdk-pixbuf to allocate a buffer for 3 channels while libjpeg writes 9 channels per pixel — resulting in a heap overflow of up to ~41 KB of attacker-controlled data.

The incremental loader path already had this exact validation, but it was missing from the direct loading path.

## Impact

- **Denial of Service**: 100% reliable crash on any application using `gdk_pixbuf_new_from_file()`
- **Heap corruption**: GObject vtable pointer (`g_class`) overwritten with pixel data
- **Code execution**: Demonstrated on 32-bit Linux via vtable hijack
- **Affected systems**: All Linux desktops — Ubuntu, Fedora, Debian, Arch, RHEL 7–10

## Affected Red Hat Products

| Product | Component | Status |
|---------|-----------|--------|
| Red Hat Enterprise Linux 10 | gdk-pixbuf2 | Affected |
| Red Hat Enterprise Linux 10 | loupe | Affected |
| Red Hat Enterprise Linux 10 | snapshot | Affected |
| Red Hat Enterprise Linux 9 | gdk-pixbuf2 | Affected |
| Red Hat Enterprise Linux 8 | gdk-pixbuf2 | Affected |
| Red Hat Enterprise Linux 7 | gdk-pixbuf2 | Affected |

## Root Cause

In `gdk-pixbuf/io-jpeg.c`, the function `gdk_pixbuf__jpeg_image_load()`:

**1. Undersized allocation** ([line 633](https://gitlab.gnome.org/GNOME/gdk-pixbuf/-/blob/master/gdk-pixbuf/io-jpeg.c#L633)):
```c
pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
                        cinfo->out_color_components == 4 ? TRUE : FALSE,
                        8, cinfo->output_width, cinfo->output_height);
```

**2. Oversized write** ([line 696](https://gitlab.gnome.org/GNOME/gdk-pixbuf/-/blob/master/gdk-pixbuf/io-jpeg.c#L696)):
```c
jpeg_read_scanlines(cinfo, lines, cinfo->rec_outbuf_height);
// writes output_components (9) bytes per pixel into a 3-byte buffer
```

**3. Missing validation** — the incremental loader already checks `output_components` at [line 1142](https://gitlab.gnome.org/GNOME/gdk-pixbuf/-/blob/master/gdk-pixbuf/io-jpeg.c#L1142), but this check was absent from the direct path.

## Reproduction

### Generate the reproducer

```bash
python3 reproducer/craft_cve_2026_5201.py
```

This creates a 122-byte JPEG file with 9 components in the SOF10 header and only 3 scanned in SOS.

### Trigger the crash

```bash
# Compile
gcc -o crash_test reproducer/crash_test.c \
    $(pkg-config --cflags --libs gdk-pixbuf-2.0) -fsanitize=address -g

# Run
./crash_test cve_2026_5201.jpg
```

### Expected output (AddressSanitizer)

```
==PID==ERROR: AddressSanitizer: SEGV on unknown address 0x52b000020006
==PID==The signal is caused by a WRITE memory access.
    #0  libjpeg.so.8  (null_convert)
    #1  libjpeg.so.8  (sep_upsample)
    #2  libjpeg.so.8  (process_data_context_main)
    #3  libjpeg.so.8  jpeg_read_scanlines
    #4  libgdk_pixbuf-2.0.so.0  (JPEG loader)
    #5  libgdk_pixbuf-2.0.so.0  gdk_pixbuf_new_from_file
```

### GDB output (without ASAN)

```
Program received signal SIGSEGV, Segmentation fault.
g_type_check_instance_is_fundamentally_a ()
  → g_object_unref()
  → gdk_pixbuf_new_from_file()

rax = 0x808080808080ffff    ← corrupted GObject vtable pointer
```

## Fix

The fix adds the same `output_components` validation that already exists in the incremental loader:

```c
jpeg_start_decompress(cinfo);

if (cinfo->output_components != 3 && cinfo->output_components != 4 &&
    !(cinfo->output_components == 1 &&
      cinfo->out_color_space == JCS_GRAYSCALE)) {
    g_set_error(error, GDK_PIXBUF_ERROR, GDK_PIXBUF_ERROR_CORRUPT_IMAGE,
                "Unsupported number of color components (%d)",
                cinfo->output_components);
    goto out;
}
```

Applied in [gdk-pixbuf@6cce931](https://gitlab.gnome.org/GNOME/gdk-pixbuf/-/commit/6cce9311e70b969cbcc6e3e1e74ae1756ed02d5b).

## Tested Environment

| | |
|---|---|
| OS | Ubuntu 24.04.1 LTS |
| gdk-pixbuf | 2.42.10+dfsg-3ubuntu3.2 |
| libjpeg | libjpeg-turbo 2.1.5 (libjpeg.so.8.2.2) |
| GCC | 13.3.0 |

## References

- https://vulners.com/cve/CVE-2026-5201
- https://nvd.nist.gov/vuln/detail/CVE-2026-5201
- https://gitlab.gnome.org/GNOME/gdk-pixbuf/-/issues/304
- https://access.redhat.com/security/cve/CVE-2026-5201
- https://bugzilla.redhat.com/show_bug.cgi?id=2453291

## Historical Precedent

[CVE-2017-2862](https://nvd.nist.gov/vuln/detail/CVE-2017-2862) (Cisco Talos TALOS-2017-0366) — CVSS 8.8 — same `null_convert` buffer mismatch bug class in gdk-pixbuf, classified as Remote Code Execution.

## Credit

**Kağan Çapar** — [GitHub](https://github.com/kagancapar) · [LinkedIn](https://linkedin.com/in/kagancapar) · [X](https://x.com/kagancapar)

*Acknowledged by Red Hat in the [CVE-2026-5201 advisory](https://access.redhat.com/security/cve/CVE-2026-5201).*