Skip to content

CorruptionBlackBox split reallocation can invalidate active CArray records

Summary

CCorruptionBlackBox::VerifiedData() and CorruptedData() held a CArray element reference while appending split records to the same array. When the append reallocated the array, the still-active reference became stale and later writes could corrupt freed memory or crash under pageheap.

The reproduced real-live crash hit VerifiedData() during AICH recovery:

  • CCorruptionBlackBox::VerifiedData
  • CPartFile::AICHRecoveryDataAvailable
  • CUpDownClient::ProcessAICHAnswer
  • socket packet dispatch

Provenance

This was not introduced by eMuleBB. The same unsafe split pattern is present in the managed stock/community baseline (community/v0.72a / baseline/community-0.72a) and traces back through community history:

  • eMule_v0.60a-community already holds a CCBBRecord& while appending new records to m_aaRecords[nPart].
  • community/v0.72a keeps the same lifetime shape.
  • blame on the pre-fix eMuleBB tree points to upstream/community commits 390156b and ef58358 for the affected split logic.

The workspace does not currently contain a 0.73 stock tag or branch. The newest local/upstream community comparison point observed during the trace was 0.72a-community.

eMuleAI Latest Status

Checked against eMuleAI upstream master at 8e34bdec2b7e4fe9e4307df9d80f691804be99ed (eMuleAIv1.4) on 2026-05-24. The same unsafe pattern is still present there: CCBBRecord& is held while m_aaRecords[nPart].Add(...) may reallocate, and the reference is used again for status and debug accounting.

Conclusion: eMuleAI latest does not appear to have this fix.

Resolution

Fixed on eMuleBB main by app commit 1f590e3 (BUG-017 fix corruption black box split reallocation). The fix snapshots the record values needed for split insertion, avoids using stale references after Add() / SetSize(), and preserves the existing split semantics.

Regression coverage was added in test commit d48532a (BUG-017 cover corruption black box split ownership).

Validation

  • Native Debug parity: passed, 729 passed / 0 failed / 237 skipped.
  • Native Release parity: passed, 726 passed / 0 failed / 237 skipped.
  • x64 Debug app build: passed.
  • x64 Release app build: passed.