I reviewed libavif 1.3.0-1ubuntu4 as checked into stonking. This shouldn't be
considered a full audit but rather a quick gauge of maintainability. The review
is based on the uaudit artifacts plus targeted reading of the source.

libavif is a portable C implementation of the AV1 Image File Format
(AVIF).

- CVE History
  - 3 CVEs in the package's entire history (UCT pkg_history), all priority
    medium, all memory-safety issues in the decode/reformat path — i.e. the
    expected attack surface for an image codec:
    - CVE-2020-36407
    - CVE-2025-48174
    - CVE-2025-48175
  - All three are addressed in the version under review (1.3.0).
    Upstream was responsive: a GHSA advisory was issued
    and the 2025 fixes landed as proper, reviewed upstream PRs (not minimal
    band-aids).
- Build-Depends
  - cmake, debhelper-compat 13, pkgconf, zlib1g-dev, pandoc (docs only).
  - Image/codec libs (the sensitive ones, since they touch untrusted data):
    libaom-dev, libdav1d-dev, libgav1-dev, libyuv-dev,
    libsharpyuv-dev, libjpeg-dev, libpng-dev, libgdk-pixbuf-2.0-dev, 
libcjson-dev.
  - libgtest-dev for the build-time test suite.
  - rav1e and SVT-AV1 encoders are deliberately disabled (d/rules) to avoid
    universe dependencies; encoding uses libaom.
  - No crypto (no libssl/gnutls), no networking (no libcurl/sockets) libraries.
- pre/post inst/rm scripts
  - None.
- init scripts
  - None.
- systemd units
  - None.
- dbus services
  - None.
- setuid binaries
  - None.
- binaries in PATH
  - /usr/bin/avifdec, /usr/bin/avifenc, /usr/bin/avifgainmaputil (libavif-bin),
    all root:root 0755, non-setuid. CLI tools that operate on user-supplied 
files
    with the invoking user's own privileges; no privilege boundary crossed.
- sudo fragments
  - None.
- polkit files
  - None.
- udev rules
  - None.
- unit tests / autopkgtests
  - Upstream gtest suite is built and run at build time (AVIF_BUILD_TESTS=ON,
    AVIF_GTEST=SYSTEM; enabled in 1.3.0-1ubuntu4). Upstream also ships oss-fuzz
    fuzz harnesses (tests/oss-fuzz/, tests/gtest/avif_fuzztest_*.cc) covering
    decode/encode/incremental-decode — good continuous fuzzing coverage for the
    parser.
  - debian/tests adds an autopkgtest "encode-decode" doing a PNG->AVIF->PNG
    round-trip via the CLI (allow-stderr). Simple but exercises the real 
binaries.
- cron jobs
  - None.
- Build logs
  - 185 lines match error:/warning:; on inspection effectively all are expected
    test-suite stdout/stderr (avifenc/avifdec emitting "ERROR:"/"WARNING:" for
    intentionally-invalid inputs in tests/test_cmd*.sh, PSNR/CICP notices, 
"samples
    clamped to N bits"). No compiler error:/warning: of concern in the actual
    C/C++ compilation. Build uses hardening=+all.
- Processes spawned
  - None.
- Memory management
  - Heavy use of malloc/calloc/memcpy/memmove in src/ — inherent to a codec 
doing
    box parsing and plane copies. This is the package's real risk area and is
    exactly where the 2025 CVEs lived (integer overflow feeding an allocation/
    memcpy). Continued reliance on the upstream oss-fuzz coverage is the
    right mitigation here.
  - Manual review of the decode path corroborated this. The parser
    consistently guards every attacker-controlled length/offset/count
    that feeds an allocation, memcpy, or array index.
  - One genuine but LOW-severity issue found by manual review: the
    CVE-2025-48175 size_t hardening was applied asymmetrically -
    several YUV<->RGB row offsets are still computed as 32-bit
    uint32*uint32 products that can wrap. This reads as a
    correctness/robustness bug rather than a security issue.
    Triggering it requires a caller that raises/disables the size
    limit AND allocates a multi-GB buffer. Not a blocker for the MIR.
  - Upstream status: follow-up commits complete the size_t hardening
    and ship in later releases. Updating stonking to >= 1.4.2 clears
    every write-side case.
- File IO
  - fopen("rb"/"wb") in the CLI tools and src/io.c; paths come straight from CLI
    arguments (user's own files). No umask-sensitive or privileged file 
creation,
    no predictable-name temp files in shipped code.
- Logging
  - Library diagnostics go through avifDiagnosticsPrintf (src/diag.c): vsnprintf
    bounded by AVIF_DIAGNOSTICS_ERROR_BUFFER_SIZE with explicit NUL-termination,
    format strings are compile-time literals (printf format attribute). CLI 
tools
    use fprintf/printf with literal format strings. gdk-pixbuf loader uses
    g_set_error. No tainted format strings observed.
- Environment variable usage
  - None.
- Use of privileged functions
  - None.
- Use of cryptography / random number sources etc
  - None.
- Use of temp files
  - None.
- Use of networking
  - None.
- Use of WebKit
  - None.
- Use of PolicyKit
  - None.

- Any significant cppcheck results
  - 70 warnings, none significant in shipped code.
- Any significant Coverity results
  - A full Coverity pass against 1.3.0-1ubuntu4 found 214 raw defects; 143 pass 
the
    standard audit filter (71 suppressed). None are a memory-safety blocker, and
    none land in the untrusted-input decode path in a way that indicates a real
    defect. The filtered set breaks down as:
      * 104 in the bundled argument parser (statically linked into the CLI tools
        only, not the shared library): all C++ performance/style 
micro-optimizations
        (copy-instead-of-move and similar), no security relevance.
      * 25 in the test and fuzz harnesses (not shipped): ignorable.
      * 10 in the CLI tools (mostly uncaught-exception-on-bad-input and dead 
code):
        local-CLI, low severity.
      * Only 4 touch shipped runtime code (the shared library and the gdk-pixbuf
        plugin), and all four are benign on inspection: the single decode-path 
hit
        is a verified false positive (the flagged dereference is unreachable 
given
        the surrounding size guard); one encode-path null-return sits inside an
        assert that is compiled out of release builds; one is benign dead code; 
and
        the last is a resource leak on an out-of-memory early-return that GLib 
makes
        unreachable (it aborts rather than returning NULL). The leak is a 
one-line
        upstream cleanup, not a blocker.
  - Net: the Coverity pass adds no new security concern and corroborates the 
manual
    decode-path review — the one decode-path detection is a verified false 
positive,
    and the only shipped-code true positives are an assert-only encode nit, 
benign
    dead code, and an unreachable OOM leak in the pixbuf plugin.
- Any significant shellcheck results
  - 176 warnings, all in upstream test/CI shell scripts (tests/*.sh, configure,
    config.guess) and similar build-time helpers. No shell scripts are shipped 
in
    the binary packages, and per the audit workflow these are ignorable.
- Any significant bandit results
  - None.
- Any significant govulncheck results
  - None.
- Any significant Semgrep results
  - 3 findings, all low/informational:
    1-2. apps/avifenc.c:354,363 — use of strtok() instead of strtok_r(). It
         operates on a 128-byte stack-local copy (strncpy-bounded, 
NUL-terminated)
         inside the single-threaded CLI argument parser; not 
reentrancy-sensitive.
         Minor style nit, not a vulnerability.
    3.   .github/actions/setup-linux/action.yml — GitHub Actions 
run-shell-injection
         via ${{ github.* }} interpolation. This is upstream CI infrastructure; 
it
         is not built or shipped in the Ubuntu package and has no bearing on the
         archive. Worth an upstream hardening note only.

General comments:
- A small (~50 kLOC C/C++), well-maintained library backed by
  AOMediaCodec/Google with active upstream development and strong oss-fuzz 
coverage
  of its parser.
- OS-level attack surface is minimal: no daemons, services, setuid binaries,
  maintainer scripts, or polkit/udev/cron/sudo fragments. Hardening flags are 
good.
- The real and inherent risk is parsing untrusted image input in the decode 
path;
  the three historical CVEs are all that class and are fixed in 1.3.0. Manual
  review found the path defensive and consistently bounds-/overflow-checked, the
  only issue being the low-severity, not-file-reachable size_t asymmetry noted
  under Memory management.
- The embedded binary files are all test fixtures plus an android_jni
  gradle-wrapper.jar; none are shipped in the runtime packages.

Security team ACK for promoting libavif to main:
  No code-level blocker was found in the shipped library or tools. Beyond the
  scanner artifacts this included a manual review of the decode/untrusted-input
  path, which was clean apart from the one low-severity, not-file-reachable
  hardening gap above. Updating stonking to >= 1.4.2 would close the gap.


** CVE added: https://cve.org/CVERecord?id=CVE-2020-36407

** CVE added: https://cve.org/CVERecord?id=CVE-2025-48174

** CVE added: https://cve.org/CVERecord?id=CVE-2025-48175

** Changed in: libavif (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/2130005

Title:
  [MIR] libavif

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


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

Reply via email to