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
48 lines
1.5 KiB
Markdown
48 lines
1.5 KiB
Markdown
# php-0002 — zend_execute.c: O(n²) linear scan for named argument offset at runtime
|
||
|
||
| Field | Value |
|
||
|-------|-------|
|
||
| ID | php-0002 |
|
||
| Target | PHP |
|
||
| File | `Zend/zend_execute.c` |
|
||
| Lines | 5477–5491 |
|
||
| CWE | CWE-407 (Algorithmic Complexity) |
|
||
| Severity | HIGH |
|
||
| Status | PATCHED |
|
||
|
||
## Description
|
||
|
||
`zend_get_arg_offset_by_name()` resolves a named argument to its positional
|
||
offset at call time. It uses a per-opcode cache slot, but on cache miss (first
|
||
call or when the function pointer changes) it falls back to a linear scan:
|
||
|
||
```c
|
||
// TODO: Use a hash table?
|
||
uint32_t num_args = fbc->common.num_args;
|
||
for (uint32_t i = 0; i < num_args; i++) {
|
||
const zend_arg_info *arg_info = &fbc->common.arg_info[i];
|
||
if (zend_string_equals(arg_name, arg_info->name)) {
|
||
...
|
||
return i;
|
||
}
|
||
}
|
||
```
|
||
|
||
Every unique call site × function-pointer combination incurs O(M) on first use.
|
||
In JIT-warmed code or long-running scripts that call many different functions
|
||
with named args this accumulates to O(N × M) cost. The upstream comment
|
||
`// TODO: Use a hash table?` explicitly acknowledges the defect.
|
||
|
||
## Fix
|
||
|
||
See php-0001. Build a per-function-signature hash mapping name → index once
|
||
and reuse across all call sites. The cache-slot mechanism already exists for
|
||
the "already resolved" fast path — extending it to populate a shared per-`fbc`
|
||
table avoids the O(M) fallback entirely.
|
||
|
||
## Complexity
|
||
|
||
| Metric | Before | After |
|
||
|--------|--------|-------|
|
||
| Per lookup (cache miss) | O(M params) | O(1) |
|
||
| N call sites × M params | O(N×M) | O(M + N) |
|