fix(p2p): harden direct-P2P framing and ingress admission - #75
Merged
Conversation
Bound pre-authentication JSON nesting depth to 32 so a pathologically nested control frame cannot overflow the session-thread stack before any trust decision. Raise the control-frame cap to 512 KiB to cover the worst-case authenticated state frame (~300 KiB across 256 writers x 256-byte ids). Gate MemorySyncLoop::applyDeltas through the resource governor so a peer cannot flood deltas on the direct replication path. Account delta/bootstrap wire bytes using the exact received frame size instead of a compact re-serialization. Signed-off-by: trvon <git@trevon.dev>
There was a problem hiding this comment.
🔵 Needs a closer look
It changes security-critical pre-auth P2P parsing/framing and ingress admission behavior, which warrants a final human review.
Pull request overview
This PR hardens the direct-P2P replication path by adding pre-auth JSON depth rejection, correcting receiver-side wire-byte accounting to use exact frame sizes, enforcing resource-governor admission for direct delta ingress, and raising the control-frame cap to accommodate worst-case authenticated state frames.
Changes:
- Add a JSON nesting-depth pre-scan in control-frame parsing and introduce
readJsonFrame()to retain exact received payload size for accounting. - Update delta/bootstrap receive paths to account bytes using the original wire size rather than compact re-serialization.
- Gate
MemorySyncLoop::applyDeltas()behind a direct-ingress admission check and expand unit coverage for the new behavior; raisekP2pMaxControlFrameBytesand add a transport regression test.
File summaries
| File | Description |
|---|---|
| tests/unit/memory_sync/memory_sync_catch2_test.cpp | Adds a unit test ensuring applyDeltas() rejects work when direct-ingress admission is denied. |
| tests/unit/daemon/p2p_transport_catch2_test.cpp | Adds a regression test validating large control frames can round-trip after the cap increase. |
| tests/unit/daemon/p2p_protocol_catch2_test.cpp | Adds a test ensuring handshake control frames reject excessive JSON nesting depth pre-auth. |
| tests/unit/daemon/p2p_delta_catch2_test.cpp | Adds a test verifying receiver byte accounting includes JSON padding/whitespace on the wire. |
| src/daemon/p2p/p2p_json.h | Implements JSON nesting depth pre-scan and readJsonFrame() (JSON + exact wire payload bytes). |
| src/daemon/p2p/p2p_delta.cpp | Switches delta/bootstrap receive accounting to use readJsonFrame().payloadBytes. |
| include/yams/memory_sync/memory_sync.h | Adds an unconditional direct-ingress admission gate for peer-delivered deltas. |
| include/yams/daemon/p2p/p2p_transport.h | Raises the control-frame cap to 512 KiB and documents sizing rationale. |
Review details
- Files reviewed: 8/8 changed files
- Comments generated: 1
- Review effort level: Lite
💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.
Comment on lines
+31
to
+33
| /// Control frames are structurally flat (<= 5 nesting levels). Anything deeper is a | ||
| /// pre-authentication stack-exhaustion probe and is rejected before nlohmann descends it. | ||
| inline constexpr std::size_t kMaxP2pJsonNestingDepth = 32; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Stacked draft child of #74. Closes four direct-P2P wire/ingress findings from the deep review of the #68 stack, without merging or deploying anything.
parseJsonFramenow rejects control frames nested deeper than 32 levels beforenlohmannrecursively descends them, so a ~32k-deep[[[…]]]hello cannot overflow the session-thread stack before any trust decision.kP2pMaxControlFrameBytesraised 64 KiB → 512 KiB to cover the worst-case authenticatedstateframe (~300 KiB: version vector +seenwatermark + 256 commitments + quarantined set).MemorySyncLoop::applyDeltasnow runsbeforeDirectIngress()(unconditionalcanAdmitRemoteWork+isCancelled), so the daemon'sResourceGovernorcan throttle a peer flooding deltas on the new replication path even though the backend is local.readJsonFrame().payloadBytes) instead of a compact re-serialization, so whitespace/duplicate-key padding from a peer counts againstmaxWireBytesPerSession/maxSnapshotWireBytes.Confirmed non-issue (no change): the cold-bootstrap snapshot path is correctly multi-writer — each winner's
originis authenticated by its own schema-v4 writer signature (validateBootstrapWinner→validateDirectDelta→writerAuth_->verify) plus the witness root digest, so it does not require the single-writerorigin == peerNodeIdcheck used on the delta-continuation path.AI disclosure
Extensive AI assistance was used for implementation, test generation, and adversarial review. All changes were locally inspected and validated; the umbrella #68 remains blocked by the decision-grade live-performance gate.
Stack
fix/p2p-operator-validation/ test(p2p): add direct control fuzz harnesses #74 at87e298e04415fbfb2ed5f06cd40712c428186f94fix/p2p-wire-hardeningat24923e95835bf31633ff9c54b46fe2a5c0b1e55cDo not merge or deploy this child independently.