1 // SPDX-License-Identifier: GPL-2.0 2 3 //! Traits for transmuting types. 4 5 /// Types for which any bit pattern is valid. 6 /// 7 /// Not all types are valid for all values. For example, a `bool` must be either zero or one, so 8 /// reading arbitrary bytes into something that contains a `bool` is not okay. 9 /// 10 /// It's okay for the type to have padding, as initializing those bytes has no effect. 11 /// 12 /// # Safety 13 /// 14 /// All bit-patterns must be valid for this type. This type must not have interior mutability. 15 pub unsafe trait FromBytes {} 16 17 macro_rules! impl_frombytes { 18 ($($({$($generics:tt)*})? $t:ty, )*) => { 19 // SAFETY: Safety comments written in the macro invocation. 20 $(unsafe impl$($($generics)*)? FromBytes for $t {})* 21 }; 22 } 23 24 impl_frombytes! { 25 // SAFETY: All bit patterns are acceptable values of the types below. 26 u8, u16, u32, u64, usize, 27 i8, i16, i32, i64, isize, 28 29 // SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit 30 // patterns are also acceptable for arrays of that type. 31 {<T: FromBytes>} [T], 32 {<T: FromBytes, const N: usize>} [T; N], 33 } 34 35 /// Types that can be viewed as an immutable slice of initialized bytes. 36 /// 37 /// If a struct implements this trait, then it is okay to copy it byte-for-byte to userspace. This 38 /// means that it should not have any padding, as padding bytes are uninitialized. Reading 39 /// uninitialized memory is not just undefined behavior, it may even lead to leaking sensitive 40 /// information on the stack to userspace. 41 /// 42 /// The struct should also not hold kernel pointers, as kernel pointer addresses are also considered 43 /// sensitive. However, leaking kernel pointers is not considered undefined behavior by Rust, so 44 /// this is a correctness requirement, but not a safety requirement. 45 /// 46 /// # Safety 47 /// 48 /// Values of this type may not contain any uninitialized bytes. This type must not have interior 49 /// mutability. 50 pub unsafe trait AsBytes {} 51 52 macro_rules! impl_asbytes { 53 ($($({$($generics:tt)*})? $t:ty, )*) => { 54 // SAFETY: Safety comments written in the macro invocation. 55 $(unsafe impl$($($generics)*)? AsBytes for $t {})* 56 }; 57 } 58 59 impl_asbytes! { 60 // SAFETY: Instances of the following types have no uninitialized portions. 61 u8, u16, u32, u64, usize, 62 i8, i16, i32, i64, isize, 63 bool, 64 char, 65 str, 66 67 // SAFETY: If individual values in an array have no uninitialized portions, then the array 68 // itself does not have any uninitialized portions either. 69 {<T: AsBytes>} [T], 70 {<T: AsBytes, const N: usize>} [T; N], 71 } 72