Skip to content

fix(ledger): replace unsafe usize-to-u32 cast in utxos_info_from_output [PM-20208]#668

Merged
gilescope merged 6 commits into
mainfrom
fix/PM-20208-unsafe-conversion-utxos-info
Feb 23, 2026
Merged

fix(ledger): replace unsafe usize-to-u32 cast in utxos_info_from_output [PM-20208]#668
gilescope merged 6 commits into
mainfrom
fix/PM-20208-unsafe-conversion-utxos-info

Conversation

@m2ux

@m2ux m2ux commented Feb 13, 2026

Copy link
Copy Markdown
Contributor

Summary

Replace the unsafe usizeu32 narrowing cast in utxos_info_from_output with a checked u32::try_from() conversion to eliminate silent truncation and potential UTXO index corruption.

🎫 Ticket 📐 Engineering


Motivation

The Least Authority audit (October 2025, Issue AA) identified an unchecked as u32 cast in utxos_info_from_output (ledger/src/versions/common/api/transaction.rs). On 64-bit platforms, if output_no exceeds u32::MAX, the value is silently truncated via wrapping, producing an incorrect UTXO output index. While the practical likelihood is low (a transaction with >4B outputs is not expected), the defect violates correctness invariants and was flagged as High severity.


Changes

  • Cast replacementoutput_no as u32u32::try_from(output_no)? in utxos_info_from_output
  • Signature change — Return type: Vec<UtxoInfo>Result<Vec<UtxoInfo>, TryFromIntError>
  • Call-site updates — Two call sites in unshielded_utxos handle the Result with log::error! + return UnshieldedUtxos::default()
  • Unit tests — Four new tests: empty vec, single output, sequential indices, field propagation

Testing

  • cargo check -p midnight-node-ledger — passes
  • cargo clippy -p midnight-node-ledger --lib -- -D warnings — passes, no warnings
  • cargo fmt -- --check — passes
  • cargo test — blocked by pre-existing hard_fork_test compilation error (extract_info_from_tx_with_context import); unrelated to this change

📌 Submission Checklist

  • Changes are backward-compatible (or flagged if breaking)
  • Pull request description explains why the change is needed
  • Self-reviewed the diff
  • I have included a change file, or skipped for this reason: audit fix, no user-facing change file needed
  • If the changes introduce a new feature, I have bumped the node minor version
  • Update documentation (if relevant)
  • No new todos introduced

🔱 Fork Strategy

  • Node Runtime Update
  • Node Client Update
  • Other
  • N/A

Placeholder commit to establish draft PR for tracked work on
unsafe usize-to-u32 conversion in utxos_info_from_output.

Ref: PM-20208
Co-authored-by: Cursor <cursoragent@cursor.com>
@github-actions

github-actions Bot commented Feb 13, 2026

Copy link
Copy Markdown
Contributor

kics-logo

KICS version: v2.1.16

Category Results
CRITICAL CRITICAL 0
HIGH HIGH 0
MEDIUM MEDIUM 96
LOW LOW 12
INFO INFO 83
TRACE TRACE 0
TOTAL TOTAL 191
Metric Values
Files scanned placeholder 31
Files parsed placeholder 31
Files failed to scan placeholder 0
Total executed queries placeholder 73
Queries failed to execute placeholder 0
Execution time placeholder 10

m2ux and others added 3 commits February 23, 2026 17:28
… in utxos_info_from_output

Replace `output_no as u32` with `u32::try_from(output_no)?` to prevent
silent truncation when output indices exceed u32::MAX. The function now
returns Result<Vec<UtxoInfo>, TryFromIntError>, with callers in
unshielded_utxos logging the error and returning a default value.

Addresses Least Authority audit Issue AA (PM-20208).

Co-authored-by: Cursor <cursoragent@cursor.com>
…onversion-utxos-info

Co-authored-by: Cursor <cursoragent@cursor.com>

# Conflicts:
#	ledger/src/versions/common/api/transaction.rs
Co-authored-by: Cursor <cursoragent@cursor.com>
@m2ux m2ux marked this pull request as ready for review February 23, 2026 18:10
@m2ux m2ux requested a review from a team as a code owner February 23, 2026 18:10
@gilescope gilescope enabled auto-merge February 23, 2026 19:21
@gilescope gilescope added this pull request to the merge queue Feb 23, 2026
Merged via the queue into main with commit 5d76cba Feb 23, 2026
39 checks passed
@gilescope gilescope deleted the fix/PM-20208-unsafe-conversion-utxos-info branch February 23, 2026 21:18
gilescope pushed a commit that referenced this pull request Apr 8, 2026
added:
- `--multisig` switch executes tests with multi signature governance authority

changed:
- `smart-contracts` commands will automatically handle signing and submitting multisig tx based on the output it gets and tests configuration

removed:
- `get_pty=True` is removed from `run_command.py` because we no longer need it; ogmios logs are written on remote host without it (PCSC CLI wasn't)
- `test_multisig_governance.py` integration tests are removed, please run whole e2e suite with new `--multisg` switch

Refs: ETCM-9629
m2ux added a commit that referenced this pull request Apr 23, 2026
added:
- `--multisig` switch executes tests with multi signature governance authority

changed:
- `smart-contracts` commands will automatically handle signing and submitting multisig tx based on the output it gets and tests configuration

removed:
- `get_pty=True` is removed from `run_command.py` because we no longer need it; ogmios logs are written on remote host without it (PCSC CLI wasn't)
- `test_multisig_governance.py` integration tests are removed, please run whole e2e suite with new `--multisg` switch

Refs: ETCM-9629
Signed-off-by: Mike Clay <mike.clay@shielded.io>
m2ux added a commit that referenced this pull request Apr 23, 2026
added:
- `--multisig` switch executes tests with multi signature governance authority

changed:
- `smart-contracts` commands will automatically handle signing and submitting multisig tx based on the output it gets and tests configuration

removed:
- `get_pty=True` is removed from `run_command.py` because we no longer need it; ogmios logs are written on remote host without it (PCSC CLI wasn't)
- `test_multisig_governance.py` integration tests are removed, please run whole e2e suite with new `--multisg` switch

Refs: ETCM-9629
Signed-off-by: Mike Clay <mike.clay@shielded.io>
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.

3 participants