Skip to content

Harden BLS host-function length validation and QC pending-bitset checks (Savanna path)#7

Open
TheJudii wants to merge 1 commit into
release/1.2-teloszerofrom
codex/savanna-node-audit-fixes
Open

Harden BLS host-function length validation and QC pending-bitset checks (Savanna path)#7
TheJudii wants to merge 1 commit into
release/1.2-teloszerofrom
codex/savanna-node-audit-fixes

Conversation

@TheJudii

@TheJudii TheJudii commented Jun 17, 2026

Copy link
Copy Markdown
Contributor

A couple of robustness fixes in the Savanna consensus path, from the same review as the contract-side changes in telosnetwork/telos.contracts#64. Targets release/1.2-teloszero (the ref the contracts repo pins as TELOSZERO_REF). Both come from upstream Antelope/Spring, so they're worth mirroring upstream as well.

BLS length validation (crypto.cpp)

bls_g1_weighted_sum, bls_g2_weighted_sum, and bls_pairing work out the expected points/scalars span lengths from the element count n using 32-bit arithmetic. For a large enough n that product can overflow, so the length check isn't exact and a malformed call could slip past it before allocation. Doing the length math in 64-bit keeps the comparison exact and sends bad inputs down the normal return_code::failure path.

Pending-QC bitset validation (qc.cpp)

verify_basic() was comparing the dual-policy finalizer votes — which indexes the pending vote bitset — before it had validated that bitset's format, and vote_same_at() only had debug assert()s (compiled out in release, and covering just one of the two indices). Reordered so the pending signature's format and weights are checked first, and replaced the assert()s with real EOS_ASSERT bounds checks on both sides, so a malformed bitset is rejected cleanly rather than indexed blindly.

No ABI or wire-format change — this is input-validation hardening. Worth adding regression coverage for a malformed pending bitset (with active and pending policies sharing a finalizer) and an oversized n on the BLS calls. CI here is the build/test gate.

@TheJudii TheJudii requested a review from a team as a code owner June 17, 2026 16:43
@TheJudii TheJudii force-pushed the codex/savanna-node-audit-fixes branch from 729925e to 224f4da Compare June 17, 2026 16:51
…et checks

Two robustness fixes in the Savanna consensus path, found during a security review.

crypto.cpp: bls_g1_weighted_sum / bls_g2_weighted_sum / bls_pairing validated the
element-count-derived span lengths using 32-bit arithmetic, which can overflow for
large element counts and let malformed inputs pass the size check before allocation.
Compute the expected span lengths in 64-bit so the comparison is exact and malformed
calls stay on the return_code::failure path.

qc.cpp: validate the pending finalizer-policy signature's vote format and weights
before comparing dual-policy finalizer votes, and replace the debug-only assert()s in
qc_sig_t::vote_same_at() (compiled out under NDEBUG) with runtime EOS_ASSERT bounds
checks on both signatures' vote indices, so a malformed pending vote bitset is rejected
rather than reaching unchecked dynamic_bitset indexing.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@TheJudii TheJudii force-pushed the codex/savanna-node-audit-fixes branch from 224f4da to fbe37b6 Compare June 17, 2026 16:52
@TheJudii TheJudii changed the title Savanna hardening: BLS weighted-sum length overflow + malformed pending-QC bitset OOB Harden BLS host-function length validation and QC pending-bitset checks (Savanna path) Jun 17, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants