Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use core::sync::atomic::AtomicU8;
- /// Build a slice of bytes that can be shared with arbitrary untrusted code
- ///
- /// This is an alternative to std::slice::from_raw_parts[_mut] for cases where
- /// the underlying bytes are shared with arbitrary and untrusted unsafe code.
- /// Which is extremely dangerous, because said code has countless ways to make
- /// us engage in Undefined Behavior, and LLVM will eat our laundry if it ever
- /// finds out that we're doing that.
- ///
- /// Remember that because the bytes are shared with untrusted code, you cannot
- /// assume anything about the values of the bytes in the slice (e.g. that they
- /// can be transmuted into a valid value of a certain type T), and you cannot
- /// rely on the other code to use atomic memory orderings correctly for
- /// synchronization.
- ///
- /// # Safety
- ///
- /// You are responsible for ensuring the following safety conditions:
- ///
- /// 1. The "data" pointer is neither null nor dangling, and will remain safe to
- /// dereference for the entire 'a lifetime. You do not need to care about
- /// alignment because `u8` is always well-aligned.
- /// 2. The specified "length" does not overflow the allocation backing the
- /// "data" pointer, and will never do so for the entire 'a lifetime.
- /// 3. No link-time optmizations are performed between you and the untrusted
- /// codebase. This is necessary because some "harmless" forms of Undefined
- /// Behavior cannot be avoided, and LLVM can miscompile your code if it is
- /// exposed to that UB.
- /// 4. The underlying hardware guarantees that reading an u8 from a valid pointer
- /// always yields a valid u8 value, and that writing an u8 using a valid
- /// pointer always succeeds.
- ///
- /// These conditions have the following implications:
- ///
- /// - The untrusted code must be unable to manipulate the shared allocation in
- /// harmful ways. In particular, it should not be able to deallocate the
- /// shared allocation, resize it, or unmap it from your virtual address space.
- /// - This, together with condition 3, implies that the untrusted code is either
- /// living in a separate OS process, or *both* linked to this process in an
- /// LTO-hostile way and sandboxed in such a manner that it cannot manipulate
- /// this process' memory allocations.
- /// - This abstraction is not suitable for exotic hardware architectures that
- /// can track uninitialized memory, or for accessing "exotic" memory such as
- /// memory-mapped IO and memory-mapped hardware registers.
- ///
- pub unsafe fn from_raw_parts_untrusted<'a>(data: *mut u8, length: usize) -> &'a [AtomicU8] {
- core::slice::from_raw_parts(data as *const AtomicU8, length)
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement