Skip to content

fix(security): prevent timelock bypass via u64-to-i64 silent truncation#22

Merged
dev-jodee merged 2 commits intomainfrom
fix/timelock-u64-i64-truncation
Feb 24, 2026
Merged

fix(security): prevent timelock bypass via u64-to-i64 silent truncation#22
dev-jodee merged 2 commits intomainfrom
fix/timelock-u64-i64-truncation

Conversation

@dev-jodee
Copy link
Collaborator

Summary

Fixes GHSA-qgq6-7hc8-rqx6 — High severity.

TimelockData::validate() used self.lock_duration as i64 to cast a u64 field. Any lock_duration > i64::MAX silently wraps to a negative number, making unlock_time earlier than deposited_at and bypassing the timelock check entirely. Unlike arithmetic operators, as casts are exempt from overflow-checks = true in Cargo.toml.

Changes

  • program/src/state/extensions/timelock.rs — replace as i64 with i64::try_from(), returning ArithmeticOverflow for out-of-range values.
  • program/src/instructions/extensions/add_timelock/data.rs — add defense-in-depth guard in AddTimelockData::try_from() that rejects lock_duration > i64::MAX with InvalidInstructionData at instruction parse time, before the value ever reaches storage.

Testing

  • 139 unit tests pass (cargo test -p escrow-program)
  • 178 integration tests pass (just integration-test)
  • just fmt and just check clean

Replace the silent `as i64` cast in TimelockData::validate() with
`i64::try_from()`, returning ArithmeticOverflow for any lock_duration
> i64::MAX instead of wrapping to a negative value.

Add a defense-in-depth guard in AddTimelockData::try_from() that
rejects lock_duration > i64::MAX at instruction parse time with
InvalidInstructionData, so a malicious value never reaches storage.

Fixes GHSA-qgq6-7hc8-rqx6
amilz
amilz previously approved these changes Feb 24, 2026
Replace u64::MAX with i64::MAX as the upper success case and add
test_add_timelock_rejects_lock_duration_exceeding_i64_max to cover
i64::MAX+1 and u64::MAX, both of which must now return
InvalidInstructionData.
@dev-jodee dev-jodee merged commit b27a635 into main Feb 24, 2026
5 checks passed
@dev-jodee dev-jodee deleted the fix/timelock-u64-i64-truncation branch February 24, 2026 19:31
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