[Security] NULL pointer dereference (SEGV at address 0x0) in sei_message() when parsing a crafted MP4 file
メンテナーはふだん 7 日以内に返信
評価
調査の方向性
Start in the sei_rbsp() loop in src/lib_ccx/avc_functions.c (around lines 366-412), where the NULL return from sei_message() is not checked before the next iteration reads through it. Reproduce by building with AddressSanitizer and running the attached crash-input.bin, which should currently abort in sei_message. Done means the crafted input exits without a SEGV and a truncated SEI is handled as an error. Because this is a security report, check with maintainers before opening a public fix.
索引モデルが issue の本文から書いたものです。
説明
1. Summary
CCExtractor (master commit d7eb132e15f4d1e2c40f4655349596b2b8f708de, version string 0.96.5) crashes with a NULL pointer dereference while parsing a crafted MP4 file. During GPAC-based MP4 processing of an AVC video track, process_avc_sample() (src/lib_ccx/mp4.c:100) hands a SEI NAL unit to sei_rbsp() (src/lib_ccx/avc_functions.c:366). The loop in sei_rbsp() does not handle the NULL return value of sei_message(): sei_message() returns NULL (src/lib_ccx/avc_functions.c:401/412) when the SEI payload-type/payload-size field (a run of 0xFF bytes) extends to the end of the NAL, and the next loop iteration dereferences that NULL pointer at src/lib_ccx/avc_functions.c:395. Under AddressSanitizer the process aborts with "SEGV on unknown address 0x000000000000 ... READ memory access ... in sei_message". The defect is a denial of service: any tool or pipeline that runs ccextractor on a malicious MP4 file can be crashed.
2. Affected version / environment
- Project: CCExtractor (https://github.com/CCExtractor/ccextractor)
- Version: version string 0.96.5, master branch commit d7eb132e15f4d1e2c40f4655349596b2b8f708de (source dated 2026-10-17, binary compiled 2026-10-26)
- Environment: Linux x86_64 (Ubuntu container), ccextractor built with AddressSanitizer, statically linked; libGPAC 2.0; default CLI options, output target .srt
- Component: src/lib_ccx/avc_functions.c (sei_message / sei_rbsp), reached via src/lib_ccx/mp4.c:100 (process_avc_sample) through the GPAC MP4 demux path
3. Steps to reproduce
1. Build ccextractor at master commit d7eb132e15f4d1e2c40f4655349596b2b8f708de with AddressSanitizer (any recent clang/gcc with -fsanitize=address works).
2. Save the attached crash-input.bin (SHA-256 f6bbb40d2694e61029e0b0394af4633283447b5a919b7c2b56f12e1fde86e3ce, a malformed MP4 file, 85,748 bytes).
3. Run: ccextractor crash-input.bin
(verification used: env ASAN_OPTIONS=abort_on_error=0:symbolize=1:detect_leaks=0:allocator_may_return_null=1:print_legend=0:malloc_context_size=0 /lh/ccextractor/src/build/ccextractor /lh/tmp/poc-export/ccx-sei/crash-input.bin inside the container)
4. Observe the process abort with an AddressSanitizer SEGV report while "Processing track 1, type=vide subtype=avc1".
5. Negative control: a valid MPEG-TS file (negative-control.bin, SHA-256 8cc876f39877677b17319e64d3577aa7ce1ae1ef1bfa5ffd14f0cf1b7f823ff2) processes to completion with no sanitizer report, confirming the crash is input-specific.
4. Expected behavior
ccextractor should detect the malformed SEI NAL unit, report/skip it, and exit normally (or with a controlled error message) without dereferencing a NULL pointer.
5. Actual behavior
AddressSanitizer:DEADLYSIGNAL
=================================================================
==1826035==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x563d9ee4e716 bp 0x7fff50c2fff0 sp 0x7fff50c2ff50 T0)
==1826035==The signal is caused by a READ memory access.
==1826035==Hint: address points to the zero page.
#0 0x563d9ee4e716 in sei_message /lh/ccextractor/src/src/lib_ccx/avc_functions.c:395:28
#1 0x563d9ee4e716 in sei_rbsp /lh/ccextractor/src/src/lib_ccx/avc_functions.c:371:10
#2 0x563d9ee4cb4f in do_NAL /lh/ccextractor/src/src/lib_ccx/avc_functions.c
#3 0x563d9ede5f6c in process_avc_sample /lh/ccextractor/src/src/lib_ccx/mp4.c:100:4
#4 0x563d9ede5f6c in process_avc_track /lh/ccextractor/src/src/lib_ccx/mp4.c:295:13
#5 0x563d9ede5f6c in processmp4 /lh/ccextractor/src/src/lib_ccx/mp4.c:989:9
#6 0x563d9eae34e0 in start_ccx /lh/ccextractor/src/src/ccextractor.c:252:12
SUMMARY: AddressSanitizer: SEGV /lh/ccextractor/src/src/lib_ccx/avc_functions.c:395:28 in sei_message
6. Impact
Denial of service (CWE-476, NULL pointer dereference). A crafted MP4 file makes ccextractor dereference a NULL pointer and crash on every run, so any automated transcoding/caption-extraction pipeline that feeds user-supplied media to ccextractor can be interrupted by a single small file. No memory corruption, information disclosure, or code execution is involved: the faulting access is a read at address 0x0.
7. Suggested fix
In sei_rbsp() (src/lib_ccx/avc_functions.c:369-372) the loop ignores the NULL that sei_message() returns when the SEI header fields run past the end of the NAL unit; on the next iteration the NULL is dereferenced at line 395. Guarding the loop, e.g.
while (tbuf < seiend - 1)
{
tbuf = sei_message(ctx, tbuf, seiend - 1);
if (tbuf == NULL)
break;
}
(or treating a NULL return like the existing "unexpected SEI unit length" path) stops the crash; optionally also validate the payload_type/payload_size varint parsing in sei_message() so a truncated SEI is reported once instead of silently returning NULL.
8. Additional context (PoC / logs, redacted)
- Attached: crash-input.bin (malformed MP4, ftyp/free/mdat boxes, one avc1 video track; SHA-256 f6bbb40d2694e61029e0b0394af4633283447b5a919b7c2b56f12e1fde86e3ce)
- Negative control attached: negative-control.bin (valid MPEG-TS transport stream, SHA-256 8cc876f39877677b17319e64d3577aa7ce1ae1ef1bfa5ffd14f0cf1b7f823ff2) — runs clean
- Crash discovered by coverage-guided fuzzing of the master build; full sanitizer transcript archived in the verification environment; terminal screenshots of the live reproduction are available on request.
- No reproduction was attempted on any other version; affected range is therefore not asserted beyond the tested commit.
- 主要言語
- C
- スター
- 913
- フォーク
- 603
- 平均マージ
- 6日 8時間
- マージ済み PR(30日)
- 33
環境構築
- Dockerfile・Docker Compose ファイルなし
- プルリクエストのテンプレートあり
- コントリビューションガイドを読む
はじめの一歩
- issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
- 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
- リポジトリをフォークし、ブランチを切って変更します。
- issue 番号を参照したプルリクエストを送ります。
CCExtractor/ccextractor のほかの issue
-
[BUG] MXF: update_tid_lut() writes past tracks[32] onto nb_tracks, turning a file-supplied track id into the write offset対応中かも @pranayr710 が今日担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
CCExtractor/ccextractor#2457 ·
メンテナーはふだん 7 日以内に返信
-
[Security] Heap buffer overflow (OOB read past GPAC sample buffer) in process_avc_sample() at mp4.c:99 when parsing a crafted MP4 file対応中かも @yasar710 が 6 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 74/100
CCExtractor/ccextractor#2449 ·
メンテナーはふだん 7 日以内に返信
-
[BUG] DVB subtitle decoder: heap-buffer-overflow write in dvbsub_parse_clut_segment via unbounded entry_id対応中かも @Aditya-Saroha が 9 日前に担当しました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
CCExtractor/ccextractor#2440 ·
メンテナーはふだん 7 日以内に返信
-
[BUG] Filename sequence expansion (`+`) panics on numeric values exceeding `i32::MAX`再び着手できるかも このイシューのプルリクエストはマージされずにクローズされました。 オープン
難易度 2/5 1〜3時間 初心者へのやさしさ 82/100
CCExtractor/ccextractor#2402 ·
メンテナーはふだん 7 日以内に返信
-
[BUG] CEA-708 .srt is written as Latin-1 and ignores --utf8/--latin1/--unicode対応中かも このイシューにリンクされたプルリクエストがオープン中、またはマージ済みです。 オープン
難易度 3/5 1〜2日 初心者へのやさしさ 65/100
CCExtractor/ccextractor#2450 · コメント 3 件 ·
メンテナーはふだん 7 日以内に返信
CCExtractor/ccextractor の issue をすべて見る
似ている issue
-
難易度 2/5 1〜3時間 初心者へのやさしさ 72/100
tursodatabase/libsql#2312 ·
メンテナーはふだん 11 日以内に返信
-
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
-
難易度 2/5 1〜3時間 初心者へのやさしさ 78/100
メンテナーはふだん 1 日以内に返信
-
follow-up Prio 📌
難易度 1/5 1時間未満 初心者へのやさしさ 84/100
メンテナーはふだん 1 日以内に返信
-
area: test kind: bug preview-effort: small priority: low
難易度 2/5 1〜3時間 初心者へのやさしさ 65/100
メンテナーはふだん 1 日以内に返信