Fix UB: Non-static callbacks are unsound

This commit is contained in:
ivmarkov 2023-11-11 18:14:12 +00:00
parent f917d5302b
commit 79fc6e738b
3 changed files with 13 additions and 9 deletions

View File

@ -1147,17 +1147,18 @@ impl<'d, T: Pin, MODE> PinDriver<'d, T, MODE> {
/// Care should be taken not to call STD, libc or FreeRTOS APIs (except for a few allowed ones)
/// in the callback passed to this function, as it is executed in an ISR context.
#[cfg(all(not(feature = "riscv-ulp-hal"), feature = "alloc"))]
pub unsafe fn subscribe(&mut self, callback: impl FnMut() + Send + 'd) -> Result<(), EspError>
pub unsafe fn subscribe<F>(&mut self, callback: F) -> Result<(), EspError>
where
F: FnMut() + Send + 'static,
MODE: InputMode,
{
extern crate alloc;
self.disable_interrupt()?;
let callback: alloc::boxed::Box<dyn FnMut() + Send + 'd> = alloc::boxed::Box::new(callback);
chip::PIN_ISR_HANDLER[self.pin.pin() as usize] =
Some(unsafe { core::mem::transmute(callback) });
let callback: alloc::boxed::Box<dyn FnMut() + Send + 'static> =
alloc::boxed::Box::new(callback);
chip::PIN_ISR_HANDLER[self.pin.pin() as usize] = Some(callback);
Ok(())
}

View File

@ -459,9 +459,9 @@ impl<'d> PcntDriver<'d> {
/// - ()
/// - EspError
#[cfg(feature = "alloc")]
pub unsafe fn subscribe<C>(&self, callback: C) -> Result<(), EspError>
pub unsafe fn subscribe<F>(&self, callback: F) -> Result<(), EspError>
where
C: FnMut(u32) + Send + 'static,
F: FnMut(u32) + Send + 'static,
{
enable_isr_service()?;

View File

@ -287,15 +287,18 @@ impl<'d> TimerDriver<'d> {
/// Care should be taken not to call STD, libc or FreeRTOS APIs (except for a few allowed ones)
/// in the callback passed to this function, as it is executed in an ISR context.
#[cfg(feature = "alloc")]
pub unsafe fn subscribe(&mut self, callback: impl FnMut() + Send + 'd) -> Result<(), EspError> {
pub unsafe fn subscribe<F>(&mut self, callback: F) -> Result<(), EspError>
where
F: FnMut() + Send + 'static,
{
self.check();
self.disable_interrupt()?;
let callback: Box<dyn FnMut() + Send + 'd> = Box::new(callback);
let callback: Box<dyn FnMut() + Send + 'static> = Box::new(callback);
ISR_HANDLERS[(self.group() * timer_idx_t_TIMER_MAX + self.index()) as usize] =
Some(unsafe { core::mem::transmute(callback) });
Some(callback);
Ok(())
}