85 lines
3.2 KiB
Markdown
85 lines
3.2 KiB
Markdown
# 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 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 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.
|