From 84b92edd3012206785dcfae38050468f2aec3706 Mon Sep 17 00:00:00 2001 From: Jan Niehusmann Date: Wed, 12 Oct 2022 22:39:14 +0000 Subject: [PATCH] Check watchdog load value max value before multiplying by 2, to avoid integer overflow --- rp2040-hal/src/watchdog.rs | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/rp2040-hal/src/watchdog.rs b/rp2040-hal/src/watchdog.rs index 3c5be87..0ba5bb5 100644 --- a/rp2040-hal/src/watchdog.rs +++ b/rp2040-hal/src/watchdog.rs @@ -41,7 +41,7 @@ use fugit::MicrosDurationU32; /// Watchdog peripheral pub struct Watchdog { watchdog: WATCHDOG, - delay_us: u32, + load_value: u32, // decremented by 2 per tick (µs) } impl Watchdog { @@ -49,7 +49,7 @@ impl Watchdog { pub fn new(watchdog: WATCHDOG) -> Self { Self { watchdog, - delay_us: 0, + load_value: 0, } } @@ -110,7 +110,7 @@ impl Watchdog { impl watchdog::Watchdog for Watchdog { fn feed(&mut self) { - self.load_counter(self.delay_us) + self.load_counter(self.load_value) } } @@ -120,19 +120,23 @@ impl watchdog::WatchdogEnable for Watchdog { fn start>(&mut self, period: T) { const MAX_PERIOD: u32 = 0xFFFFFF; + let delay_us = period.into().to_micros(); + if delay_us > MAX_PERIOD / 2 { + panic!( + "Period cannot exceed maximum load value of {} ({} microseconds))", + MAX_PERIOD, + MAX_PERIOD / 2 + ); + } // Due to a logic error, the watchdog decrements by 2 and // the load value must be compensated; see RP2040-E1 - self.delay_us = period.into().to_micros() * 2; - - if self.delay_us > MAX_PERIOD { - panic!("Period cannot exceed maximum load value of {}", MAX_PERIOD); - } + self.load_value = delay_us * 2; self.enable(false); unsafe { self.configure_wdog_reset_triggers(); } - self.load_counter(self.delay_us); + self.load_counter(self.load_value); self.enable(true); } }