mirror of
https://github.com/luxfi/pulsar.git
synced 2026-09-24 00:25:52 +00:00
Item7(a) library-side defense-in-depth, on SHIPPED pulsar v1.9.0 (the tag cloud's consensus v1.35.30 pins). Non-breaking: CanonicalSignerSet's 2-arg signature is UNCHANGED so the existing consensus consumer compiles and runs unmodified. CanonicalSignerSet sized the signer bitmap at make([]byte, maxID/8+1) with maxID taken straight from an attacker-controlled uint32 Partial. PartyID and no upper bound — a single Partial naming PartyID near math.MaxUint32 drives a ~512MiB allocation (memory-exhaustion DoS). Added MaxCanonicalPartyID = 1<<20 (bitmap <= 128 KiB) and a typed ErrPartyIDOutOfRange; CanonicalSignerSet now rejects any partial in `valid` whose PartyID >= the cap BEFORE the sort or the allocation. The whole slice is checked, not just the chosen subset, so a hostile PartyID cannot hide behind the threshold cut. The cap sits far above any real validator set (Lux runs hundreds to low thousands) so legitimate inputs are never rejected. This is orthogonal to — not a replacement for — the consumer's own exact-ValidatorSetSize bound (consensus PulsarRoundSigner.Finalize, its companion commit): the library needs no external context and stays signature-stable, so this hardening protects any future caller lacking that upstream guard. New test: TestCanonicalSignerSet_RejectsOversizedPartyID (MaxUint32, excluded-from-chosen, at-cap boundary, and the just-below-cap happy path with a bounded bitmap). No go.mod/go.sum change.