Skip to content

Commit 6f89322

Browse files
bors[bot]jannic
andauthored
Merge #659
659: Make export::acquire() and export::release() unsafe r=Urhengulas a=jannic Calling export::release() may enable interrupts, which is unsound if done inside a critical section or other code which expects interrupts to be disabled. Calling export::acquire() is less dangerous (no obvious way to cause unsoundness), but is still a bad idea and breaks the safety contract of critical_section::acquire(), which must only be called paired with critical_section::release(). Co-authored-by: Jan Niehusmann <jan@gondor.com>
2 parents 9bbb0a9 + 3dca095 commit 6f89322

5 files changed

Lines changed: 28 additions & 10 deletions

File tree

CHANGELOG.md

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,10 @@ and this project adheres to [Semantic Versioning](http://semver.org/).
88
## [Unreleased]
99

1010
- [#640]: use crate [critical-section](https://crates.io/crates/critical-section) in defmt-rtt
11+
- [#659]: mark extern::acquire() and extern::release() as unsafe
12+
13+
[#640]: https://github.com/knurling-rs/defmt/pull/640
14+
[#659]: https://github.com/knurling-rs/defmt/pull/659
1115

1216
## [v0.3.1] - 2021-11-26
1317

defmt/src/export/mod.rs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -39,28 +39,36 @@ pub fn fetch_bytes() -> Vec<u8> {
3939
BYTES.with(|b| core::mem::replace(&mut *b.borrow_mut(), Vec::new()))
4040
}
4141

42+
/// Only to be used by the defmt macros
43+
/// Safety: must be paired with a later call to release()
4244
#[cfg(feature = "unstable-test")]
43-
pub fn acquire() {}
45+
pub unsafe fn acquire() {}
4446

47+
/// Only to be used by the defmt macros
48+
/// Safety: must be paired with a later call to release()
4549
#[cfg(not(feature = "unstable-test"))]
4650
#[inline(always)]
47-
pub fn acquire() {
51+
pub unsafe fn acquire() {
4852
extern "Rust" {
4953
fn _defmt_acquire();
5054
}
51-
unsafe { _defmt_acquire() }
55+
_defmt_acquire()
5256
}
5357

58+
/// Only to be used by the defmt macros
59+
/// Safety: must follow an earlier call to acquire()
5460
#[cfg(feature = "unstable-test")]
55-
pub fn release() {}
61+
pub unsafe fn release() {}
5662

63+
/// Only to be used by the defmt macros
64+
/// Safety: must follow an earlier call to acquire()
5765
#[cfg(not(feature = "unstable-test"))]
5866
#[inline(always)]
59-
pub fn release() {
67+
pub unsafe fn release() {
6068
extern "Rust" {
6169
fn _defmt_release();
6270
}
63-
unsafe { _defmt_release() }
71+
_defmt_release()
6472
}
6573

6674
#[cfg(feature = "unstable-test")]

firmware/defmt-rtt/src/lib.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ static mut ENCODER: defmt::Encoder = defmt::Encoder::new();
4242

4343
unsafe impl defmt::Logger for Logger {
4444
fn acquire() {
45+
// safety: Must be paired with corresponding call to release(), see below
4546
let token = unsafe { critical_section::acquire() };
4647

4748
if TAKEN.load(Ordering::Relaxed) {
@@ -67,6 +68,7 @@ unsafe impl defmt::Logger for Logger {
6768
ENCODER.end_frame(do_write);
6869

6970
TAKEN.store(false, Ordering::Relaxed);
71+
// safety: Must be paired with corresponding call to acquire(), see above
7072
critical_section::release(INTERRUPTS_ACTIVE.load(Ordering::Relaxed));
7173
}
7274

macros/src/function_like/log.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -44,10 +44,12 @@ pub(crate) fn expand_parsed(level: Level, args: Args) -> TokenStream2 {
4444
match (#(&(#formatting_exprs)),*) {
4545
(#(#patterns),*) => {
4646
if #filter_check {
47-
defmt::export::acquire();
47+
// safety: will be released a few lines further down
48+
unsafe { defmt::export::acquire() };
4849
defmt::export::header(&#header);
4950
#(#exprs;)*
50-
defmt::export::release()
51+
// safety: acquire() was called a few lines above
52+
unsafe { defmt::export::release() }
5153
}
5254
}
5355
}

macros/src/function_like/println.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -34,10 +34,12 @@ pub(crate) fn expand_parsed(args: Args) -> TokenStream2 {
3434
quote!({
3535
match (#(&(#formatting_exprs)),*) {
3636
(#(#patterns),*) => {
37-
defmt::export::acquire();
37+
// safety: will be released a few lines further down
38+
unsafe { defmt::export::acquire(); }
3839
defmt::export::header(&#header);
3940
#(#exprs;)*
40-
defmt::export::release()
41+
// safety: acquire() was called a few lines above
42+
unsafe { defmt::export::release() }
4143
}
4244
}
4345
})

0 commit comments

Comments
 (0)