x264+x265: 5-MOAD scan CLEAN — all MOADs checked, no defects found

This commit is contained in:
russell@unturf.com 2026-03-31 21:33:22 -04:00
parent 53a4e369b2
commit 6c6dc2b114
2 changed files with 105 additions and 0 deletions

View file

@ -0,0 +1,46 @@
# x264 — 5-MOAD Scan Result: CLEAN
Scanned: 2026-03-31
Repo: https://code.videolan.org/videolan/x264.git (depth=1)
Language: C
## MOAD-0001 (CWE-407): CLEAN
x264 is a pure H.264 video encoder. All collection scans over reference frame lists
and motion vector candidate lists are bounded by codec-spec constants:
- `X264_REF_MAX` = 16 reference frames maximum (H.264 spec limit)
- `i_mvc` (MV predictor candidates): bounded by spatial neighbor count (~4)
- `x264_predictor_clip()` in `common/common.h`: single O(N) pass over MV candidates,
deduplicates only against `pmv` (one value), not against each other
- `analyse_weight_frame()` in `encoder/analyse.c`: O(R^2) inner weight plane scaling
but R is bounded by `X264_REF_MAX` = 16, making it O(256) constant
- `ratecontrol.c` nested loops: outer over `num_entries` (frames), inner over `cplxblur`
window (fixed ~20 frames) = O(F * 20), not O(F^2)
- Reference list reorder check in `encoder/encoder.c`: O(R) per list, R <= 16
No unbounded O(N^2) list membership patterns found.
## MOAD-0002 (Intertangle): CLEAN
`x264_t` is a per-encoder context struct passed explicitly to all functions. No global
mutable singleton state is shared across encoder instances. Each thread in frame-parallel
mode gets its own `x264_t` slice context. No god object anti-pattern.
## MOAD-0003 (Leaked Context): CLEAN
No ThreadLocal / `__thread` / `pthread_key` usage found. x264 is C-based and uses
explicit context passing via `x264_t*`. No request-scoped identity carried on thread.
## MOAD-0004 (CWE-312 Logged Secret): CLEAN
x264 is a pure codec library with no authentication, credential, or token data flows.
`x264_log()` calls log encoder state, frame type decisions, and file path errors.
No credential exposure possible. File paths logged in error cases do not contain auth tokens
(codec CLIs do not accept `rtsp://user:pass@host` style input natively).
## MOAD-0005 (Thundering Herd): CLEAN
x264 frame allocation uses `x264_frame_pop_unused()` from a pre-allocated pool, called
under `x264_encoder_encode()` which is documented as not thread-safe (caller serializes).
No concurrent get+null+compute+put cache pattern.

View file

@ -0,0 +1,59 @@
# x265 (libx265 / HEVC Reference Encoder) — 5-MOAD Scan Result: CLEAN
Scanned: 2026-03-31
Repo: https://github.com/videolan/x265 (depth=1)
Language: C++
## MOAD-0001 (CWE-407): CLEAN
x265 is a pure H.265/HEVC video encoder. All hot-path collection scans are bounded
by HEVC spec constants:
- `m_numRefIdx[list]` bounded by `MAX_NUM_REF` = 16 (HEVC spec)
- `RPS::sortDeltaPOC()` in `common/slice.cpp`: insertion sort over `numberOfPictures`
(max 16 entries per HEVC spec) — O(16^2) = constant 256 comparisons, never O(N^2) at scale
- `DPB::applyReferencePictureSet()` in `encoder/dpb.cpp`: O(F * R) where F = DPB frames
(bounded by `maxDecPicBuffer` <= 16) and R = RPS size (<= 16) — O(256) constant
- `DPB::computeRPS()`: single O(F) pass over DPB linked list, F bounded by 16
- `MotionEstimate` candidate dedup in `encoder/motion.cpp` line 800: O(C) pass over
candidates where C is small (4-8 spatial neighbors); no inner O(C) membership scan
- `RateControl::getZone()` in `encoder/ratecontrol.cpp`: O(Z) scan over user-defined
zones, called ~4 times per frame. O(F * Z) total, not O(F^2) or O(Z^2).
Called in the RC path (not motion estimation inner loop); Z is typically small (< 100
for VOD workflows). Borderline, not a confirmed CWE-407 — the zone scan is not
inside a per-element inner loop.
- `Analysis::findSameContentRefCount()` in `encoder/analysis.cpp`: O(2 * R) where
R = numRefIdx, bounded by 16
No unbounded O(N^2) list membership patterns found in hot encode path.
## MOAD-0002 (Intertangle): CLEAN
`Encoder` in `encoder/encoder.h` is a per-encoder instance object. Each `x265_encoder`
opaque pointer wraps a single `Encoder` instance. Frame encoders (`FrameEncoder`) are
worker objects coordinated through `ThreadPool`. No global singleton shared mutable state
between independent encoder instances.
## MOAD-0003 (Leaked Context): CLEAN
`ThreadLocalData` in `encoder/analysis.h` is per-CTU-row work state: it holds
`Analysis` objects and scratch buffers scoped to one frame-encoding row. It carries
no request-scoped identity (user ID, session token, tenant context). It is not a
ThreadLocal in our MOAD-0003 sense — it is work state, not identity.
## MOAD-0004 (CWE-312 Logged Secret): CLEAN
x265 is a pure codec library with no authentication or credential data flows.
`x265_csvlog_encode()` in `encoder/api.cpp` writes `argv[]` to a CSV file — this
dumps CLI arguments including filenames. Input filenames could theoretically contain
embedded credentials (`rtsp://user:pass@host/stream`) but this is a codec CLI
convention issue, not a logging defect in our library code. The output goes to
a CSV file, not a centralized log stream. Not a MOAD-0004 finding.
## MOAD-0005 (Thundering Herd): CLEAN
`x265_encoder_encode()` is documented as not thread-safe per-encoder-instance.
Our frame free-list access (`m_dpb->m_freeList`) occurs under this single-threaded
API entry contract — no concurrent get+null+compute+put pattern. Frame-level
parallelism is internal to the encoder with proper `Lock`/`atomic` primitives
(`m_sliceQpLock`, `m_sliceRefIdxLock`, etc. in `encoder/encoder.h`).