[BUG] SIGSEGV in tlt_read_rcwt(): rcwt_loop re-checks parsebuf[6..7] after it was overwritten with caption data (608-mode RCWT)
I maintainer di solito rispondono entro 1 giorno
Valutazione
- Difficoltà
- 3/5
- Tempo stimato
- 1-2 giorni
- Idoneità per principianti
- 72/100
Direzione di ricerca
Start in src/lib_ccx/general_loop.c at rcwt_loop() and trace where parsebuf is reused after the RCWT header is validated. Reproduce with the 83-byte sample and ccextractor crash.rcwt, then check the 608-mode branch and teletext-mode behavior. Done when the crash is fixed and both modes retain their expected output; the issue reports local validation but does not name test files.
Scritto dal modello di indicizzazione a partire dal testo della issue.
Descrizione
CCExtractor version: 0.96.5, git master d7eb132e (built from source on 2026-10-27)
In raising this issue, I confirm the following:
- I have read and understood the contributors guide.
- I have checked that the bug I am reporting can be replicated.
- I have checked that this issue isn't already reported in closed issues and in open issues.
- I have checked the pull requests tab for existing solutions/implementations.
- I have verified this on current master built from source.
Necessary information
- Is this a regression? No — the loop code involved dates back to 2015; I found it by code reading and confirmed it with AddressSanitizer.
- What platform did you use? Mac (macOS arm64, Apple clang; the crashing code is platform-independent C).
- What were the used arguments?
ccextractor crash.rcwt
Video links
- Sample (83 bytes): https://gist.github.com/VishnuSrivatsava/79a2d40af506ebabbfe925de9305fb08 — it is base64-encoded (
ghdoes not accept binary gists); decode withbase64 -d crash.rcwt.b64 > crash.rcwtand verify SHA2566565e25b9b773ee1ad2731eb3b07ed7266d8f7dfbf2e3601084cc6347ab8c701.
Additional information
Summary
rcwt_loop() (src/lib_ccx/general_loop.c) decides whether an RCWT input is a teletext file by testing parsebuf[6] == 0 && parsebuf[7] == 2 (the file-format revision bytes of the 11-byte header) at two places:
- Before the processing loop — correct,
parsebufstill holds the file header. - At the top of every loop iteration (line 1792 on master) — incorrect: in 608 mode
parsebufis reused for the 10-byte data header and thenrealloc'd and overwritten with the raw caption-block bytes.
If the caption byte stream contains 00 02 at offsets 6–7, iteration 2 takes the teletext branch even though the file is a 608-mode RCWT. In that mode dec_ctx->private_data is NULL (telxcc_init() only runs in teletext mode), so the branch calls tlt_read_rcwt(NULL, buf, dec_sub), which does memcpy(&(ctx->last_timestamp), &buf[1], sizeof(uint64_t)) (src/lib_ccx/telxcc.c:1327) → SIGSEGV.
00 02 at those offsets does not require a hand-crafted file: in RCWT caption blocks the bytes at positions 6–7 are raw CC data (e.g. a 00 marker byte followed by 02), which ordinary corruption or real caption content can produce.
Reproduction
$ base64 -d crash.rcwt.b64 > crash.rcwt
$ ccextractor crash.rcwt
Plain build on master d7eb132e: exit code 139 (SIGSEGV).
With an AddressSanitizer build:
==...==ERROR: AddressSanitizer: SEGV on unknown address 0x000000007700 (pc ... WRITE of size 8)
#0 tlt_read_rcwt telxcc.c:1327
#1 rcwt_loop general_loop.c:1801
#2 start_ccx ccextractor.c:217
The PoC is a minimal 608-mode RCWT file: valid 11-byte header (CC CC ED, revision 00 01), a data header with cbcount = 3, caption blocks 04 80 80 04 80 80 00 02 80 (bytes 6–7 = 00 02), plus 53 bytes so the hijacked teletext branch actually runs the NULL-context memcpy.
Proposed fix
Decide the mode once, right after the header is validated:
is_teletext = (parsebuf[6] == 0 && parsebuf[7] == 2);
and test is_teletext (not parsebuf[6..7]) inside the loop. I have this implemented and validated locally (PoC exits cleanly; a teletext-mode RCWT produces byte-identical output before/after; a 12-sample TS corpus shows no behavior change). Happy to open a PR with the patch if you agree with the approach.
- Lingua principale
- C
- Stelle
- 912
- Fork
- 598
- Merge medio
- 2g 17h
- PR unite (30g)
- 30
Preparare l'ambiente
- Nessun Dockerfile né file Docker Compose
- Ha un modello di pull request
- Leggi la guida per i contributori
Come iniziare
- Leggi tutta la issue e poi la guida ai contributi del progetto.
- Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
- Fai un fork del repository e lavora su un branch.
- Apri una pull request che faccia riferimento al numero della issue.
Altre issue di CCExtractor/ccextractor
-
Heap OOB read in parse_ad_cdp: cc_count not bounded by packet lengthForse già presa @Nikhil-jaiswal007 l’ha presa 3 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
CCExtractor/ccextractor#2425 · 1 commento ·
I maintainer di solito rispondono entro 1 giorno
-
[BUG] Heap buffer overflow in parse_PMT with C0/C1 section lengthForse già presa @kun-codes l’ha presa 6 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
CCExtractor/ccextractor#2419 ·
I maintainer di solito rispondono entro 1 giorno
-
[BUG] Filename sequence expansion (`+`) panics on numeric values exceeding `i32::MAX`Forse già presa @muntasir-396 l’ha presa 9 giorni fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 82/100
CCExtractor/ccextractor#2402 ·
I maintainer di solito rispondono entro 1 giorno
-
[BUG] ISDB decoder ignores the payload length: heap-buffer-overflow in parse_statement, plus a one-byte overflow in get_textForse già presa @pranayr710 l’ha presa 1 giorno fa. Aperta
Difficoltà 4/5 3-5 giorni Idoneità per principianti 55/100
CCExtractor/ccextractor#2434 ·
I maintainer di solito rispondono entro 1 giorno
-
[BUG] WTV read_header(): unchecked len and text_len from the file crash the parser (SEGV, 4 KB reproducer)Forse già presa @pranayr710 l’ha presa 1 giorno fa. Aperta
Difficoltà 2/5 1-3 ore Idoneità per principianti 35/100
CCExtractor/ccextractor#2433 ·
I maintainer di solito rispondono entro 1 giorno
Tutte le issue di CCExtractor/ccextractor
Issue simili
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 70/100
I maintainer di solito rispondono entro 2 giorni
-
Component - Build
Difficoltà 2/5 1-3 ore Idoneità per principianti 75/100
I maintainer di solito rispondono entro 1 giorno
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 76/100
-
Difficoltà 2/5 1-3 ore Idoneità per principianti 78/100
-
Difficoltà 1/5 Meno di un'ora Idoneità per principianti 68/100
JustAResearcher/gpu-unlock-ada#110 ·
I maintainer di solito rispondono entro 1 giorno