
gdk-pixbuf JPEGローダーにおけるヒープベースのバッファオーバーフロー
こんにちは、Kağan Çapar です。私は、実質的にすべてのLinuxデスクトップ環境に影響するgdk-pixbufのJPEG画像ローダーにおけるヒープベースのバッファオーバーフロー脆弱性を発見しました。この脆弱性には CVE-2026-5201 が割り当てられ、Red Hat によって CVSS スコア 7.5 (重要) として確認されました。
このリポジトリには、私の完全な分析、ゼロから作成した再現コード、および実際の Ubuntu 24.04 LTS システムでのクラッシュ証跡が含まれています。
| CVE | CVE-2026-5201 |
| CWE | CWE-122 — ヒープベースのバッファオーバーフロー |
| CVSS v3 | 7.5 (AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H) |
| 影響を受けるバージョン | 修正前の全バージョンのgdk-pixbuf |
| ベンダー | GNOME |
| 修正 | gdk-pixbuf@6cce931 |
| トラッカー | GNOME #304 |
| Bugzilla | Red Hat #2453291 |
私は gdk-pixbuf の JPEG 画像ローダー (io-jpeg.c) にヒープベースのバッファオーバーフローを発見しました。直接ファイルロードのパス (gdk_pixbuf__jpeg_image_load) は、ピクセルバッファを確保する前にカラーコンポーネント数を検証していません。SOFヘッダーに9コンポーネントを宣言しながらSOSで3コンポーネントのみをスキャンする、特別に細工された122バイトのJPEGにより、gdk-pixbuf は3チャンネル分のバッファを確保する一方、libjpeg はピクセルごとに9チャンネルを書き込みます — その結果、攻撃者が制御する最大約49KBのヒープオーバーフローが発生します。
インクリメンタルローダーのパスにはこの正確な検証が既にありましたが、直接ロードのパスには欠落していました。
gdk_pixbuf_new_from_file() を使用するあらゆるアプリケーションで100%再現性のあるクラッシュg_class)がピクセルデータで上書きされるgdk-pixbuf/io-jpeg.c 内の関数 gdk_pixbuf__jpeg_image_load() について:
1. 過小なメモリ確保 (633行目):
pixbuf = gdk_pixbuf_new(GDK_COLORSPACE_RGB,
cinfo->out_color_components == 4 ? TRUE : FALSE,
8, cinfo->output_width, cinfo->output_height);
2. 過大な書き込み (696行目):
jpeg_read_scanlines(cinfo, lines, cinfo->rec_outbuf_height);
// writes output_components (9) bytes per pixel into a 3-byte buffer
3. 検証の欠落 — インクリメンタルローダーは既に 1142行目 で output_components をチェックしているが、直接ロードのパスにはこのチェックが存在しなかった。
python3 reproducer/craft_cve_2026_5201.py
これにより、SOF10ヘッダーに9コンポーネント、SOSでスキャンされるのは3コンポーネントだけの122バイトのJPEGファイルが作成されます。
# 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
==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
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
修正では、インクリメンタルローダーに既に存在するのと同じ output_components 検証を追加しています:
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;
}
修正は gdk-pixbuf@6cce931 で適用されました。
| 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 |
CVE-2017-2862 (Cisco Talos TALOS-2017-0366) — CVSS 8.8 — gdk-pixbuf における同じ null_convert バッファ不一致バグ分類で、リモートコード実行 (Remote Code Execution) に分類されています。
Kağan Çapar — GitHub · LinkedIn · X
Red Hat による CVE-2026-5201 セキュリティアドバイザリ で確認済み。
| 製品 | コンポーネント | ステータス |
|---|
| Red Hat Enterprise Linux 10 | gdk-pixbuf2 | 影響あり |
| Red Hat Enterprise Linux 10 | loupe | 影響あり |
| Red Hat Enterprise Linux 10 | snapshot | 影響あり |
| Red Hat Enterprise Linux 9 | gdk-pixbuf2 | 影響あり |
| Red Hat Enterprise Linux 8 | gdk-pixbuf2 | 影響あり |
| Red Hat Enterprise Linux 7 | gdk-pixbuf2 | 影響あり |