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.1 KiB
mariadb-0001 — setup_order/setup_group: O(ORDER × SELECT) find_item_in_list quadratic
Target: MariaDB/server Severity: HIGH CWE: CWE-407 (Inefficient Algorithmic Complexity) Files:
sql/sql_select.cclines 28873–28876 (setup_order)sql/sql_select.cclines 28950–28953 (setup_group) Status: PATCHED
Defect
Both setup_order() and setup_group() iterate over the ORDER BY / GROUP BY
item linked list and for each item call find_order_in_list() (lines 28875,
28952), which itself calls find_item_in_list() — a linear O(S) walk over
List<Item> &fields (the SELECT list) implemented at sql/sql_base.cc:7175.
This gives O(O × S) complexity where O = number of ORDER/GROUP BY columns and S = number of SELECT columns. For a query with 100 ORDER BY expressions and a 100-column SELECT list this is 10 000 string comparisons per query parse/resolution pass.
find_item_in_list uses List_iterator<Item> (a singly-linked list iterator)
so there is no random access and no shortcut — every call scans from the
head.
The same find_item_in_list is also called from setup_new_fields()
(line 29062) in a loop over a new-fields linked list, compounding the issue
for INSERT ... SELECT or multi-table updates with many expressions.
Root Cause
List<Item> (MariaDB's intrusive linked list) has no index. Resolving ORDER
BY / GROUP BY positions against the SELECT list requires a name lookup, and
the current code rebuilds this O(S) walk for every ORDER/GROUP item without
caching a name→position map.
Fix
Before the for loop in setup_order and setup_group, build a
std::unordered_map<std::string, uint> mapping field name to SELECT-list
position. Each find_order_in_list call can then resolve positional and
name-based references in O(1) instead of O(S).
See: defects/mariadb/patch/mariadb-0001.patch
Benchmark
defects/mariadb/unit/MariadbTest.java — setup_order quadratic test case:
- Slow (List_iterator linear scan per ORDER item): O(n²)
- Fast (HashMap pre-indexed): O(n), speedup ≥ 15× at n=500