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