java-topology/whitepaper/outreach/jami.md

3.1 KiB
Raw Blame History

Jami — CWE-407 Disclosure Brief

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

Finding

Two defects in Jami's (formerly Ring) conversation management. One uses std::find on a replies vector during git commit history loading; the other incorrectly uses a range iterator over a std::set instead of the set's own find() method — bypassing O(log n) lookup. Patches ready for upstream review.

The Defects

jami-daemon-0001 (PATCHED — HIGH): conversation.cpp:832

// Inside loadMessages() — per git commit:
auto it = std::find(replies.begin(), replies.end(), commitId);
// O(N) vector scan per commit during message history load

std::find on a replies vector performs O(N) linear scan for each git commit during loadMessages(). For N commits: O(N²) total history load. Measured ratio: 211×.

jami-daemon-0002 (PATCHED — MEDIUM): conversation_module.cpp:2341

// std::set<string> members — but using iterator-based find instead of set::find():
auto it = std::find(members.begin(), members.end(), userId);
// Bypasses set::find() O(log n) — uses O(n) iterator scan instead

std::find used on a std::set bypasses the set's O(log n) find() method, performing an O(n) linear iterator scan instead. Measured ratio: 49×.

Complexity Proof

jami-daemon-0001: For N=211 commits in conversation history:

  • O(N) scan per commit: O(N²) = 44,521 comparisons
  • Fixed: unordered_set<std::string> → O(1) per commit
  • 211× measured ratio.

jami-daemon-0002: For M=49 members:

  • std::find on std::set: O(M) iterator scan
  • members.find(): O(log M)
  • 49× measured ratio.

Impact

All Jami users loading conversation history and receiving group messages. Jami is a distributed peer-to-peer communication application (voice, video, messaging) based on the Ring protocol. Conversations with long git commit histories hit jami-daemon-0001 on every history load. Group conversations hit jami-daemon-0002 on every membership check.

The Fix

jami-daemon-0001: Replace std::find with unordered_set:

// Before
auto it = std::find(replies.begin(), replies.end(), commitId);

// After
// CWE-407 fix: unordered_set for O(1) lookup instead of O(N) std::find scan.
if (repliesSet.count(commitId)) { ... }

jami-daemon-0002: Use members.find() (set's own method) instead of std::find:

// Before
auto it = std::find(members.begin(), members.end(), userId);  // O(n) iterator scan

// After
// CWE-407 fix: use set::find() for O(log n) instead of std::find O(n) scan.
auto it = members.find(userId);  // O(log n)

Patch

defects/jami/patch/jami-daemon-0001-0002-conversation-hashset.patch

What We Ask

  1. Confirm receipt and assign a GitHub Security Advisory or issue reference.
  2. Validate the patch against your conversation loading and group membership test suites.
  3. Assess CVE eligibility — jami-daemon-0001 measured at 211× on conversation history load.
  4. Coordinate a disclosure date — we are targeting 90 days from first contact.

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