Something went wrong. Try again.
(I'm so sorry!) Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
Something went wrong. Try again.
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230// 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],}