ShareAccounting::on_share_rejection is fed error_code values straight from upstream SubmitSharesError messages:
|
pub fn on_share_rejection(&mut self, error_code: String) { |
|
self.rejected_shares |
|
.entry(error_code) |
|
.and_modify(|v| *v += 1) |
|
.or_insert(1); |
|
} |
The wire type is Str0255, so a malicious or compromised pool controls up to 255 bytes of arbitrary content per message.
Every distinct value becomes a permanent key in rejected_shares: HashMap<String, u32> — no length cap, no eviction, no allowlist, and (unlike seen_shares) no flush on chain-tip updates.
Over a sustained connection this is a slow but real memory-exhaustion DoS against the mining client (CWE-400), mirroring the upstream-trust threat model already accepted for the same struct's counter-overflow fixes.
In-repo usage treats this set as a small fixed enumeration (the ERROR_CODE_SUBMIT_SHARES_* constants in mining_sv2), so bounding it matches intent.
fix
count only the known ERROR_CODE_SUBMIT_SHARES_* codes
fold anything else into an "unknown" bucket.
regression test
Feed 10,000 unique error codes into on_share_rejection, assert the stored map stays bounded.
ShareAccounting::on_share_rejectionis federror_codevalues straight from upstreamSubmitSharesErrormessages:stratum/sv2/channels-sv2/src/client/share_accounting.rs
Lines 129 to 134 in 30ca82a
The wire type is
Str0255, so a malicious or compromised pool controls up to 255 bytes of arbitrary content per message.Every distinct value becomes a permanent key in
rejected_shares: HashMap<String, u32>— no length cap, no eviction, no allowlist, and (unlikeseen_shares) no flush on chain-tip updates.Over a sustained connection this is a slow but real memory-exhaustion DoS against the mining client (CWE-400), mirroring the upstream-trust threat model already accepted for the same struct's counter-overflow fixes.
In-repo usage treats this set as a small fixed enumeration (the
ERROR_CODE_SUBMIT_SHARES_*constants inmining_sv2), so bounding it matches intent.fix
count only the known
ERROR_CODE_SUBMIT_SHARES_*codesfold anything else into an "unknown" bucket.
regression test
Feed 10,000 unique error codes into
on_share_rejection, assert the stored map stays bounded.