Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

"Extra Sections" example is potentially unsound #498

Open
jamesmunns opened this issue Nov 26, 2023 · 4 comments
Open

"Extra Sections" example is potentially unsound #498

jamesmunns opened this issue Nov 26, 2023 · 4 comments
Labels
I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness

Comments

@jamesmunns
Copy link
Member

In the cortex-m-rt docs, the extra sections example shows the definition of a zero-initialized static mut array in a section outside of RAM.

I believe this to be unsound, and difficult, if not impossible, to use totally soundly.

The CRT is required to initialize all statics, either to their default value (in .data), or to zero (in .bss). cortex-m-rt explicitly only performs initialization for data and bss sections in the RAM region, meaning the CCRAM must be considered to be uninitialized in the example as currently written.

At the very least if we include an example like this, we should discuss this deficiency, and state that pre_init must be used to guarantee that the static is initialized at the start of the program.

I personally am of the opionion that we cannot soundly perform this initialization in a pre_init in Rust, as that means that Rust code is running without all statics initialized, which violates the agreement the language makes with the platform environment.

This argument is part of why we switched to an assembly CRT, rather than the previously Rust-based init sequence.

@jamesmunns
Copy link
Member Author

@Dirbaio noted (and I agree) that changing it to:

#[link_section=".ccmram.BUFFERS"]
static mut BUF: MaybeUninit<[u8; 1024]> = MaybeUninit::uninit();

alleviates the majority of the UB (though, still recommends static mut which is still hard to use right IMO, but is not "plainly always UB" anymore)

@thejpster
Copy link
Contributor

Can you soundly perform the initialisation in pre_init in assembly?

@jamesmunns
Copy link
Member Author

jamesmunns commented Nov 26, 2023

Can you soundly perform the initialisation in pre_init in assembly?

In my opinion, yes.

__pre_init is the actual ABI symbol for the function called BEFORE init AND BEFORE control transfer to Rust code. See here.

Assembly has no "abstract machine" requirements - so there isn't any soundness requirement here.

I'm not certain we could use inline assembly within a rust pre_init function, e.g. using the #[pre_init] macro, I believe it must be a global asm definition (or externally assembled file that defines the underlying __pre_init symbol).

edit: I was incorrect that __pre_init occured AFTER regular data/bss init, it actually takes place before either of those.

@adamgreig
Copy link
Member

I've updated the documentation in #525 to specify that you have to use MaybeUninit or pre_init, though I'd be open to adding a more useful/complete example too.

@newAM newAM added the I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness label Jun 30, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
I-unsound Issue: A soundness hole (worst kind of bug), see: https://en.wikipedia.org/wiki/Soundness
Projects
None yet
Development

No branches or pull requests

4 participants