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.
2.7 KiB
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.
- Confirm receipt and assign an issue reference (systemd/systemd).
- Assess severity — fires per architecture per service start with SystemCallFilter= enabled.
- Coordinate a disclosure date — we are targeting 90 days from first contact.
- 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.