java-topology/docs/tickets/vlc-0001-module-find-linear-scan-per-check.md
russell@unturf.com 9934133dcf whitepaper: 312 sites / 151 ecosystems — wave2+3 defect tables and PDF rebuild
Add 88 new defect entries to HIGH and MEDIUM tables:
  HIGH: mysql-0001/0002, mariadb-0001, redis-0001/0002, valkey-0001/0002, openvpn-0001,
        vlc-0001, prometheus-0001, otel-collector-0001, cockroachdb-0001..0004,
        tidb-0001..0008, kubernetes-0001/0002, go-0001, kotlin-0002, scala-0001,
        allegro5-0001, sdl2-0001, grafana-0001, clickhouse-0001, duckdb-0001,
        mongodb-0001, envoy-0001, istio-0001, cilium-0001, linkerd2-0001,
        linux-0001/0002/0003, tor-0002/0003, curl-0001, julia-0001, lua-0001,
        perl5-0001, nats-0001, spring-0003/0004, tomcat-0001, onos-0002, odl-0002

  MEDIUM: helm-0001, mariadb-0002, openssl-0001/0002, memcached-0001,
          cassandra-0001..0004, flink-0001, storm-0001/0002, zookeeper-0001..0003,
          pip-0001, gradle-0001, nginx-0001, haproxy-0001, caddy-0001, varnish-0001,
          ffmpeg-0001, gstreamer-0001, raylib-0001, love2d-0001, php-0001/0002,
          r-source-0001, cpython-0002, ruby-0001, rabbitmq-0003/0004, activemq-0001,
          ovs-0001, onos-0003, odl-0002, jetty-0001

PDF: 976K
2026-03-27 15:23:43 -04:00

2.5 KiB
Raw Permalink Blame History

vlc-0001 — module_find() Linear Scan Per Module Existence Check (CWE-407)

Status: PATCHED Severity: MEDIUM Target: VLC src/modules/modules.c Function: module_find(), module_exists()

Defect

module_find() allocates and traverses the complete flat module list on every call. module_list_get() (bank.c:829) walks all vlc_plugins linked-list to build a malloc'd module_t** array, which is then scanned sequentially for a name match:

module_t *module_find(const char *name)
{
    size_t count;
    module_t **list = module_list_get(&count);   // malloc + O(N) build
    for (size_t i = 0; i < count; i++)           // O(N) scan
        if (!strcmp(module->pp_shortcuts[0], name))
            ...
}

module_exists() (vlc_modules.h:136) is just module_find(name) != NULL.

Hot Call Sites

src/audio_output/output.c — calls module_exists() 5 times in sequence inside aout_New(), triggered once per audio output creation:

module_exists("goom")        // O(N)
module_exists("projectm")    // O(N)
module_exists("vsxu")        // O(N)
module_exists("glspectrum")  // O(N)
module_exists("equalizer")   // O(N)

Plus one more at line 600: module_exists("spatialaudio"). That is 6 × O(N) linear mallocs+scans, each allocating and freeing a full module pointer array.

src/preparser/internal.c:738 — called inside a for loop over all supported thumbnail formats, checking module_exists(formats[i].module). This is O(formats × modules) = O(N²) when the module list is large.

lib/media_player.c:721,732 — two more calls at player creation.

Root Cause

module_find uses no index. The capability-indexed lookup (module_list_cap, bank.c:853) correctly uses a tsearch balanced BST, but name-based lookup bypasses it entirely. A g_hash_table / uthash keyed on shortcut name would reduce each call to O(1).

Fix

Add a name → module_t* hash table populated during vlc_bank_Load / module registration. module_find() replaces the scan with a tfind or hash lookup. The module_list_get alloc is eliminated entirely for existence checks.

Patch: defects/vlc/patch/vlc-0001.patch

Complexity

Before After
module_find O(N) + malloc O(1)
module_exists (×6 in aout) 6 × O(N) + 6 malloc 6 × O(1)
preparser format loop O(formats × N) O(formats)

Benchmark

See defects/vlc/unit/VlcModuleFindTest.java — at N=500 modules, 6 sequential scans vs 6 hash lookups; scan executes >200× more comparisons.