java-topology/whitepaper/outreach/zabbix-0002.md
russell@unturf.com 6784cdf1cf feat: add 39 outreach docs (batches 6-8)
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.
2026-04-14 17:06:28 -04:00

2.6 KiB
Raw Permalink Blame History

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.

  1. Confirm receipt and assign a GitHub issue reference (zabbix/zabbix).
  2. Assess severity — fires on every discovery queue drain, quadratic in job count.
  3. Coordinate a disclosure date — we target 90 days from first contact.
  4. 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.