java-topology/whitepaper/outreach/systemd-0004.md
russell@unturf.com 652608142a feat: close outreach doc gap — 276 docs (batches 11-16)
All projects with patches now have outreach docs. 276 new docs covering
CWE-407, CWE-312, CWE-362 across C, C++, Java, Python, Go, Rust, C#,
PHP, Ruby, JavaScript, Dart, Erlang, R, and more.

Outreach gap: 276 -> 0.
2026-04-15 13:57:42 -04:00

2.7 KiB
Raw Blame History

systemd — CWE-407 Disclosure Brief (systemd-0004)

2026-04-13 · Patch available — awaiting upstream merge

Finding

One O(n²) defect in systemd's seccomp syscall filter loading. strv_contains() performs O(K×A) linear scans when checking ~537 syscalls in the @known set against a growing list of already-added syscalls. Patched.

The Defects

systemd-0004 (PATCHED — MEDIUM): src/shared/seccomp-util.c:1195

// In seccomp_load_syscall_filter_set() — fires per architecture per service start:
NULSTR_FOREACH(name, syscall_filter_sets[SYSCALL_FILTER_SET_KNOWN].value) {
    // ...
    if (strv_contains(added, name))  // O(A) scan of all already-added syscalls
        continue;
}

After processing a filter set, the function iterates over all ~537 syscalls in @known and calls strv_contains(added, name) to check if each was already handled. strv_contains is O(A) where A = number of added syscalls. With K=537 known syscalls and A growing up to ~300, total cost is O(K×A) per architecture per service start.

The sibling function seccomp_load_syscall_filter_set_raw() already uses hashmap_contains for O(1) lookup. This fix brings the named-set path in line.

Complexity Proof

systemd-0004: At K=537, A=300 (per architecture):

  • Defective: ~161,100 string comparisons per architecture
  • Fixed: ~537 hash lookups
  • ~150× op reduction per architecture per service start.

Impact

systemd manages service lifecycle on virtually all major Linux distributions. seccomp_load_syscall_filter_set() runs during every service start that uses SystemCallFilter= (a common hardening directive). On systems with many seccomp-filtered services starting at boot or during deployment, the quadratic cost compounds. The fix aligns the named-set path with the raw-set path that already uses O(1) lookups.

The Fix

systemd-0004: Build a Set* from the added strv and use set_contains() instead of strv_contains():

// Before — O(K×A)
if (strv_contains(added, name))

// After — O(K)
_cleanup_set_free_ Set *added_set = NULL;
// ... populate added_set from added strv ...
if (set_contains(added_set, name))

Patch

Fix available: defects/systemd-0004/patch/systemd-0004-seccomp-strv-to-set.patch

Single-file patch in src/shared/seccomp-util.c.

What We Ask

A patch is ready for review.

  1. Confirm receipt and assign an issue reference (systemd/systemd).
  2. Assess severity — fires per architecture per service start with SystemCallFilter= enabled.
  3. Coordinate a disclosure date — we are targeting 90 days from first contact.
  4. We will credit the systemd team in the public disclosure. Preferred acknowledgment format welcome.

Contact: see cover email. This brief is confidential until coordinated disclosure.