fix(decompiler): cap consecutive empty v1 frames in FrameInStreambuf#459
Open
CryptoJones wants to merge 1 commit into
Open
fix(decompiler): cap consecutive empty v1 frames in FrameInStreambuf#459CryptoJones wants to merge 1 commit into
CryptoJones wants to merge 1 commit into
Conversation
…449) FrameInStreambuf::underflow() skipped empty-payload frames in an unbounded loop. A peer sending an endless run of zero-length frames kept the worker spinning in underflow() — never delivering a byte, never reaching EOF — a CPU-spin DoS. Cap the run at MAX_CONSECUTIVE_EMPTY_FRAMES (16) per underflow() call; exceeding it ends the stream with the new Error::TOO_MANY_EMPTY_FRAMES, retrievable via getLastError(). The counter is per-underflow, which is exactly the span over which empties are consecutive (a non-empty frame returns from underflow and resets the count naturally). Adds unit tests for the at-cap (still delivers) and over-cap (stops) boundaries. Verified by compiling frame_v1.cc against a standalone driver on macOS (no BFD): ==CAP delivers, CAP+1 -> TOO_MANY_EMPTY_FRAMES. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
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.
Closes #449.
FrameInStreambuf::underflow()skipped empty-payload frames in an unboundedfor(;;)loop. A peer sending an endless run of zero-length v1 frames keeps the worker spinning inunderflow()— never delivering a byte, never reaching EOF. That's a CPU-spin DoS against the native decompiler worker.(Severity note from the original review: this is localhost IPC between Ghidra and its own decompiler child process, not a network-facing service — the threat model is a misbehaving/compromised sibling process, not a remote attacker. Still worth bounding.)
Change
frame_v1::MAX_CONSECUTIVE_EMPTY_FRAMES = 16.Error::TOO_MANY_EMPTY_FRAMES.underflow()counts consecutive empties per call and, when the run exceeds the cap, ends the stream (EOF) withlastError = TOO_MANY_EMPTY_FRAMES. The counter is correctly per-underflow(): a non-empty frame returns from the call, so all consecutive empties are always consumed within one invocation.Tests
Two new unit tests in
testframe_v1.cc:frame_v1_tunnel_in_skips_max_empty_frames_then_delivers— exactly CAP empties still skip through to the real frame.frame_v1_tunnel_in_caps_empty_frame_flood— CAP+1 empties → EOF +TOO_MANY_EMPTY_FRAMES, real frame never reached.The existing
frame_v1_tunnel_in_skips_empty_payload_frame(single empty) still holds.Verification
The repo's
decomp_test_dbglinks-lbfd, which isn't available on this macOS host (the same reason CI's C++ tests are Ubuntu-only — see #447). So I compiled the actual editedframe_v1.cc+crc32.ccinto a standalone driver (no BFD, no decompiler lib) exercising the realFrameInStreambuf:The
TEST()-macro versions run undermake decomp_test_dbgin CI on Ubuntu. Noswitchoverframe_v1::Errorexists, so the new enum value can't break-Wswitch.🤖 Generated with Claude Code