• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2024, The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *     http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 //! Utilities for serialization and deserialization.
18 
19 use std::{
20     collections::TryReserveError,
21     fmt::Debug,
22     ops::{Deref, DerefMut},
23 };
24 use zerocopy::{FromBytes, Immutable, IntoBytes, KnownLayout, Unalign};
25 
26 /// A `Vec` wrapper that is compatible with tipc serialization.
27 ///
28 /// Automatic tipc serde is implemented for `T` that can be freely converted
29 /// to and from bytes.
30 ///
31 /// # The `len` field
32 ///
33 /// The current design of [`Serialize::serialize`] means that it needs to
34 /// output a `&[u8]` that is directly tied to the lifetime of a `&Self`.
35 /// `Vec::len` returns a `usize` instead of `&u32`, so `as_bytes` borrows
36 /// a temporary. `Vec` does not expose a method to borrow its length field.
37 /// There's no way to do this stably even with `unsafe`.
38 ///
39 /// So, a secondary field is used and its value kept in-sync with the inner `Vec`.
40 /// Any used `&mut Vec` methods should be mirrored.
41 ///
42 /// # The `MAX_LEN` parameter
43 ///
44 /// This is used to calculate the correct `Deserialize::MAX_SERIALIZED_SIZE`.
45 /// Constructing a `SerdeVec` with a length larger than `MAX_LEN` is allowed,
46 /// but may not be deserializable on the receiving end - use `is_over_max_len`
47 /// to check.
48 #[derive(Debug, Default)]
49 pub struct SerdeVec<T, const MAX_LEN: u32> {
50     len: u32,
51     values: Vec<T>,
52 }
53 
54 impl<T, const MAX_LEN: u32> Deref for SerdeVec<T, MAX_LEN> {
55     type Target = [T];
56 
deref(&self) -> &[T]57     fn deref(&self) -> &[T] {
58         &self.values
59     }
60 }
61 
62 impl<T, const MAX_LEN: u32> DerefMut for SerdeVec<T, MAX_LEN> {
deref_mut(&mut self) -> &mut [T]63     fn deref_mut(&mut self) -> &mut [T] {
64         &mut self.values
65     }
66 }
67 
68 impl<T, const MAX_LEN: u32> SerdeVec<T, MAX_LEN> {
69     /// Returns whether `self.len() > MAX_LEN`.
is_over_max_len(&self) -> bool70     pub fn is_over_max_len(&self) -> bool {
71         assert_eq!(self.len, self.values.len().try_into().unwrap(), "length invariant invalidated");
72         self.len > MAX_LEN
73     }
74 
sync_len(&mut self)75     fn sync_len(&mut self) {
76         self.len = self.values.len().try_into().expect("len shouldn't be able to exceed u32::MAX");
77     }
78 
79     /// See [`Vec::push`]
push(&mut self, val: T)80     pub fn push(&mut self, val: T) {
81         // TODO: kupiakos - ensure that the length can't exceed `u32::MAX`
82         self.values.push(val);
83         self.sync_len();
84     }
85 }
86 
87 impl<'s, T: Immutable + IntoBytes + 's, const MAX_LEN: u32> Serialize<'s> for SerdeVec<T, MAX_LEN> {
serialize<'a: 's, S: Serializer<'s>>( &'a self, serializer: &mut S, ) -> Result<S::Ok, S::Error>88     fn serialize<'a: 's, S: Serializer<'s>>(
89         &'a self,
90         serializer: &mut S,
91     ) -> Result<S::Ok, S::Error> {
92         serializer.serialize_bytes(self.len.as_bytes())?;
93         serializer.serialize_bytes(self[..].as_bytes())
94     }
95 }
96 
97 impl<T: Immutable + KnownLayout + IntoBytes + FromBytes + 'static, const MAX_LEN: u32>
98     DeserializePrefix for SerdeVec<T, MAX_LEN>
99 {
100     const MAX_SERIALIZED_SIZE: usize = size_of::<u32>() + size_of::<T>() * MAX_LEN as usize;
101 
deserialize_prefix(bytes: &mut &[u8]) -> Result<Self, DeserializeError>102     fn deserialize_prefix(bytes: &mut &[u8]) -> Result<Self, DeserializeError> {
103         let Ok((len, tail)) = u32::read_from_prefix(bytes) else {
104             return Err(DeserializeError::NotEnoughBuffer);
105         };
106         let len_usize = u32_to_usize(len);
107         let Ok((contents, rest)) = <[Unalign<T>]>::ref_from_prefix_with_elems(tail, len_usize)
108         else {
109             return Err(DeserializeError::NotEnoughBuffer);
110         };
111         let mut values = T::new_vec_zeroed(len_usize)?;
112         values.as_mut_bytes().copy_from_slice(contents.as_bytes());
113         *bytes = rest;
114         Ok(Self { len, values })
115     }
116 }
117 
118 /// An `Option` alternative that is compatible with tipc serialization.
119 #[repr(u8)]
120 pub enum SerdeOption<T> {
121     /// Equivalent to [`Option::None`].
122     None = 0,
123 
124     /// Equivalent to [`Option::Some`].
125     Some(T) = 1,
126 }
127 
128 impl<T> From<SerdeOption<T>> for Option<T> {
from(value: SerdeOption<T>) -> Self129     fn from(value: SerdeOption<T>) -> Self {
130         match value {
131             SerdeOption::None => None,
132             SerdeOption::Some(x) => Some(x),
133         }
134     }
135 }
136 
137 impl<T> From<Option<T>> for SerdeOption<T> {
from(value: Option<T>) -> Self138     fn from(value: Option<T>) -> Self {
139         match value {
140             None => SerdeOption::None,
141             Some(x) => SerdeOption::Some(x),
142         }
143     }
144 }
145 
146 impl<'s, T: Serialize<'s>> Serialize<'s> for SerdeOption<T> {
serialize<'a: 's, S: Serializer<'s>>( &'a self, serializer: &mut S, ) -> Result<S::Ok, S::Error>147     fn serialize<'a: 's, S: Serializer<'s>>(
148         &'a self,
149         serializer: &mut S,
150     ) -> Result<S::Ok, S::Error> {
151         // TODO: b/372549215 - replace with zerocopy extracting the discriminant ref directly.
152         let discriminant = match self {
153             SerdeOption::Some(_) => &1u8,
154             _ => &0u8,
155         };
156         let ok = serializer.serialize_bytes(discriminant.as_bytes())?;
157         match self {
158             SerdeOption::Some(val) => val.serialize(serializer),
159             _ => Ok(ok),
160         }
161     }
162 }
163 
164 impl<T: DeserializePrefix> DeserializePrefix for SerdeOption<T> {
165     const MAX_SERIALIZED_SIZE: usize = size_of::<u8>() + T::MAX_SERIALIZED_SIZE;
166 
deserialize_prefix(bytes: &mut &[u8]) -> Result<Self, DeserializeError>167     fn deserialize_prefix(bytes: &mut &[u8]) -> Result<Self, DeserializeError> {
168         let &[has_value, ref rest @ ..] = *bytes else {
169             return Err(DeserializeError::NotEnoughBuffer);
170         };
171         *bytes = rest;
172         let has_value = has_value != 0;
173         Ok(if has_value {
174             SerdeOption::Some(T::deserialize_prefix(bytes)?)
175         } else {
176             SerdeOption::None
177         })
178     }
179 }
180 
181 /// An error that occurred while deserializing.
182 #[derive(Debug)]
183 pub enum DeserializeError {
184     /// The input buffer to deserialize was too small.
185     NotEnoughBuffer,
186 
187     /// There were unacceptable bits in the input buffer.
188     InvalidValue,
189 
190     /// Dynamic allocation failed.
191     Alloc,
192 }
193 
194 impl From<zerocopy::error::AllocError> for DeserializeError {
from(_: zerocopy::error::AllocError) -> Self195     fn from(_: zerocopy::error::AllocError) -> Self {
196         DeserializeError::Alloc
197     }
198 }
199 
200 impl From<TryReserveError> for DeserializeError {
from(_: TryReserveError) -> Self201     fn from(_: TryReserveError) -> Self {
202         DeserializeError::Alloc
203     }
204 }
205 
206 /// A copy of `tipc::Serializer` that can be used outside of Trusty.
207 pub trait Serializer<'s> {
208     /// The value that is outputted upon success.
209     type Ok;
210 
211     /// The value that is outputted upon error.
212     type Error: Debug;
213 
214     /// Serialize a sequence of bytes.
serialize_bytes(&mut self, bytes: &'s [u8]) -> Result<Self::Ok, Self::Error>215     fn serialize_bytes(&mut self, bytes: &'s [u8]) -> Result<Self::Ok, Self::Error>;
216 }
217 
218 // A newtype is not necessary here because it implements a local trait for foreign types.
219 #[cfg(target_os = "trusty")]
220 impl<'s, S: tipc::Serializer<'s>> Serializer<'s> for S {
221     type Ok = <S as tipc::Serializer<'s>>::Ok;
222     type Error = <S as tipc::Serializer<'s>>::Error;
223 
serialize_bytes(&mut self, bytes: &'s [u8]) -> Result<Self::Ok, Self::Error>224     fn serialize_bytes(&mut self, bytes: &'s [u8]) -> Result<Self::Ok, Self::Error> {
225         <S as tipc::Serializer<'s>>::serialize_bytes(self, bytes)
226     }
227 }
228 
229 /// A copy of `tipc::Serialize` that can be used outside of Trusty.
230 pub trait Serialize<'s> {
231     /// Serialize this data as a byte slice that lives for at least as long as `&self`.
serialize<'a: 's, S: Serializer<'s>>( &'a self, serializer: &mut S, ) -> Result<S::Ok, S::Error>232     fn serialize<'a: 's, S: Serializer<'s>>(
233         &'a self,
234         serializer: &mut S,
235     ) -> Result<S::Ok, S::Error>;
236 }
237 
238 #[cfg(target_os = "trusty")]
239 /// Newtype which forwards a local `Serialize` impl to the `tipc` version.
240 pub struct ForwardTipcSerialize<'a, T>(pub &'a T);
241 
242 #[cfg(target_os = "trusty")]
243 impl<'b, 's, T: Serialize<'s>> tipc::Serialize<'s> for ForwardTipcSerialize<'b, T>
244 where
245     's: 'b,
246 {
serialize<'a: 's, S: tipc::Serializer<'s>>( &'a self, serializer: &mut S, ) -> Result<S::Ok, S::Error>247     fn serialize<'a: 's, S: tipc::Serializer<'s>>(
248         &'a self,
249         serializer: &mut S,
250     ) -> Result<S::Ok, S::Error> {
251         <T as Serialize<'s>>::serialize(self.0, serializer)
252     }
253 }
254 
255 /// A composable version of `tipc::Deserialize` that parses the start of the input.
256 pub trait DeserializePrefix: Sized {
257     /// The maximum number of bytes that can be deserialized into this type.
258     ///
259     /// Used to reserve sufficient space.
260     const MAX_SERIALIZED_SIZE: usize;
261 
262     /// Deserializes `Self` from the prefix of `bytes`,
263     /// mutating the input slice to remove the prefix that was deserialized.
264     ///
265     /// On an `Err` return, the slice left in `bytes` is unspecified.
deserialize_prefix(bytes: &mut &[u8]) -> Result<Self, DeserializeError>266     fn deserialize_prefix(bytes: &mut &[u8]) -> Result<Self, DeserializeError>;
267 }
268 
269 #[cfg(target_os = "trusty")]
270 /// Newtype to forward a [`DeserializePrefix`] impl as `tipc::Deserialize`,
271 /// rejecting the input buffer if larger than what `DeserializePrefix` parsed.
272 ///
273 /// Ignores the `handles` parameter.
274 pub struct DeserializeExact<T>(pub T);
275 
276 #[cfg(target_os = "trusty")]
277 impl<T: DeserializePrefix> tipc::Deserialize for DeserializeExact<T> {
278     type Error = tipc::TipcError;
279     const MAX_SERIALIZED_SIZE: usize = T::MAX_SERIALIZED_SIZE;
280 
deserialize(mut bytes: &[u8], _: &mut [Option<tipc::Handle>]) -> Result<Self, Self::Error>281     fn deserialize(mut bytes: &[u8], _: &mut [Option<tipc::Handle>]) -> Result<Self, Self::Error> {
282         let out = T::deserialize_prefix(&mut bytes).map_err(|e| match e {
283             DeserializeError::InvalidValue => tipc::TipcError::InvalidData,
284             DeserializeError::NotEnoughBuffer => tipc::TipcError::NotEnoughBuffer,
285             DeserializeError::Alloc => tipc::TipcError::AllocError,
286         })?;
287         if bytes.is_empty() {
288             Ok(DeserializeExact(out))
289         } else {
290             // TODO: kupiakos - log that the message is too long
291             Err(tipc::TipcError::InvalidData)
292         }
293     }
294 }
295 
field_max_serialized_size<T, U: DeserializePrefix>( _accessor: &impl FnOnce(&T) -> &U, ) -> usize296 pub(crate) const fn field_max_serialized_size<T, U: DeserializePrefix>(
297     _accessor: &impl FnOnce(&T) -> &U,
298 ) -> usize {
299     U::MAX_SERIALIZED_SIZE
300 }
301 
sum_usize(elems: &[usize]) -> usize302 pub(crate) const fn sum_usize(elems: &[usize]) -> usize {
303     let mut sum = 0;
304     let mut i = 0;
305     while i < elems.len() {
306         sum += elems[i];
307         i += 1;
308     }
309     sum
310 }
311 
312 /// Returns `0` if `elems` is empty.
max_usize(elems: &[usize]) -> usize313 pub(crate) const fn max_usize(elems: &[usize]) -> usize {
314     let mut max = None;
315     let mut i = 0;
316     while i < elems.len() {
317         let elem = elems[i];
318         match max {
319             Some(current) if current > elem => {}
320             _ => max = Some(elem),
321         }
322         i += 1;
323     }
324     match max {
325         Some(x) => x,
326         None => 0,
327     }
328 }
329 
330 /// Infallibly convert a `u32` to `usize`. Fails to compile if `usize` is 16-bit.
u32_to_usize(x: u32) -> usize331 const fn u32_to_usize(x: u32) -> usize {
332     const _: () = assert!(size_of::<u32>() <= size_of::<usize>(), "16-bit usize is unsupported");
333     x as usize
334 }
335 
336 /// Defines a new enum with fields that may be serialized/deserialized automatically.
337 ///
338 /// Supports enums whose variants have either no data or a single field of one token.
339 /// Note: if an enum has no data to carry, serialize the bytes directly with zerocopy.
340 macro_rules! serde_enums {
341     (@match_variant_pat $data:ident, $name:ident :: $variant:ident,) => {
342         $name::$variant
343     };
344     (@match_variant_pat $data:ident, $name:ident :: $variant:ident, $inner:tt) => {
345         $name::$variant($data)
346     };
347     (@serialize_variant_arm $data:ident, $discriminant:expr, $serializer:ident, ) => {{
348         let discriminant: &'static u8 = &$discriminant;
349         $crate::util::Serialize::serialize(discriminant, $serializer)
350     }};
351     (@serialize_variant_arm $data:ident, $discriminant:expr, $serializer:ident, $inner:tt) => {{
352         // TODO: b/372549215 - replace with zerocopy extracting the discriminant ref directly.
353         // The discriminant expression must not produce a temporary so it can `&'static`.
354         let discriminant: &'static u8 = &$discriminant;
355         $crate::util::Serialize::serialize(discriminant, $serializer)?;
356         $crate::util::Serialize::serialize($data, $serializer)
357     }};
358     (@deserialize_variant_arm $bytes:ident, $name:ident :: $variant:ident,) => {
359         $name::$variant
360     };
361     (@deserialize_variant_arm $bytes:ident, $name:ident :: $variant:ident, $inner:tt) => {
362         $name::$variant($crate::util::DeserializePrefix::deserialize_prefix($bytes)?)
363     };
364     (@variant_max_serialized_size) => {0};
365     (@variant_max_serialized_size $inner:tt) => {
366         <$inner as $crate::util::DeserializePrefix>::MAX_SERIALIZED_SIZE
367     };
368     ($(
369         $(#[$attr:meta])*
370         pub enum $name:ident {
371         $(
372             $(#[$variant_attr:meta])*
373             $variant:ident $(($data:tt))? = $discriminant:expr
374         ),* $(,)?
375         }
376     )*) => {$(
377         $(#[$attr])*
378         #[repr(u8)]
379         pub enum $name {$(
380             $(#[$variant_attr])*
381             $variant $(($data))? = $discriminant,
382         )*}
383         impl<'s> $crate::util::Serialize<'s> for $name {
384             fn serialize<'a: 's, S: $crate::util::Serializer<'s>>(
385                 &'a self,
386                 serializer: &mut S,
387             ) -> Result<S::Ok, S::Error> {
388                 match self {$(
389                     $crate::util::serde_enums!(
390                         @match_variant_pat
391                         data, $name :: $variant,
392                         $($data)?
393                     ) => $crate::util::serde_enums!(
394                         @serialize_variant_arm
395                         data, $discriminant, serializer,
396                         $($data)?
397                     ),
398                 )*}
399             }
400         }
401 
402         impl $crate::util::DeserializePrefix for $name {
403             const MAX_SERIALIZED_SIZE: usize = size_of::<u8>() +
404                 $crate::util::max_usize(&[$(
405                     $crate::util::serde_enums!(
406                         @variant_max_serialized_size
407                         $($data)?
408                     ),
409                 )*]);
410 
411             fn deserialize_prefix(bytes: &mut &[u8]) -> Result<Self, $crate::util::DeserializeError> {
412                 let &[discriminant, ref variant_data @ ..] = *bytes else {
413                     return Err($crate::util::DeserializeError::NotEnoughBuffer);
414                 };
415                 *bytes = variant_data;
416                 Ok(match discriminant {
417                     $(
418                         $discriminant => $crate::util::serde_enums!(
419                             @deserialize_variant_arm
420                             bytes, $name :: $variant,
421                             $($data)?
422                         ),
423                     )*
424                     // TODO: kupiakos@ - log this error
425                     _ => return Err($crate::util::DeserializeError::InvalidValue),
426                 })
427             }
428         }
429     )*};
430 }
431 
432 /// Implements `Serialize`/`DeserializePrefix` for all of the fields in the given wire order.
433 macro_rules! serde_fields {
434     ($($name:ident {$($field:ident),* $(,)?}),* $(,)?) => {$(
435         impl $crate::util::DeserializePrefix for $name {
436             const MAX_SERIALIZED_SIZE: usize = $crate::util::sum_usize(&[$(
437                 $crate::util::field_max_serialized_size(&|x: &Self| &x.$field),
438             )*]);
439             fn deserialize_prefix(bytes: &mut &[u8]) -> Result<Self, $crate::util::DeserializeError> {
440                 $(
441                     let $field = $crate::util::DeserializePrefix::deserialize_prefix(bytes)?;
442                 )*
443                 Ok(Self {
444                     $($field),*
445                 })
446             }
447         }
448 
449         impl<'s> $crate::util::Serialize<'s> for $name {
450             fn serialize<'a: 's, S: $crate::util::Serializer<'s>>(
451                 &'a self,
452                 serializer: &mut S,
453             ) -> Result<S::Ok, S::Error> {
454                 // Check there are no missing fields.
455                 let $name { $($field),* } = self;
456                 $(
457                     let _ok = $crate::util::Serialize::serialize($field, serializer)?;
458                 )*
459                 Ok(_ok)
460             }
461         }
462     )*};
463 }
464 
465 /// Uses `zerocopy` to serialize/deserialize all fields at once in order.
466 ///
467 /// Note that this is sensitive to changes in field layout.
468 macro_rules! serde_zerocopy {
469     ($($t:ty),* $(,)?) => {
470         $(
471             impl $crate::util::DeserializePrefix for $t {
472                 const MAX_SERIALIZED_SIZE: usize = size_of::<Self>();
473                 fn deserialize_prefix(
474                     bytes: &mut &[u8]
475                 ) -> Result<Self, $crate::util::DeserializeError> {
476                     let Ok((head, tail)) = <$t as zerocopy::FromBytes>::read_from_prefix(*bytes)
477                     else {
478                         return Err($crate::util::DeserializeError::NotEnoughBuffer);
479                     };
480                     *bytes = tail;
481                     Ok(head)
482                 }
483             }
484 
485             impl<'s> $crate::util::Serialize<'s> for $t {
486                 fn serialize<'a: 's, S: $crate::util::Serializer<'s>>(
487                     &'a self,
488                     serializer: &mut S,
489                 ) -> Result<S::Ok, S::Error> {
490                     serializer.serialize_bytes(self.as_bytes())
491                 }
492             }
493         )*
494     };
495 }
496 
497 serde_zerocopy!(u8, i8, u16, i16, u32, i32, u64, i64);
498 
499 pub(crate) use {serde_enums, serde_fields, serde_zerocopy};
500