Advertisement
Guest User

Untitled

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