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
1.8 KiB
openssl-0001: SSL_get_shared_ciphers — O(n²) cipher intersection via unsorted sk_SSL_CIPHER_find
CWE: CWE-407 (Inefficient Algorithmic Complexity)
Severity: MEDIUM
Status: PATCHED
File: ssl/ssl_lib.c — SSL_get_shared_ciphers()
Defect
SSL_get_shared_ciphers() iterates all client cipher suites (outer loop, O(n)) and for
each one calls sk_SSL_CIPHER_find(srvrsk, c) on the server cipher stack.
sk_SSL_CIPHER_find → OPENSSL_sk_find → internal_find: when the stack has no
comparator set or is not sorted, falls through to a linear scan (for i = 0; i < st->num).
The compare function is intentionally NOT set on srvrsk here — the comment in s3_lib.c
(line 4808) says: "Do not set the compare functions, because this may lead to a reordering
by 'id'. We want to keep the original ordering. We may pay a price in performance during
sk_SSL_CIPHER_find()."
Result: O(n × m) where n = client cipher count, m = server cipher count.
TLS 1.2 supports ~100 cipher suites; hostile clients can send 100 → 10,000 comparisons
per SSL_get_shared_ciphers() call.
// ssl/ssl_lib.c:3618
for (i = 0; i < sk_SSL_CIPHER_num(clntsk); i++) { // O(n)
c = sk_SSL_CIPHER_value(clntsk, i);
if (sk_SSL_CIPHER_find(srvrsk, c) < 0) // O(m) — linear when unsorted
continue;
...
}
Fix
Build a uint32_t bitset or LHASH/hash-set of server cipher IDs before the loop.
Membership check becomes O(1); total complexity O(n + m).
See patch: defects/openssl/patch/openssl-0001.patch
Hot Path
Called by diagnostic/logging code and TLS session inspection. Not the negotiation fast path
(ssl_choose_cipher uses a pre-sorted cipher_list_by_id) but still reachable per
connection on servers that log shared cipher info.