libvorbis+libopus: 5-MOAD scan; CLEAN both targets

This commit is contained in:
russell@unturf.com 2026-03-31 22:38:59 -04:00
parent 8a3fc56b23
commit 2c215e46e5
2 changed files with 163 additions and 0 deletions

View file

@ -0,0 +1,85 @@
# 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 147153)**
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 60118)**
Outer loop over MAX_LOOPS=20 iterations. Inner loops over L (10 or 16) elements
for min-diff search, plus two accumulation loops over k<I and k>I (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 5475)**
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 5791)**
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 28 channels, 14 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` (12 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.