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
2.5 KiB
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.