bitbox02/delay: call delay_cancel after init
What changed, and why it matters
This commit fixes a bug in the BitBox02 hardware wallet's Rust delay system. Previously, calling delay_for() 10 times without cleanup caused the device to abort with 'Too many concurrent delays'. The fix ensures each delay is cancelled automatically when finished, preventing the device from crashing. It is a reliability fix rather than a clear security vulnerability, though any device crash could theoretically affect availability or user workflow.
Treat as a reliability/availability fix. Review whether the abort path could be triggered by user-facing flows and confirm delay_cancel is safe to call on already-completed delays. No immediate security patch urgency unless availability attacks are demonstrated.
Security signals we found
Firmware abort/crash after 10 uses of delay_for()
Resource leak in async delay wrapper
Missing cleanup of embedded C FFI delay object
Availability impact on hardware wallet operation
Evidence from the diff
The patch adds a Drop guard (DelayGuard) around the bitbox02_sys::delay_t object in delay_for(). When the async future completes or is dropped, the guard invokes delay_cancel(), releasing the underlying delay resource. Previously, the delay handle was not explicitly cancelled, and after 10 concurrent delay objects were leaked, the firmware aborted. The fix is localised to src/rust/bitbox02/src/delay.rs and is a resource-leak/cleanup correction.
Changed components
src/rust/bitbox02/src/delay.rsbitbox02_sys delay subsystemAsync delay_for futureInspect captured patch +9 / −1
diff --git a/src/rust/bitbox02/src/delay.rs b/src/rust/bitbox02/src/delay.rs
index 5a3cf0e..250c603 100644
--- a/src/rust/bitbox02/src/delay.rs
+++ b/src/rust/bitbox02/src/delay.rs
@@ -48,7 +48,15 @@ pub async fn delay_for(duration: Duration) {
shared_state_ptr,
)
}
-
+ struct DelayGuard<'a>(&'a bitbox02_sys::delay_t);
+ impl Drop for DelayGuard<'_> {
+ fn drop(&mut self) {
+ unsafe {
+ bitbox02_sys::delay_cancel(self.0 as *const _);
+ }
+ }
+ }
+ let _delay_guard = DelayGuard(&bitbox02_delay);
core::future::poll_fn({
let shared_state = &shared_state;
move |cx| {
Why this scored 33/100
Community notes
Notes can correct, qualify, or add evidence to the AI analysis. Every note shown here has been validated by a human moderator.
The AI analysis stands alone for now. Submit a note if you can add evidence or important context.