xref: /linux/rust/kernel/transmute.rs (revision 7ed188605e1d30e8b45d78846e3bc2bbb6394948)
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