3.2 KiB
libopus (Opus audio codec) — 5-MOAD Scan Result: CLEAN
Target: xiph/opus Source: https://github.com/xiph/opus Scan Date: 2026-03-31 Language: C
MOAD-0001 — CWE-407: Algorithmic Complexity (list membership in loop)
Candidates investigated
silk/sort.c — silk_insertion_sort_increasing_all_values_int16() (lines 147–153)
Insertion sort O(L²) worst case. L = LPC order, which is spec-fixed: 10 (NB/MB)
or 16 (WB). Max 256 comparisons per call. Called only in silk_NLSF_stabilize
fallback path when iterative adjustment exceeds MAX_LOOPS=20, which is itself a
rare corner case. Bounded absolutely. Not actionable.
silk/NLSF_stabilize.c — main loop (lines 60–118)
Outer loop over MAX_LOOPS=20 iterations. Inner loops over L (10 or 16) elements for min-diff search, plus two accumulation loops over kI (up to L). Total: O(20 × L) = O(320) ops worst case. Spec-bounded. CLEAN.
silk/NLSF_VQ.c — silk_NLSF_VQ() codebook search (lines 54–75)
O(K × LPC_order) where K=nVectors. Both codebooks (WB and NB/MB) have K=32 and LPC_order of 16 or 10. Max 512 ops per call. Spec-bounded. CLEAN.
silk/NLSF_encode.c — silk_insertion_sort_increasing() on K=32 errors (line 75)
Partial insertion sort to find nSurvivors best candidates from 32. K=32 is spec-fixed. CLEAN.
src/opus_multistream.c — get_left_channel() / get_right_channel() / get_mono_channel() (lines 57–91)
Per-frame call inside the outer for(s=0; s<nb_streams; s++) decode loop.
Each get_*_channel call scans nb_channels (max 255 per spec). Total:
O(nb_streams × nb_channels) = O(255×255) = ~65000 per decode call. However:
(a) these functions advance via prev parameter — no restart scanning; the
while loop in the decoder iterates each channel at most once per stream,
making the total across all streams O(nb_channels), not O(S×C). (b) Practical
multistream configs are 2–8 channels, 1–4 streams. Not a growth defect. CLEAN.
celt/bands.c — all band processing loops
All loops are bounded by eBands entries (21 for CELT wideband) and
nb_channels (1–2 in typical operation). No nested membership test pattern.
CLEAN.
Verdict: CLEAN — no CWE-407 defects
MOAD-0002 — Intertangle: shared mutable global state / god object
No mutable process-global state in encode/decode paths. All session state lives
in OpusEncoder, OpusDecoder, SilkEncoder, SilkDecoder structs allocated
and owned by callers. No static mutable globals found in silk/, celt/, or
src/ encode/decode paths. CLEAN.
MOAD-0003 — Leaked Context: ThreadLocal / thread-scoped request identity
No pthread_getspecific, __thread, thread_local, or equivalent in any C
source under silk/, celt/, or src/. Pure C library with caller-owned state.
CLEAN.
MOAD-0004 — CWE-312: credentials or keys logged verbatim
Pure audio codec library. No auth flows, HTTP headers, API keys, or credential handling. CLEAN.
MOAD-0005 — Thundering Herd: unsynchronized cache get+null+compute+put
No shared cache with double-checked locking or unsynchronized lazy initialization
in encode/decode paths. silk_NLSF_stabilize memo state is stack-local. CELT
mode tables are static const (read-only). CLEAN.