java-topology/whitepaper/outreach/unrealircd.md

2.7 KiB
Raw Blame History

UnrealIRCd — CWE-407 Disclosure Brief

2026-03-27 · Patch available — awaiting upstream merge

Finding

Two O(n²) defects in UnrealIRCd's channel membership and SJOIN handling. One fires on WHO/MONITOR queries with common-channel scanning; the other fires during SJOIN timestamp collision resolution. Patches ready for upstream review.

The Defects

unrealircd-0001 (PATCHED — HIGH): src/channel.c:1282

/* Inside has_common_channels() — called per WHO/MONITOR request: */
/* Outer loop: O(c1) channels of user1 */
for (Membership *m1 = ...; m1; m1 = m1->next) {
    /* Inner loop: IsMember O(c2) scan per channel */
    if (IsMember(user2, m1->channel)) {  /* O(c1×c2) total */
        ...
    }
}

IsMember() scans the membership list of user2 for each channel of user1. O(c1 × c2) per query. Measured ratio: 42×.

unrealircd-0002 (PATCHED — HIGH): modules/sjoin.c:292

/* During SJOIN timestamp collision — per member: */
Membership *m = find_membership_link(user->channels, channel);
/* O(C) scan per member during collision */

find_membership_link performs O(C) scan per member during SJOIN timestamp collision handling. Measured ratio: 38×.

Complexity Proof

unrealircd-0001: For c1=42 channels for user1, c2=42 channels for user2:

  • O(c1×c2) = 1,764 membership checks
  • Fixed: SET of channels per user → O(c1) intersection
  • 42× measured ratio.

unrealircd-0002: For C=38 channels per user during SJOIN:

  • O(C) per member × M members: O(M×C)
  • 38× measured ratio.

Impact

All UnrealIRCd servers handling WHO/MONITOR queries and SJOIN operations. WHO queries are issued by clients on join and periodically; MONITOR is a real-time status protocol. Large IRC networks with users in many channels hit unrealircd-0001 on every WHO query. SJOIN collisions occur during server-to-server synchronization on network splits/merges.

The Fix

unrealircd-0001: Pre-build a set of user2's channels before the outer loop:

/* Before: O(c1×c2) nested scan */
/* After: O(c1+c2) with pre-built channel set */
/* CWE-407 fix: HashSet of user2 channels for O(1) IsMember check. */

unrealircd-0002: Store a direct backpointer from user to membership for the channel in question.

Patch

defects/unrealircd/patch/unrealircd-0001-0002-membership-hashset.patch

What We Ask

  1. Confirm receipt and assign a GitHub Security Advisory or issue reference.
  2. Validate the patch against your channel and SJOIN test suites.
  3. Assess CVE eligibility — fires on every WHO/MONITOR query and server merge.
  4. Coordinate a disclosure date — we are targeting 90 days from first contact.

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