I reviewed libgav1 0.20.0-2ubuntu1 as checked into stonking. This shouldn't be
considered a full audit but rather a quick gauge of maintainability. The review
is driven by the generated audit artifacts (scanners, code greps, packaging)
plus targeted source reads; the ~120K lines of C++ decoder code were not
reviewed line by line.

libgav1 is a Google-authored, spec-compliant AV1 video decoder library (Main,
High and Professional profiles). It exposes a C/C++ decoding API that consumes
compressed AV1 OBU bitstreams and produces decoded YUV frames; the entire
bitstream is untrusted input. The core is ~108K lines of C++ plus ~11K lines of
C headers, is heavily multithreaded (tile/frame parallel, default max 128
threads), and has no networking, no privileged operations and no filesystem
access in the library itself. The attack surface is the OBU bitstream parser
and the DSP kernels. A small example CLI (gav1_decode) is shipped for decoding
IVF files.

- CVE History
  - No CVEs are recorded for libgav1 in the Ubuntu CVE Tracker (both
    pkg_history and pkg_status are empty across all releases) and osv-scanner
    reports none.
- Build-Depends
  - cmake, libabsl-dev, pkg-kde-tools, googletest (test-only), debhelper. All
    in main. No crypto or networking libraries. Abseil (libabsl) is used only
    for the ThreadPool mutex; runtime depends only on shlibs/misc plus libabsl.
- pre/post inst/rm scripts
  - None. No maintainer scripts; pure library packaging.
- init scripts
  - None.
- systemd units
  - None.
- dbus services
  - None.
- setuid binaries
  - None. No setuid binaries or file capabilities.
- binaries in PATH
  - /usr/bin/gav1_decode (libgav1-bin), the example AV1/IVF decoder CLI. Not
    setuid, no capabilities, no network or privileged operations; reads an IVF
    file and writes decoded YUV. Low risk.
- sudo fragments
  - None.
- polkit files
  - None.
- udev rules
  - None.
- unit tests / autopkgtests
  - Upstream GoogleTest suite runs at build time: 100% passed, 0 failed out of
    56. Many ERROR lines in the log are expected negative-test output
    (malformed-bitstream cases) and confirm the decoder rejects bad input
    gracefully. A debian/tests autopkgtest (decode) also decodes two in-tree
    IVF sample files with gav1_decode to exercise the shared library at runtime.
- cron jobs
  - None.
- Build logs
  - No compiler errors. Warnings are benign: repeated Abseil
    Mutex::Lock/Unlock deprecation notices in threadpool.h, and
    -Walloc-size-larger-than warnings in dynamic_buffer.h/array_2d.h that
    correspond to the SIZE_MAX overflow-guard path (size is checked before
    allocation).

- Processes spawned
  - None. No fork/exec/system/popen; no shell invocation anywhere.
- Memory management
  - Heavy but expected memcpy/malloc use for pixel and coefficient buffers and
    DSP kernels; copies are generally fixed-size or sizeof-bounded, and
    allocations use new(std::nothrow) with nullptr checks (defensive style).
  - The core Vector::reserve() (utils/vector.h:98) does malloc(new_cap *
    sizeof(T)) without an explicit multiply-overflow check (source of the
    -Walloc-size-larger-than build warning). All four non-test callers were
    traced: two use thread counts (config, not bitstream) and two use
    tile_count, which is tile_rows * tile_columns with both capped at 64
    (kMaxTileColumns/Rows), so tile_count <= 4096. No reserve() size is an
    unbounded attacker value.
  - All DynamicBuffer::Resize() sizes were traced to bounded values: block
    dimensions (rows4x4 * columns4x4, derived from frame width/height that are
    validated against sequence max_frame_width/height, themselves <= 65536 via
    16-bit fields), tile/plane counts, or loop-restoration unit counts. None is
    an independent unbounded length field.
  - set_itut_t35() copies attacker-controlled OBU metadata, but payload_size is
    GetLastNonzeroByteIndex(data, size) and thus bounded by the remaining OBU
    bytes; Resize(payload_size) and the following memcpy use that same length,
    so source and destination match. The Coverity UNINIT lead
    (obu_parser.cc:2485) is the whole-struct copy in set_itut_t35 reading
    country_code_extension_byte, which is left uninitialized when country_code
    != 0xFF; the byte is later exposed via the public itut_t35() accessor. It is
    a low-severity init-hygiene issue (one indeterminate stack byte, fixed by
    value-initializing the struct), not a memory-safety defect.
- File IO
  - None. The core library performs no filesystem IO; all fopen/fread/fwrite
    calls are in the example CLI and tests only.
- Logging
  - None. Library logging uses fixed format strings via the LIBGAV1_DLOG
    macros; no tainted format strings or overflow risk.
- Environment variable usage
  - None. The shipped library reads no environment variables; getenv appears
    only in test helpers (TMPDIR/TEMP/LIBGAV1_TEST_DATA_PATH).
- Use of privileged functions
  - None. No setuid/setgid/capset or other privilege-changing calls.
- Use of cryptography / random number sources etc
  - N/A. No cryptography or TLS. The only randomness is
    GetFilmGrainRandomNumber, a deterministic LCG mandated by the AV1 spec for
    film-grain synthesis; it is not used in any security context.
- Use of temp files
  - None. The library and gav1_decode create no temp files; temp-file use is
    confined to tests and the fuzzer harness.
- Use of networking
  - None. No sockets or network calls; the networking grep matched only
    file IO, thread names and comments, and all http:// hits are Apache license
    headers. Untrusted input is the in-memory AV1 bitstream, whose OBU parser
    rejects malformed streams gracefully (confirmed by the negative tests).
- Use of WebKit
  - N/A.
- Use of PolicyKit
  - N/A.

- Any significant cppcheck results
  - None. All 57 items are cppcheck syntaxError/preprocessor false positives:
    55 from failing to parse GoogleTest TEST() macros in test files, and one
    from the token-paste version macro in version.cc. No real defects.
- Any significant Coverity results
  - The 402 reported defects are heavily inflated (~8x) by template/path
    duplication and are mostly in test/example code; ~340 are a single
    intentional CONSTANT_EXPRESSION_RESULT in intrapred_smooth.cc. After
    filtering, only ~20-25 distinct findings are in real library source.
  - A few bitstream-reachable leads merit an upstream look but none are
    confirmed vulnerabilities: an uninitialized ITU-T T.35
    country_code_extension_byte copied and exposed via the public accessor at
    obu_parser.cc:2485, a potential null-deref of obu_headers_.back() at
    obu_parser.cc:3000, and an integer-overflow-before-widen in
    dsp/inverse_transform.cc:93-109. The cdef.cc OVERRUN cluster appears to be
    a false positive (loop bounded by planes_ == kMaxPlanes).
- Any significant shellcheck results
  - None.
- Any significant bandit results
  - None. Not a Python package (one build-tooling script only).
- Any significant govulncheck results
  - N/A. govulncheck is a Go-only tool; it failed with "no go.mod file" because
    this is a C++ package.
- Any significant Semgrep results
  - None.

Overall libgav1 is a mature Google AV1 decoder that is still actively maintained
upstream (latest main commit ~9 weeks old; the packaged 0.20.0 is the newest
tag, primarily authored by James Zern), with no CVE history and a clean, minimal
package (a shared library, headers, and one non-privileged example CLI) with
zero OS-level attack surface. Tagged releases are infrequent, but commit
activity between them is continuous and includes in-tree fuzzers and recurring
ASan/MSan and -Warray-bounds hardening.
The entire security-relevant surface is the AV1 OBU bitstream parser and the DSP
kernels, all of which treat their input as untrusted; the build-time and
negative test suites confirm malformed streams are rejected gracefully. Static
analysis produced no confirmed defects: cppcheck results are all false
positives, the other scanners are clean, and the large Coverity count collapses
to a handful of unconfirmed, mostly bitstream-reachable leads worth an upstream
glance (an uninitialized ITU-T T.35 country_code_extension_byte, a possible
null-deref, and an integer-overflow-before-widen in the inverse transform). The
main residual risk is inherent to any codec parsing untrusted media, which is
best mitigated by keeping current with upstream.

Security team ACK for promoting libgav1 to main. No blocking conditions. The
unconfirmed Coverity leads in src/obu_parser.cc (uninitialized itut_t35
country_code_extension_byte, obu_headers_.back() null-deref) and
src/dsp/inverse_transform.cc (integer overflow before widening) are ones I may
report upstream myself if further analysis shows it is worthwhile; that is
a follow-up on my part, and none of these are demonstrated vulnerabilities or
block promotion.


** Changed in: libgav1 (Ubuntu)
     Assignee: Ubuntu Security Team (ubuntu-security) => (unassigned)

** Changed in: libgav1 (Ubuntu)
       Status: New => In Progress

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2158712

Title:
  [MIR] libgav1 (libavif dependency)

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/libgav1/+bug/2158712/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to