[Security] NULL pointer dereference (SEGV at address 0x0) in sei_message() when parsing a crafted MP4 file

Open
#2,444 0 comments 0 reactions 0 assignees View on GitHub

Maintainers usually reply within 7 days

@yasar710 is already working on this.

Since Nov 2, 2026.

  • #2448 by @yasar710 — open

Assessment

Difficulty
2/5
Estimated time
1-3 hours
Newbie friendliness
50/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
c
Domain
security

Research direction

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.

Written by the indexing model from the issue text.

Description

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.

poc.zip

Dominant language
C
Stars
913
Forks
603
Avg merge
6d 8h
Merged PRs (30d)
33

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from CCExtractor/ccextractor

All issues in CCExtractor/ccextractor

Similar issues

More C issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.