gdk-pixbuf JPEG Loader Heap Buffer Overflow — CVE-2026-5201
by Kağan Çapar (GitHub: kagancapar) — acknowledged by Red Hat · 2026-07-05
- Severity
- Important
- CVE
- CVE-2026-5201
- Category
- binary
- Affected product
- gdk-pixbuf (GNOME image loading library), JPEG loader (io-jpeg.c)
- Affected versions
- All gdk-pixbuf versions prior to commit 6cce9311e70b969cbcc6e3e1e74ae1756ed02d5b (fixed in 2.44.6); confirmed vulnerable on gdk-pixbuf 2.42.10 (Ubuntu 24.04 LTS) and 2.44.5
- Disclosed
- 2026-07-05
- Patch status
- patched
References
- https://github.com/kagancapar/CVE-2026-5201
- https://www.cve.org/CVERecord?id=CVE-2026-5201
- https://access.redhat.com/security/cve/CVE-2026-5201
- https://gitlab.gnome.org/GNOME/gdk-pixbuf/-/issues/304
- https://bugzilla.redhat.com/show_bug.cgi?id=2453291
- https://gitlab.gnome.org/GNOME/gdk-pixbuf/-/commit/6cce9311e70b969cbcc6e3e1e74ae1756ed02d5b
Archive entry
intelseclab/poc-archiveMetadata
| Field | Value |
|---|---|
| Date Added | 2026-07-05 |
| Last Updated | 2026-04 |
| Author / Researcher | Kağan Çapar (GitHub: kagancapar) — acknowledged by Red Hat |
| CVE / Advisory | CVE-2026-5201 |
| Category | binary |
| Severity | Important |
| CVSS Score | 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H, as stated in source repository / Red Hat advisory) |
| Status | PoC |
| Tags | gdk-pixbuf, jpeg, libjpeg, heap-overflow, gnome, gtk, linux-desktop, cwe-122, vtable-hijack |
| Related | CVE-2017-2862 (same bug class, prior gdk-pixbuf JPEG null_convert overflow) |
Affected Target
| Field | Value |
|---|---|
| Software / System | gdk-pixbuf (GNOME image loading library), JPEG loader (io-jpeg.c) |
| Versions Affected | All gdk-pixbuf versions prior to commit 6cce9311e70b969cbcc6e3e1e74ae1756ed02d5b (fixed in 2.44.6); confirmed vulnerable on gdk-pixbuf 2.42.10 (Ubuntu 24.04 LTS) and 2.44.5 |
| Language / Platform | Python (JPEG reproducer generator), C (crash/exploitation PoCs, ASan); target is native C (gdk-pixbuf/libjpeg) on Linux |
| Authentication Required | No |
| Network Access Required | No (local file processing); Red Hat’s CVSS vector marks AV:N/UI:N reflecting automated/server-side image processing scenarios |
Summary
gdk-pixbuf’s direct JPEG loading path (gdk_pixbuf__jpeg_image_load / gdk_pixbuf__real_jpeg_image_load in io-jpeg.c) allocates the output pixel buffer based on the expected number of color components (3 for RGB, 4 for CMYK) without validating that libjpeg’s actual output_components value matches. A crafted 122-byte JPEG that declares 9 components in its SOF10 header but only scans 3 in the SOS marker causes libjpeg to decode 9 bytes per pixel into a buffer sized for 3, an approximately 49KB heap overflow for the PoC’s dimensions. This repository includes a Python reproducer that generates the malicious JPEG, C crash-test/AddressSanitizer harnesses that demonstrate the overflow and resulting corruption of adjacent GObject vtable pointers, and detailed bilingual (English/Turkish) writeups covering root cause, exploitation primitives (including a demonstrated 32-bit RCE via dispose() function-pointer hijack and an ASLR-bypass technique), and the official upstream fix.
Vulnerability Details
Root Cause
In gdk-pixbuf/io-jpeg.c, the direct file-loading path allocates the pixbuf using cinfo->out_color_components (line ~633) to decide the buffer’s channel count, but does not check cinfo->output_components against the allowed values (3, 4, or 1-for-grayscale) before calling jpeg_read_scanlines() (line ~696), which writes output_components bytes per pixel as reported by libjpeg. The incremental loader path (GdkPixbufLoader) already contains this exact validation (line ~1142), but it is missing from the direct-loading path, creating an inconsistency where the same malformed JPEG is safely rejected by one path and triggers a heap overflow through the other.
Attack Vector
- Attacker crafts a 122-byte JPEG with a SOF10 (arithmetic sequential DCT) header declaring 9 color components but a SOS marker that only scans 3 of them, sized 8224x1 pixels.
- Victim application calls
gdk_pixbuf_new_from_file()(or any API using the direct-loading path) on the crafted file — e.g., an image viewer, file manager, or automated/server-side image-processing pipeline. - gdk-pixbuf allocates an undersized buffer (
8224 x 3 = 24,672bytes) based on the RGB/CMYK assumption. - libjpeg’s
null_convert()writes8224 x 9 = 74,016bytes into that buffer — a 49,344-byte overflow — corrupting adjacent heap memory, including a neighboring GObject’sg_classvtable pointer. - When
g_object_unref()is later called, it dereferences the corrupted vtable pointer, leading to a crash (64-bit) or, as demonstrated in the repo, adispose()function-pointer hijack enabling arbitrary code execution (32-bit, and shown as achievable via partial-pointer-overwrite/ASLR-bypass techniques on 64-bit primitives).
Impact
Reliable (100%) crash/denial of service in any application using gdk_pixbuf_new_from_file(); heap corruption of adjacent GObject structures; demonstrated code execution on 32-bit Linux via GObject vtable dispose() hijack, with the repo documenting (but not weaponizing end-to-end) the additional primitives — deterministic heap layout and partial-pointer ASLR bypass — relevant to 64-bit exploitation.
Environment / Lab Setup
Target: Ubuntu 24.04.1 LTS, gdk-pixbuf 2.42.10+dfsg-3ubuntu3.2,
libjpeg-turbo 2.1.5 (libjpeg.so.8.2.2), GCC 13.3.0, glibc 2.39
Attacker: Python 3 (reproducer generator), GCC + AddressSanitizer,
pkg-config with gdk-pixbuf-2.0 development headers
Proof of Concept
PoC Script
See
reproducer/craft_cve_2026_5201.py,reproducer/cve_2026_5201.jpg,poc/crash_test.c,poc/rce_32bit.c,poc/rce_shell.c,poc/aslr_bypass.c,poc/find_dispose.c,poc/heap_analysis.c,poc/pixel_control_test.c,poc/analyze_jpeg.py,patch/0001-io-jpeg-Fix-heap-buffer-overflow.patch, and the full writeups inwriteup-en/andwriteup-tr/in this folder.
| |
craft_cve_2026_5201.py builds the minimal malformed JPEG (SOF10 with 9 declared components, SOS scanning only 3). crash_test.c loads the file via both gdk_pixbuf_new_from_file() (vulnerable direct path) and GdkPixbufLoader (safe incremental path) to demonstrate the discrepancy; the other poc/*.c files (rce_32bit.c, rce_shell.c, aslr_bypass.c, find_dispose.c) further explore the GObject vtable corruption and its exploitation into RCE primitives.
Detection & IOCs
Signs of compromise:
- Applications using
gdk_pixbuf_new_from_file()crashing while loading a JPEG file - Crash reports/tombstones referencing
null_convert,sep_upsample, org_object_unrefshortly after JPEG loading - JPEG files with a SOF header declaring more color components than are present in the corresponding SOS scan
Remediation
| Action | Detail |
|---|---|
| Primary fix | Update gdk-pixbuf to 2.44.6 or later, which includes the output_components validation fix (commit 6cce9311e70b969cbcc6e3e1e74ae1756ed02d5b, matching the included patch/0001-io-jpeg-Fix-heap-buffer-overflow.patch) |
| Interim mitigation | Avoid processing untrusted JPEG files via direct-loading APIs (gdk_pixbuf_new_from_file()); where possible, route untrusted images through sandboxed/incremental loaders or a separately-patched libjpeg wrapper until updated |
References
- Source repository
- CVE Record
- Red Hat Security Advisory
- GNOME gdk-pixbuf Issue #304
- Red Hat Bugzilla #2453291
- Fix commit
Notes
Mirrored from https://github.com/kagancapar/CVE-2026-5201 on 2026-07-05.