Hacktoberfest 2026:メンテナが10月に向けて印を付けた、オープンで初心者向けの issue。 Hacktoberfest の issue を見る

[BUG] Heap buffer overflow in parse_PMT with C0/C1 section length

オープン 初心者向け
#2,419 コメント 0 件 リアクション 0 件 担当者 0 名 GitHub で見る

メンテナーはふだん 1 日以内に返信

@kun-codes がすでに取り組んでいます。

2026年10月22日 から。

  • #2420 @kun-codes による — オープン

評価

難易度
2/5
見積もり時間
1〜3時間
初心者へのやさしさ
78/100
issue の種類
バグ
明瞭さ
明確に書かれている
活発さ
活発
技術スタック
c
領域
backend

調査の方向性

src/lib_ccx/ts_tables.c の parse_PMT から始めます。issue では、C0/C1 セクション長の処理と安全でない memmove が指摘されています。PSI バッファの長さがどのように追跡されているかを確認し、添付の pmt_c0.py と issue に記載された AddressSanitizer ビルドコマンドを使って再現します。バッファに格納されたデータより長いセクションを拒否し、報告されたオーバーフローを回避できれば完了です。issue によると、最小限のパッチが用意されています。

索引モデルが issue の本文から書いたものです。

説明

CCExtractor version: 0.96.5 (master d7eb132)

Necessary information

  • Is this a regression (i.e. did it work before)? NO The 0xC1 path dates to 2016 and the 0xC0 memmove to 2020; neither has changed since.
  • What platform did you use? Linux
  • What were the used arguments? pmt_c0.ts --ts

Video links

Not a video. The reproducer generator is attached: pmt_c0.py.

pmt_c0.py

It writes pmt_c0.ts (376 bytes).

Additional information

parse_PMT() handles the SCTE 57 Program Information and Program Name tables (table_id 0xC0/0xC1) by stripping them from the front of the PSI buffer before parsing the PMT that follows. The 12-bit section length is read directly from the input and used without checking it against the number of bytes actually buffered:

unsigned c0length = (buf[1] << 8 | buf[2]) & 0xFFF;
memmove(buf, buf + c0length + 3, len - c0length - 3);

If c0length + 3 is larger than len, the size expression wraps to a value near 2^32 and memmove() reads and writes far outside the 184-byte PSI buffer. This is not limited to deliberately malformed input: a valid C0/C1 section that spans multiple TS packets also hits it, because the memmove() runs before the code checks whether the whole section has been buffered.

Reproduce
  1. Run the attached pmt_c0.py; it creates pmt_c0.ts.

  2. Build with AddressSanitizer. GPAC is required (libgpac-dev on Debian/Ubuntu):

cmake -S src -B build-asan -G Ninja \
  -DCMAKE_BUILD_TYPE=Debug \
  -DCMAKE_C_COMPILER=clang \
  -DCMAKE_CXX_COMPILER=clang++ \
  -DCMAKE_C_FLAGS="-fsanitize=address -fno-omit-frame-pointer -g -O1" \
  -DCMAKE_CXX_FLAGS="-fsanitize=address -fno-omit-frame-pointer -g -O1" \
  -DCMAKE_EXE_LINKER_FLAGS="-fsanitize=address"

cmake --build build-asan -j"$(nproc)"
  1. Run:
ASAN_OPTIONS=detect_leaks=0 ./build-asan/ccextractor pmt_c0.ts --ts

The generated file contains a PAT mapping program 1 to PID 0x100, followed by a PMT packet with table_id = 0xC0 and section_length = 0xFFF.

ASan report (addresses and build IDs vary between builds)
=================================================================
==163035==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x7c26841e9b43 at pc 0x559fcb8def54 bp 0x7ffff843f7d0 sp 0x7ffff843ef90
READ of size 4294963381 at 0x7c26841e9b43 thread T0
    #0 0x559fcb8def53 in __asan_memmove (/tmp/ccextractor-parent/build-asan/ccextractor+0x225f53) (BuildId: e6eef4c3fe76d03bb70bfcaa782da599722b0bb6)
    #1 0x559fcbba5ffb in parse_PMT /tmp/ccextractor-parent/src/lib_ccx/ts_tables.c
    #2 0x559fcbba2614 in ts_readstream /tmp/ccextractor-parent/src/lib_ccx/ts_functions.c:847:9
    #3 0x559fcbba3e74 in ts_get_more_data /tmp/ccextractor-parent/src/lib_ccx/ts_functions.c:1098:9
    #4 0x559fcbb71013 in general_loop /tmp/ccextractor-parent/src/lib_ccx/general_loop.c:1443:9
    #5 0x559fcb9c8f13 in start_ccx /tmp/ccextractor-parent/src/ccextractor.c:199:11
    #6 0x7f269b227780 in __libc_start_call_main (/usr/src/debug/glibc/glibc/csu/../sysdeps/nptl/libc_start_call_main.h:59:16)
    #7 0x7f269b2278b8 in __libc_start_main (/usr/src/debug/glibc/glibc/csu/../csu/libc-start.c:372:3)
    #8 0x559fcb82dfc4 in _start (/tmp/ccextractor-parent/build-asan/ccextractor+0x174fc4) (BuildId: e6eef4c3fe76d03bb70bfcaa782da599722b0bb6)

0x7c26841e9b43 is located 3915 bytes after 184-byte region [0x7c26841e8b40,0x7c26841e8bf8)
allocated by thread T0 here:
    #0 0x559fcb8e1394 in malloc (/tmp/ccextractor-parent/build-asan/ccextractor+0x228394) (BuildId: e6eef4c3fe76d03bb70bfcaa782da599722b0bb6)
    #1 0x559fcbba8814 in ts_buffer_psi_packet /tmp/ccextractor-parent/src/lib_ccx/ts_tables.c:590:46
    #2 0x559fcbba257e in ts_readstream /tmp/ccextractor-parent/src/lib_ccx/ts_functions.c:845:4
    #3 0x559fcbba3e74 in ts_get_more_data /tmp/ccextractor-parent/src/lib_ccx/ts_functions.c:1098:9
    #4 0x559fcbb71013 in general_loop /tmp/ccextractor-parent/src/lib_ccx/general_loop.c:1443:9
    #5 0x559fcb9c8f13 in start_ccx /tmp/ccextractor-parent/src/ccextractor.c:199:11
    #6 0x7f269b227780 in __libc_start_call_main (/usr/src/debug/glibc/glibc/csu/../sysdeps/nptl/libc_start_call_main.h:59:16)
    #7 0x7f269b2278b8 in __libc_start_main (/usr/src/debug/glibc/glibc/csu/../csu/libc-start.c:372:3)
    #8 0x559fcb82dfc4 in _start (/tmp/ccextractor-parent/build-asan/ccextractor+0x174fc4) (BuildId: e6eef4c3fe76d03bb70bfcaa782da599722b0bb6)

SUMMARY: AddressSanitizer: heap-buffer-overflow (/tmp/ccextractor-parent/build-asan/ccextractor+0x225f53) (BuildId: e6eef4c3fe76d03bb70bfcaa782da599722b0bb6) in __asan_memmove
Shadow bytes around the buggy address:
  0x7c26841e9880: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7c26841e9900: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7c26841e9980: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7c26841e9a00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7c26841e9a80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
=>0x7c26841e9b00: fa fa fa fa fa fa fa fa[fa]fa fa fa fa fa fa fa
  0x7c26841e9b80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7c26841e9c00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7c26841e9c80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7c26841e9d00: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
  0x7c26841e9d80: fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa fa
Shadow byte legend (one shadow byte represents 8 application bytes):
  Addressable:           00
  Partially addressable: 01 02 03 04 05 06 07 
  Heap left redzone:       fa
  Freed heap region:       fd
  Stack left redzone:      f1
  Stack mid redzone:       f2
  Stack right redzone:     f3
  Stack after return:      f5
  Stack use after scope:   f8
  Global redzone:          f9
  Global init order:       f6
  Poisoned by user:        f7
  Container overflow:      fc
  Array cookie:            ac
  Intra object redzone:    bb
  ASan internal:           fe
  Left alloca redzone:     ca
  Right alloca redzone:    cb
==163035==ABORTING

The section should be rejected when c0length + 3 > len, and len should be reduced by c0length + 3 after the move. I have a minimal patch that does both and can open a PR.

主要言語
C
スター
912
フォーク
598
平均マージ
2日 17時間
マージ済み PR(30日)
30

環境構築

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

CCExtractor/ccextractor のほかの issue

CCExtractor/ccextractor の issue をすべて見る

似ている issue

C の issue をもっと見る

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。