From 1a46345a2aa710c4ec5ea8fb6589424bc4450d0f Mon Sep 17 00:00:00 2001 From: Emil Fresk Date: Sun, 21 Feb 2021 16:15:34 +0100 Subject: [PATCH] Fixed UB in generated `Monotonic::now()` --- macros/src/codegen.rs | 19 ++++++++++++++----- macros/src/codegen/post_init.rs | 2 +- macros/src/codegen/timer_queue.rs | 17 +++++++++++------ 3 files changed, 26 insertions(+), 12 deletions(-) diff --git a/macros/src/codegen.rs b/macros/src/codegen.rs index f75a8f2d20..b1e87ca837 100644 --- a/macros/src/codegen.rs +++ b/macros/src/codegen.rs @@ -112,9 +112,12 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { .iter() .map(|(_, monotonic)| { let name = &monotonic.ident; + let name_str = &name.to_string(); let ty = &monotonic.ty; - let mangled_name = util::mangle_monotonic_type(&name.to_string()); - let ident = util::monotonic_ident(&name.to_string()); + let mangled_name = util::mangle_monotonic_type(&name_str); + let ident = util::monotonic_ident(&name_str); + let panic_str = &format!("Use of monotonic '{}' before it was passed to the runtime", name_str); + quote! { pub use rtic::Monotonic as _; @@ -123,14 +126,20 @@ pub fn app(app: &App, analysis: &Analysis, extra: &Extra) -> TokenStream2 { #[allow(non_snake_case)] pub mod #name { + /// Access the global `Monotonic` implementation, not that this will panic + /// before the this `Monotonic` has been passed to the RTIC runtime. pub fn now() -> rtic::time::Instant<#app_path::#mangled_name> { rtic::export::interrupt::free(|_| { use rtic::Monotonic as _; use rtic::time::Clock as _; - if let Ok(v) = unsafe{ (&*#app_path::#ident.as_ptr()).try_now() } { - v + if let Some(m) = unsafe{ #app_path::#ident.as_ref() } { + if let Ok(v) = m.try_now() { + v + } else { + unreachable!("Your monotonic is not infallible!") + } } else { - unreachable!("Your monotonic is not infallible!") + panic!(#panic_str); } }) } diff --git a/macros/src/codegen/post_init.rs b/macros/src/codegen/post_init.rs index b6cf47c3d8..8ebcb12b19 100644 --- a/macros/src/codegen/post_init.rs +++ b/macros/src/codegen/post_init.rs @@ -35,7 +35,7 @@ pub fn codegen(app: &App, analysis: &Analysis) -> Vec { // Store the monotonic let name = util::monotonic_ident(&monotonic.to_string()); - stmts.push(quote!(#name.as_mut_ptr().write(monotonics.#idx);)); + stmts.push(quote!(#name = Some(monotonics.#idx);)); } // Enable the interrupts -- this completes the `init`-ialization phase diff --git a/macros/src/codegen/timer_queue.rs b/macros/src/codegen/timer_queue.rs index 54b2c1f059..65560680ae 100644 --- a/macros/src/codegen/timer_queue.rs +++ b/macros/src/codegen/timer_queue.rs @@ -69,11 +69,11 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec); + let mono_ty = quote!(Option<#m>); items.push(quote!( #[doc = #doc] - static mut #mono: #mono_ty = core::mem::MaybeUninit::uninit(); + static mut #mono: #mono_ty = None; )); } @@ -122,10 +122,15 @@ pub fn codegen(app: &App, analysis: &Analysis, _extra: &Extra) -> Vec