Skip to content

Potential UB due to data race between regular thread and interrupt handler #5

Closed
@RalfJung

Description

@RalfJung

The docs say

A compiler fence is sufficient for sharing a !Sync type, such as RefCell, with an interrupt handler on the same thread.

That's not quite true. A compiler fence plus using atomic accesses is sufficient. Non-atomic accesses still cause data races between a thread and its interrupt handler, even if you add all the fences in the world. This is because the interrupt handler could otherwise observe a state that's half-way through executing a Rust operation, which is not a state that can even be described in the Rust Abstract Machine. Also, compiler optimizations assume that non-atomic accesses cannot be observed and hence be arbitrarily reordered when there is no synchronization.

This crate needs to ensure interrupts are disabled on any racy read or write to shared data (in particular, the RefCell borrow tracking flags). In that case disabling the interrupts becomes the critical section (this also requires appropriate acquire/release fences, but I assume interrupt disabling/enabling is anyway done with inline assembly so the fences can be "implicit" in the inline asm block). It is concerning that the docs say interrupt disabling is best-effort, since that seems to imply that soundness is best-effort. If that's truly the case it definitely needs to be stated in stronger terms in the docs.

Metadata

Metadata

Assignees

Labels

No labels
No labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions