| // SPDX-License-Identifier: GPL-2.0 | |
| //! Traits for transmuting types. | |
| use core::mem::size_of; | |
| /// Types for which any bit pattern is valid. | |
| /// | |
| /// Not all types are valid for all values. For example, a `bool` must be either zero or one, so | |
| /// reading arbitrary bytes into something that contains a `bool` is not okay. | |
| /// | |
| /// It's okay for the type to have padding, as initializing those bytes has no effect. | |
| /// | |
| /// # Examples | |
| /// | |
| /// ``` | |
| /// use kernel::transmute::FromBytes; | |
| /// | |
| /// # fn test() -> Option<()> { | |
| /// let raw = [1, 2, 3, 4]; | |
| /// | |
| /// let result = u32::from_bytes(&raw)?; | |
| /// | |
| /// #[cfg(target_endian = "little")] | |
| /// assert_eq!(*result, 0x4030201); | |
| /// | |
| /// #[cfg(target_endian = "big")] | |
| /// assert_eq!(*result, 0x1020304); | |
| /// | |
| /// # Some(()) } | |
| /// # test().ok_or(EINVAL)?; | |
| /// # Ok::<(), Error>(()) | |
| /// ``` | |
| /// | |
| /// # Safety | |
| /// | |
| /// All bit-patterns must be valid for this type. This type must not have interior mutability. | |
| pub unsafe trait FromBytes { | |
| /// Converts a slice of bytes to a reference to `Self`. | |
| /// | |
| /// Succeeds if the reference is properly aligned, and the size of `bytes` is equal to that of | |
| /// `T` and different from zero. | |
| /// | |
| /// Otherwise, returns [`None`]. | |
| fn from_bytes(bytes: &[u8]) -> Option<&Self> | |
| where | |
| Self: Sized, | |
| { | |
| let slice_ptr = bytes.as_ptr().cast::<Self>(); | |
| let size = size_of::<Self>(); | |
| if bytes.len() == size && slice_ptr.is_aligned() { | |
| // SAFETY: Size and alignment were just checked. | |
| unsafe { Some(&*slice_ptr) } | |
| } else { | |
| None | |
| } | |
| } | |
| /// Converts the beginning of `bytes` to a reference to `Self`. | |
| /// | |
| /// This method is similar to [`Self::from_bytes`], with the difference that `bytes` does not | |
| /// need to be the same size of `Self` - the appropriate portion is cut from the beginning of | |
| /// `bytes`, and the remainder returned alongside `Self`. | |
| fn from_bytes_prefix(bytes: &[u8]) -> Option<(&Self, &[u8])> | |
| where | |
| Self: Sized, | |
| { | |
| let (prefix, remainder) = bytes.split_at_checked(size_of::<Self>())?; | |
| Self::from_bytes(prefix).map(|s| (s, remainder)) | |
| } | |
| /// Converts a mutable slice of bytes to a reference to `Self`. | |
| /// | |
| /// Succeeds if the reference is properly aligned, and the size of `bytes` is equal to that of | |
| /// `T` and different from zero. | |
| /// | |
| /// Otherwise, returns [`None`]. | |
| fn from_bytes_mut(bytes: &mut [u8]) -> Option<&mut Self> | |
| where | |
| Self: AsBytes + Sized, | |
| { | |
| let slice_ptr = bytes.as_mut_ptr().cast::<Self>(); | |
| let size = size_of::<Self>(); | |
| if bytes.len() == size && slice_ptr.is_aligned() { | |
| // SAFETY: Size and alignment were just checked. | |
| unsafe { Some(&mut *slice_ptr) } | |
| } else { | |
| None | |
| } | |
| } | |
| /// Converts the beginning of `bytes` to a mutable reference to `Self`. | |
| /// | |
| /// This method is similar to [`Self::from_bytes_mut`], with the difference that `bytes` does | |
| /// not need to be the same size of `Self` - the appropriate portion is cut from the beginning | |
| /// of `bytes`, and the remainder returned alongside `Self`. | |
| fn from_bytes_mut_prefix(bytes: &mut [u8]) -> Option<(&mut Self, &mut [u8])> | |
| where | |
| Self: AsBytes + Sized, | |
| { | |
| let (prefix, remainder) = bytes.split_at_mut_checked(size_of::<Self>())?; | |
| Self::from_bytes_mut(prefix).map(|s| (s, remainder)) | |
| } | |
| /// Creates an owned instance of `Self` by copying `bytes`. | |
| /// | |
| /// Unlike [`FromBytes::from_bytes`], which requires aligned input, this method can be used on | |
| /// non-aligned data at the cost of a copy. | |
| fn from_bytes_copy(bytes: &[u8]) -> Option<Self> | |
| where | |
| Self: Sized, | |
| { | |
| if bytes.len() == size_of::<Self>() { | |
| // SAFETY: we just verified that `bytes` has the same size as `Self`, and per the | |
| // invariants of `FromBytes`, any byte sequence of the correct length is a valid value | |
| // for `Self`. | |
| Some(unsafe { core::ptr::read_unaligned(bytes.as_ptr().cast::<Self>()) }) | |
| } else { | |
| None | |
| } | |
| } | |
| /// Creates an owned instance of `Self` from the beginning of `bytes`. | |
| /// | |
| /// This method is similar to [`Self::from_bytes_copy`], with the difference that `bytes` does | |
| /// not need to be the same size of `Self` - the appropriate portion is cut from the beginning | |
| /// of `bytes`, and the remainder returned alongside `Self`. | |
| fn from_bytes_copy_prefix(bytes: &[u8]) -> Option<(Self, &[u8])> | |
| where | |
| Self: Sized, | |
| { | |
| let (prefix, remainder) = bytes.split_at_checked(size_of::<Self>())?; | |
| Self::from_bytes_copy(prefix).map(|s| (s, remainder)) | |
| } | |
| } | |
| macro_rules! impl_frombytes { | |
| ($($({$($generics:tt)*})? $t:ty, )*) => { | |
| // SAFETY: Safety comments written in the macro invocation. | |
| $(unsafe impl$($($generics)*)? FromBytes for $t {})* | |
| }; | |
| } | |
| impl_frombytes! { | |
| // SAFETY: Inhabited ZSTs only have one possible bit pattern, and these two have no invariant. | |
| (), | |
| {<T>} core::marker::PhantomData<T>, | |
| // SAFETY: All bit patterns are acceptable values of the types below. | |
| u8, u16, u32, u64, usize, | |
| i8, i16, i32, i64, isize, | |
| // SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit | |
| // patterns are also acceptable for arrays of that type. | |
| {<T: FromBytes>} [T], | |
| {<T: FromBytes, const N: usize>} [T; N], | |
| } | |
| /// Types that can be viewed as an immutable slice of initialized bytes. | |
| /// | |
| /// If a struct implements this trait, then it is okay to copy it byte-for-byte to userspace. This | |
| /// means that it should not have any padding, as padding bytes are uninitialized. Reading | |
| /// uninitialized memory is not just undefined behavior, it may even lead to leaking sensitive | |
| /// information on the stack to userspace. | |
| /// | |
| /// The struct should also not hold kernel pointers, as kernel pointer addresses are also considered | |
| /// sensitive. However, leaking kernel pointers is not considered undefined behavior by Rust, so | |
| /// this is a correctness requirement, but not a safety requirement. | |
| /// | |
| /// # Safety | |
| /// | |
| /// Values of this type may not contain any uninitialized bytes. This type must not have interior | |
| /// mutability. | |
| pub unsafe trait AsBytes { | |
| /// Returns `self` as a slice of bytes. | |
| fn as_bytes(&self) -> &[u8] { | |
| // CAST: `Self` implements `AsBytes` thus all bytes of `self` are initialized. | |
| let data = core::ptr::from_ref(self).cast::<u8>(); | |
| let len = core::mem::size_of_val(self); | |
| // SAFETY: `data` is non-null and valid for reads of `len * sizeof::<u8>()` bytes. | |
| unsafe { core::slice::from_raw_parts(data, len) } | |
| } | |
| /// Returns `self` as a mutable slice of bytes. | |
| fn as_bytes_mut(&mut self) -> &mut [u8] | |
| where | |
| Self: FromBytes, | |
| { | |
| // CAST: `Self` implements both `AsBytes` and `FromBytes` thus making `Self` | |
| // bi-directionally transmutable to `[u8; size_of_val(self)]`. | |
| let data = core::ptr::from_mut(self).cast::<u8>(); | |
| let len = core::mem::size_of_val(self); | |
| // SAFETY: `data` is non-null and valid for read and writes of `len * sizeof::<u8>()` | |
| // bytes. | |
| unsafe { core::slice::from_raw_parts_mut(data, len) } | |
| } | |
| } | |
| macro_rules! impl_asbytes { | |
| ($($({$($generics:tt)*})? $t:ty, )*) => { | |
| // SAFETY: Safety comments written in the macro invocation. | |
| $(unsafe impl$($($generics)*)? AsBytes for $t {})* | |
| }; | |
| } | |
| impl_asbytes! { | |
| // SAFETY: Inhabited ZSTs only have one possible bit pattern, and these two have no invariant. | |
| (), | |
| {<T>} core::marker::PhantomData<T>, | |
| // SAFETY: Instances of the following types have no uninitialized portions. | |
| u8, u16, u32, u64, usize, | |
| i8, i16, i32, i64, isize, | |
| bool, | |
| char, | |
| str, | |
| // SAFETY: If individual values in an array have no uninitialized portions, then the array | |
| // itself does not have any uninitialized portions either. | |
| {<T: AsBytes>} [T], | |
| {<T: AsBytes, const N: usize>} [T; N], | |
| } |