libvorbis+libopus: 5-MOAD scan; CLEAN both targets
This commit is contained in:
parent
8a3fc56b23
commit
2c215e46e5
2 changed files with 163 additions and 0 deletions
85
defects/libopus-scan/patch/CLEAN.md
Normal file
85
defects/libopus-scan/patch/CLEAN.md
Normal 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 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.
|
||||
78
defects/libvorbis-scan/patch/CLEAN.md
Normal file
78
defects/libvorbis-scan/patch/CLEAN.md
Normal file
|
|
@ -0,0 +1,78 @@
|
|||
# libvorbis (Ogg Vorbis) — 5-MOAD Scan Result: CLEAN
|
||||
|
||||
**Target:** xiph/vorbis
|
||||
**Source:** https://github.com/xiph/vorbis
|
||||
**Scan Date:** 2026-03-31
|
||||
**Language:** C
|
||||
|
||||
---
|
||||
|
||||
## MOAD-0001 — CWE-407: Algorithmic Complexity (list membership in loop)
|
||||
|
||||
### Candidates investigated
|
||||
|
||||
**`lib/floor1.c` — `floor1_look()` neighbor search (lines 233–252)**
|
||||
|
||||
Double loop: outer over `n-2` posts (n ≤ VIF_POSIT+2 = 65), inner over `i+2`
|
||||
prior posts. O(n²) = O(63²) = ~3969 ops. Runs once per codec setup call, not
|
||||
per frame. Bounded absolutely by spec constant VIF_POSIT=63. Not actionable.
|
||||
|
||||
**`lib/res0.c` — `_01class()` / `_2class()` partition threshold scan (lines 441–444, 505–508)**
|
||||
|
||||
For each partition value, a linear scan through `possible_partitions` to find
|
||||
our threshold bracket. Outer loop is over `partvals` (n/grouping, where n is
|
||||
residue length and grouping is typically 32). Inner scan is at most
|
||||
`possible_partitions-1` ≤ 63 (6-bit field per spec). Both dimensions are
|
||||
codec-spec bounded. In practice: 64 partvals × 63 partitions = 4032 comparisons
|
||||
per frame. Not an O(N²) growth pattern over user-controlled input. Not actionable.
|
||||
|
||||
**`lib/psy.c` — `noise_normalize()` qsort call**
|
||||
|
||||
Sorts up to `n` floats per partition band. Uses qsort (O(n log n)). CLEAN.
|
||||
|
||||
**`lib/floor1.c` — per-frame `floor1_forward_block()` neighbor update (lines 680–689)**
|
||||
|
||||
Two inner loops over `posts` positions when a new split post is accepted. Both
|
||||
break immediately on first mismatch — amortized O(posts) total across all splits
|
||||
per frame. Not O(posts²). CLEAN.
|
||||
|
||||
**`lib/vorbisfile.c` — serialno scan (lines 840–841, 1373–1374)**
|
||||
|
||||
Linear scan of `vf->serialnos[link]` inside page-reading loop. `vf->links` is
|
||||
the number of chained bitstreams in the file — typically 1–3 for real files.
|
||||
Seek-path only, not hot decode path. CLEAN.
|
||||
|
||||
### Verdict: CLEAN — no CWE-407 defects
|
||||
|
||||
---
|
||||
|
||||
## MOAD-0002 — Intertangle: shared mutable global state / god object
|
||||
|
||||
No mutable process-global state in the encode/decode path. All per-session state
|
||||
lives in `vorbis_dsp_state`, `vorbis_block`, `vorbis_info` — caller-owned structs.
|
||||
`lib/misc.c` global tracking (`pointers`, `global_bytes`) is `#ifdef DEBUG_MALLOC`
|
||||
only — not compiled in production. `mapping0.c` `seq`/`total` statics are inside
|
||||
`#if 0` dead code block. CLEAN.
|
||||
|
||||
---
|
||||
|
||||
## MOAD-0003 — Leaked Context: ThreadLocal / thread-scoped request identity
|
||||
|
||||
No `pthread_getspecific`, `__thread`, `thread_local`, or equivalent in any
|
||||
encode/decode path. 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 anywhere in our codebase. CLEAN.
|
||||
|
||||
---
|
||||
|
||||
## MOAD-0005 — Thundering Herd: unsynchronized cache get+null+compute+put
|
||||
|
||||
No caching with unsynchronized double-checked access. `lib/floor0.c`/`floor1.c`
|
||||
memo arrays are stack-local per-block, passed explicitly. `lib/smallft.c`
|
||||
trigcache is computed once during `drft_init` in single-threaded setup, never
|
||||
updated after initialization. CLEAN.
|
||||
Loading…
Add table
Add a link
Reference in a new issue