Avoiding UB in shared mutable state


#1

Say you have two mutually distrustful processes communicating using a shared memory buffer. Neither & nor &mut are correct to use in this case, because the other process might modify the underlying memory, violating either immutability or aliasing guarantees. What is the correct way to model this in Rust? Similar questions apply to memory-mapped files, etc.


#2

Either copy to a private buffer (one-copy, not zero-copy) or somehow lock/seal the file (for linux, see: https://lwn.net/Articles/593918/).


#3

In case I misunderstood your question, the correct pointer type (before sealing/copying) would be *mut u8 (mutable, potentially aliased, pointer into arbitrary memory).


#4

Use ptr::read_volatile and ptr::write_volatile with a raw pointer. This will ensure that values are only read once from memory and prevents the compiler from assuming that the data won’t change between reads. Only trust data after you have read it into your own memory so that it won’t change between reads.


#5

If you want to be really paranoid, keep in mind that if one process shrinks the size of the shared file (ftruncate on Linux for example) then any accesses to parts of the memory mapping that no longer contain valid file data may trigger a SIGBUS signal.

There are ways to protect against this, but at that point we’re getting into really platform/architecture-specific details.