[BREAKGLASS] A Rust MP4 format sanitizer
Go to file
2023-10-01 09:06:34 -07:00
.github/workflows fix: cargo-afl tool was renamed from afl to cargo-afl upstream 2023-08-30 11:07:14 -07:00
cli fix clippy warnings 2023-05-16 12:59:31 -07:00
derive fully qualify all paths in derive 2023-08-28 10:29:45 -07:00
fuzz-afl add fuzzing dictionary 2023-06-30 06:22:05 -07:00
mp4san format with latest rustfmt 2023-10-01 09:06:34 -07:00
test format with latest rustfmt 2023-10-01 09:06:34 -07:00
test-gen fix invalid test input file 2023-06-29 10:35:57 -07:00
.gitignore add fuzz testing via cargo-fuzz 2023-06-30 04:58:49 -07:00
.gitmodules run tests on all .mp4/.mp4.gz files in test-data submodule 2023-01-29 10:05:50 -08:00
Cargo.toml factor out common package variables into the workspace toml 2023-08-28 10:29:45 -07:00
LICENSE Big Bang 2022-12-22 11:37:43 -08:00
README.md fix: cargo-afl tool was renamed from afl to cargo-afl upstream 2023-08-30 11:07:14 -07:00
rustfmt.toml Big Bang 2022-12-22 11:37:43 -08:00

mp4san Fuzzing Status

A Rust MP4 format "sanitizer".

Currently the sanitizer is capable of:

  • Returning all presentation metadata present in the input as a self-contained contiguous byte array.
  • Finding and returning a pointer to the span in the input containing the (contiguous) media data.

"Presentation" metadata means any metadata which is required by an MP4 player to play the file. "Self-contained and contiguous" means that the returned metadata can be concatenated with the media data to form a valid MP4 file.

Unsupported MP4 features

The sanitizer does not currently support:

  • "Fragmented" MP4 files, which are mostly used for adaptive-bitrate streaming.
  • Discontiguous media data, i.e. media data (mdat) boxes interspersed with presentation metadata (moov).
  • Media data references (dref) pointing to separate files.
  • Any similar format, e.g. Quicktime File Format (mov) or the legacy MP4 version 1, which does not contain the isom compatible brand in its file type header (ftyp).

Usage

The main entry points to the sanitizer are sanitize/sanitize_async, which take a Read + Skip input. The Skip trait represents a subset of the Seek trait; an input stream which can be skipped forward, but not necessarily seeked to arbitrary positions.

use mp4san_test::{example_ftyp, example_mdat, example_moov};

let example_input = [example_ftyp(), example_mdat(), example_moov()].concat();

let sanitized = mp4san::sanitize(std::io::Cursor::new(example_input)).unwrap();

assert_eq!(sanitized.metadata, Some([example_ftyp(), example_moov()].concat()));
assert_eq!(sanitized.data.offset, example_ftyp().len() as u64);
assert_eq!(sanitized.data.len, example_mdat().len() as u64);

The parse module also contains a less stable and undocumented API which can be used to parse individual MP4 box types.

API Documentation
Private Documentation

Contributing Bug Reports

GitHub is the project's bug tracker. Please search for similar existing issues before submitting a new one.

Testing

FFMpeg and GPAC-based verification of mp4san output can be enabled using the features mp4san-test/ffmpeg and mp4san-test/gpac.

The mp4san-test/ffmpeg feature requires the following FFMpeg libraries and their headers to be installed:

  • libavcodec
  • libavformat
  • libavutil
  • libswresample
  • libswscale

The mp4san-test/gpac feature requires libgpac >= 2.2 and its headers to be installed.

Integration tests on sample data files can be processed through mp4san-test-gen before being added to the mp4san-test-data repo. This removes any actual media data from the sample file, since it's not read by mp4san anyway, leaving only metadata for testing purposes. This allows even very large media files to be gzipped to very small sizes.

$ cargo run --bin mp4san-test-gen -- test-sample.mp4 mp4san/tests/test-data/test-sample.mp4.gz

Fuzz Testing

Fuzz testing via both cargo afl and cargo fuzz is supported. See the Rust Fuzz Book for more details. To run AFL-based fuzzing:

$ cargo install cargo-afl
$ cd fuzz-afl
$ ./fuzz $num_cpus

To run libFuzzer-based fuzzing:

$ cargo +nightly install cargo-fuzz
$ cd mp4san
$ cargo +nightly fuzz run sanitize -- -dict=fuzz/mp4.dict -seed_inputs=fuzz/input/ffmpeg-black-1f.mp4,fuzz/input/ffmpeg-smptebars-30f.mp4

OSS-Fuzz

Continuous fuzz testing is also provided by OSS-Fuzz.

Build Status
Code Coverage
Bugs Found

License

Licensed under MIT.