1 // SPDX-License-Identifier: GPL-2.0 2 3 //! Traits for transmuting types. 4 5 use core::mem::size_of; 6 7 /// Types for which any bit pattern is valid. 8 /// 9 /// Not all types are valid for all values. For example, a `bool` must be either zero or one, so 10 /// reading arbitrary bytes into something that contains a `bool` is not okay. 11 /// 12 /// It's okay for the type to have padding, as initializing those bytes has no effect. 13 /// 14 /// # Examples 15 /// 16 /// ``` 17 /// use kernel::transmute::FromBytes; 18 /// 19 /// # fn test() -> Option<()> { 20 /// let raw = [1, 2, 3, 4]; 21 /// 22 /// let result = u32::from_bytes(&raw)?; 23 /// 24 /// #[cfg(target_endian = "little")] 25 /// assert_eq!(*result, 0x4030201); 26 /// 27 /// #[cfg(target_endian = "big")] 28 /// assert_eq!(*result, 0x1020304); 29 /// 30 /// # Some(()) } 31 /// # test().ok_or(EINVAL)?; 32 /// # Ok::<(), Error>(()) 33 /// ``` 34 /// 35 /// # Safety 36 /// 37 /// All bit-patterns must be valid for this type. This type must not have interior mutability. 38 pub unsafe trait FromBytes { 39 /// Converts a slice of bytes to a reference to `Self`. 40 /// 41 /// Succeeds if the reference is properly aligned, and the size of `bytes` is equal to that of 42 /// `T` and different from zero. 43 /// 44 /// Otherwise, returns [`None`]. 45 fn from_bytes(bytes: &[u8]) -> Option<&Self> 46 where 47 Self: Sized, 48 { 49 let slice_ptr = bytes.as_ptr().cast::<Self>(); 50 let size = size_of::<Self>(); 51 52 if bytes.len() == size && slice_ptr.is_aligned() { 53 // SAFETY: Size and alignment were just checked. 54 unsafe { Some(&*slice_ptr) } 55 } else { 56 None 57 } 58 } 59 60 /// Converts the beginning of `bytes` to a reference to `Self`. 61 /// 62 /// This method is similar to [`Self::from_bytes`], with the difference that `bytes` does not 63 /// need to be the same size of `Self` - the appropriate portion is cut from the beginning of 64 /// `bytes`, and the remainder returned alongside `Self`. 65 fn from_bytes_prefix(bytes: &[u8]) -> Option<(&Self, &[u8])> 66 where 67 Self: Sized, 68 { 69 if bytes.len() < size_of::<Self>() { 70 None 71 } else { 72 // PANIC: We checked that `bytes.len() >= size_of::<Self>`, thus `split_at` cannot 73 // panic. 74 // TODO: replace with `split_at_checked` once the MSRV is >= 1.80. 75 let (prefix, remainder) = bytes.split_at(size_of::<Self>()); 76 77 Self::from_bytes(prefix).map(|s| (s, remainder)) 78 } 79 } 80 81 /// Converts a mutable slice of bytes to a reference to `Self`. 82 /// 83 /// Succeeds if the reference is properly aligned, and the size of `bytes` is equal to that of 84 /// `T` and different from zero. 85 /// 86 /// Otherwise, returns [`None`]. 87 fn from_bytes_mut(bytes: &mut [u8]) -> Option<&mut Self> 88 where 89 Self: AsBytes + Sized, 90 { 91 let slice_ptr = bytes.as_mut_ptr().cast::<Self>(); 92 let size = size_of::<Self>(); 93 94 if bytes.len() == size && slice_ptr.is_aligned() { 95 // SAFETY: Size and alignment were just checked. 96 unsafe { Some(&mut *slice_ptr) } 97 } else { 98 None 99 } 100 } 101 102 /// Converts the beginning of `bytes` to a mutable reference to `Self`. 103 /// 104 /// This method is similar to [`Self::from_bytes_mut`], with the difference that `bytes` does 105 /// not need to be the same size of `Self` - the appropriate portion is cut from the beginning 106 /// of `bytes`, and the remainder returned alongside `Self`. 107 fn from_bytes_mut_prefix(bytes: &mut [u8]) -> Option<(&mut Self, &mut [u8])> 108 where 109 Self: AsBytes + Sized, 110 { 111 if bytes.len() < size_of::<Self>() { 112 None 113 } else { 114 // PANIC: We checked that `bytes.len() >= size_of::<Self>`, thus `split_at_mut` cannot 115 // panic. 116 // TODO: replace with `split_at_mut_checked` once the MSRV is >= 1.80. 117 let (prefix, remainder) = bytes.split_at_mut(size_of::<Self>()); 118 119 Self::from_bytes_mut(prefix).map(|s| (s, remainder)) 120 } 121 } 122 123 /// Creates an owned instance of `Self` by copying `bytes`. 124 /// 125 /// Unlike [`FromBytes::from_bytes`], which requires aligned input, this method can be used on 126 /// non-aligned data at the cost of a copy. 127 fn from_bytes_copy(bytes: &[u8]) -> Option<Self> 128 where 129 Self: Sized, 130 { 131 if bytes.len() == size_of::<Self>() { 132 // SAFETY: we just verified that `bytes` has the same size as `Self`, and per the 133 // invariants of `FromBytes`, any byte sequence of the correct length is a valid value 134 // for `Self`. 135 Some(unsafe { core::ptr::read_unaligned(bytes.as_ptr().cast::<Self>()) }) 136 } else { 137 None 138 } 139 } 140 141 /// Creates an owned instance of `Self` from the beginning of `bytes`. 142 /// 143 /// This method is similar to [`Self::from_bytes_copy`], with the difference that `bytes` does 144 /// not need to be the same size of `Self` - the appropriate portion is cut from the beginning 145 /// of `bytes`, and the remainder returned alongside `Self`. 146 fn from_bytes_copy_prefix(bytes: &[u8]) -> Option<(Self, &[u8])> 147 where 148 Self: Sized, 149 { 150 if bytes.len() < size_of::<Self>() { 151 None 152 } else { 153 // PANIC: We checked that `bytes.len() >= size_of::<Self>`, thus `split_at` cannot 154 // panic. 155 // TODO: replace with `split_at_checked` once the MSRV is >= 1.80. 156 let (prefix, remainder) = bytes.split_at(size_of::<Self>()); 157 158 Self::from_bytes_copy(prefix).map(|s| (s, remainder)) 159 } 160 } 161 } 162 163 macro_rules! impl_frombytes { 164 ($($({$($generics:tt)*})? $t:ty, )*) => { 165 // SAFETY: Safety comments written in the macro invocation. 166 $(unsafe impl$($($generics)*)? FromBytes for $t {})* 167 }; 168 } 169 170 impl_frombytes! { 171 // SAFETY: Inhabited ZSTs only have one possible bit pattern, and these two have no invariant. 172 (), 173 {<T>} core::marker::PhantomData<T>, 174 175 // SAFETY: All bit patterns are acceptable values of the types below. 176 u8, u16, u32, u64, usize, 177 i8, i16, i32, i64, isize, 178 179 // SAFETY: If all bit patterns are acceptable for individual values in an array, then all bit 180 // patterns are also acceptable for arrays of that type. 181 {<T: FromBytes>} [T], 182 {<T: FromBytes, const N: usize>} [T; N], 183 } 184 185 /// Types that can be viewed as an immutable slice of initialized bytes. 186 /// 187 /// If a struct implements this trait, then it is okay to copy it byte-for-byte to userspace. This 188 /// means that it should not have any padding, as padding bytes are uninitialized. Reading 189 /// uninitialized memory is not just undefined behavior, it may even lead to leaking sensitive 190 /// information on the stack to userspace. 191 /// 192 /// The struct should also not hold kernel pointers, as kernel pointer addresses are also considered 193 /// sensitive. However, leaking kernel pointers is not considered undefined behavior by Rust, so 194 /// this is a correctness requirement, but not a safety requirement. 195 /// 196 /// # Safety 197 /// 198 /// Values of this type may not contain any uninitialized bytes. This type must not have interior 199 /// mutability. 200 pub unsafe trait AsBytes { 201 /// Returns `self` as a slice of bytes. 202 fn as_bytes(&self) -> &[u8] { 203 // CAST: `Self` implements `AsBytes` thus all bytes of `self` are initialized. 204 let data = core::ptr::from_ref(self).cast::<u8>(); 205 let len = core::mem::size_of_val(self); 206 207 // SAFETY: `data` is non-null and valid for reads of `len * sizeof::<u8>()` bytes. 208 unsafe { core::slice::from_raw_parts(data, len) } 209 } 210 211 /// Returns `self` as a mutable slice of bytes. 212 fn as_bytes_mut(&mut self) -> &mut [u8] 213 where 214 Self: FromBytes, 215 { 216 // CAST: `Self` implements both `AsBytes` and `FromBytes` thus making `Self` 217 // bi-directionally transmutable to `[u8; size_of_val(self)]`. 218 let data = core::ptr::from_mut(self).cast::<u8>(); 219 let len = core::mem::size_of_val(self); 220 221 // SAFETY: `data` is non-null and valid for read and writes of `len * sizeof::<u8>()` 222 // bytes. 223 unsafe { core::slice::from_raw_parts_mut(data, len) } 224 } 225 } 226 227 macro_rules! impl_asbytes { 228 ($($({$($generics:tt)*})? $t:ty, )*) => { 229 // SAFETY: Safety comments written in the macro invocation. 230 $(unsafe impl$($($generics)*)? AsBytes for $t {})* 231 }; 232 } 233 234 impl_asbytes! { 235 // SAFETY: Inhabited ZSTs only have one possible bit pattern, and these two have no invariant. 236 (), 237 {<T>} core::marker::PhantomData<T>, 238 239 // SAFETY: Instances of the following types have no uninitialized portions. 240 u8, u16, u32, u64, usize, 241 i8, i16, i32, i64, isize, 242 bool, 243 char, 244 str, 245 246 // SAFETY: If individual values in an array have no uninitialized portions, then the array 247 // itself does not have any uninitialized portions either. 248 {<T: AsBytes>} [T], 249 {<T: AsBytes, const N: usize>} [T; N], 250 } 251