Batch 6 (9): dolibarr, jitsi-videobridge, zed, tryton, suricata, strawberry, zulip, zesarux, zephyr Batch 7 (15): xonotic (4), xash3d (3), xenia, xtuple, zabbix (2), zathura, zebra, yabause, zephyr-0001 Batch 8 (15): woodpecker (2), wine (4), widelands (3), wesnoth (3), wekan (3) Mix of CWE-407 and CWE-312.
2.6 KiB
Zabbix — CWE-407 Disclosure Brief (zabbix-0002)
2026-04-13 · Patch available — awaiting upstream merge
Finding
One O(J²) defect in Zabbix discoverer queue job deduplication. discoverer_queue uses zbx_vector_uint64_search (linear scan) to check whether a discovery rule ID has already been collected, producing O(J²) total comparisons when draining J jobs from the queue.
The Defect
zabbix-0002 (PATCHED — LOW-MEDIUM): src/libs/zbxdiscoverer/discoverer_queue.c:108
// In discoverer queue drain loop:
zbx_vector_uint64_t ids;
zbx_vector_uint64_create(&ids);
while (1)
{
// ... get next job id ...
if (FAIL != zbx_vector_uint64_search(&ids, id,
ZBX_DEFAULT_UINT64_COMPARE_FUNC)) // O(J) linear scan
break;
zbx_vector_uint64_append(&ids, id);
}
zbx_vector_uint64_search scans the entire ids vector on every iteration. As jobs accumulate, each subsequent check grows linearly. Total cost for J jobs: O(1+2+...+J) = O(J²/2).
Complexity Proof
At J=200 discovery jobs:
- Defective: 200 × 100 average = 20,000 uint64 comparisons
- Fixed: 200 × O(1) hash lookups = 200 operations
- ~100x op reduction per queue drain.
Impact
Zabbix network discovery scans configured IP ranges and services. Environments with many discovery rules (large enterprise networks with per-subnet or per-VLAN rules) queue hundreds of discovery jobs. The quadratic dedup fires on every queue drain cycle, which runs continuously while discovery jobs are pending.
The Fix
Replace zbx_vector_uint64_t with zbx_hashset_t for O(1) membership checks:
// Before
zbx_vector_uint64_t ids;
if (FAIL != zbx_vector_uint64_search(&ids, id, ...)) break;
zbx_vector_uint64_append(&ids, id);
// After
// CWE-407 fix: hashset for O(1) job ID dedup.
zbx_hashset_t ids;
zbx_hashset_create(&ids, 64, ZBX_DEFAULT_UINT64_HASH_FUNC, ZBX_DEFAULT_UINT64_COMPARE_FUNC);
if (NULL != zbx_hashset_search(&ids, &id)) break;
zbx_hashset_insert(&ids, &id, sizeof(id));
Patch
Fix available: defects/zabbix-0002/patch/zabbix-0002.patch
Single-file patch on src/libs/zbxdiscoverer/discoverer_queue.c. Replaces vector with hashset for job ID tracking.
What We Ask
A patch is ready for review.
- Confirm receipt and assign a GitHub issue reference (zabbix/zabbix).
- Assess severity — fires on every discovery queue drain, quadratic in job count.
- Coordinate a disclosure date — we target 90 days from first contact.
- We will credit the Zabbix team in the public disclosure. Preferred acknowledgment format welcome.
Contact: see cover email. This brief is confidential until coordinated disclosure.