• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2021 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 use alloc::rc::{Rc, Weak};
18 use core::fmt;
19 use core::mem::{ManuallyDrop, MaybeUninit};
20 use core::num::ParseIntError;
21 use log::{debug, error, warn};
22 use trusty_std::alloc::{AllocError, Vec};
23 use trusty_std::ffi::{CString, FallibleCString};
24 use trusty_std::TryClone;
25 use trusty_sys::c_void;
26 
27 use crate::handle::MAX_MSG_HANDLES;
28 use crate::sys;
29 use crate::{ConnectResult, Deserialize, Handle, MessageResult, Result, TipcError};
30 use handle_set::HandleSet;
31 
32 mod handle_set;
33 
34 /// A description of a server-side IPC port.
35 ///
36 /// A port configuration specifies the service port and various parameters for
37 /// the service. This configuration struct is a builder to set these parameters.
38 ///
39 /// # Examples
40 ///
41 /// ```
42 /// # impl Service for () {
43 /// #     type Connection = ();
44 /// #     type Message = ();
45 ///
46 /// #     fn on_connect(
47 /// #         &self,
48 /// #         _port: &PortCfg,
49 /// #         _handle: &Handle,
50 /// #         _peer: &Uuid,
51 /// #     ) -> Result<ConnectResult<Self::Connection>> {
52 /// #         Ok(ConnectResult::Accept(()))
53 /// #     }
54 /// #
55 /// #     fn on_message(
56 /// #         &self,
57 /// #         _connection: &Self::Connection,
58 /// #         _handle: &Handle,
59 /// #         _msg: Self::Message,
60 /// #     ) -> Result<MessageResult> {
61 /// #         Ok(MessageResult::MaintainConnection)
62 /// #     }
63 /// # }
64 ///
65 /// let cfg = PortCfg::new("com.android.trusty.rust_port_test")
66 ///     .msg_queue_len(4)
67 ///     .msg_max_size(4096)
68 ///     .allow_ta_connect();
69 ///
70 /// let service = ();
71 /// let buffer = [0u8; 4096];
72 /// let manager = Manager::new(service, cfg, buffer);
73 /// ```
74 #[derive(Debug, Eq, PartialEq)]
75 pub struct PortCfg {
76     path: CString,
77     msg_queue_len: u32,
78     msg_max_size: u32,
79     flags: u32,
80     uuid_allow_list: Option<&'static [Uuid]>,
81 }
82 
83 impl PortCfg {
84     /// Construct a new port configuration for the given path
new<T: AsRef<str>>(path: T) -> Result<Self>85     pub fn new<T: AsRef<str>>(path: T) -> Result<Self> {
86         Ok(Self {
87             path: CString::try_new(path.as_ref())?,
88             msg_queue_len: 1,
89             msg_max_size: 4096,
90             flags: 0,
91             uuid_allow_list: None,
92         })
93     }
94 
95     /// Construct a new port configuration for the given path
96     ///
97     /// This version takes ownership of the path and does not allocate.
new_raw(path: CString) -> Self98     pub fn new_raw(path: CString) -> Self {
99         Self { path, msg_queue_len: 1, msg_max_size: 4096, flags: 0, uuid_allow_list: None }
100     }
101 
102     /// Set the message queue length for this port configuration
msg_queue_len(self, msg_queue_len: u32) -> Self103     pub fn msg_queue_len(self, msg_queue_len: u32) -> Self {
104         Self { msg_queue_len, ..self }
105     }
106 
107     /// Set the message maximum length for this port configuration
msg_max_size(self, msg_max_size: u32) -> Self108     pub fn msg_max_size(self, msg_max_size: u32) -> Self {
109         Self { msg_max_size, ..self }
110     }
111 
112     /// Allow connections from non-secure (Android) clients for this port
113     /// configuration
allow_ns_connect(self) -> Self114     pub fn allow_ns_connect(self) -> Self {
115         Self { flags: self.flags | sys::IPC_PORT_ALLOW_NS_CONNECT as u32, ..self }
116     }
117 
118     /// Allow connections from secure (Trusty) client for this port
119     /// configuration
allow_ta_connect(self) -> Self120     pub fn allow_ta_connect(self) -> Self {
121         Self { flags: self.flags | sys::IPC_PORT_ALLOW_TA_CONNECT as u32, ..self }
122     }
123 
124     /// Filter allowable UUID connections. Leaving this unset will allow connection from any peer
125     /// UUID. Services should handle any additional filtering they need.
allowed_uuids(self, uuids: &'static [Uuid]) -> Self126     pub fn allowed_uuids(self, uuids: &'static [Uuid]) -> Self {
127         Self { uuid_allow_list: Some(uuids), ..self }
128     }
129 
130     /// Get path
get_path(&self) -> &CString131     pub fn get_path(&self) -> &CString {
132         &self.path
133     }
134 
135     /// Get message max size
get_msg_max_size(&self) -> u32136     pub fn get_msg_max_size(&self) -> u32 {
137         self.msg_max_size
138     }
139 
140     /// Get message queue length
get_msg_queue_len(&self) -> u32141     pub fn get_msg_queue_len(&self) -> u32 {
142         self.msg_queue_len
143     }
144 
145     /// Get flags
get_flags(&self) -> u32146     pub fn get_flags(&self) -> u32 {
147         self.flags
148     }
149 
150     /// Get allowed UUIDs
get_uuid_allow_list(&self) -> Option<&'static [Uuid]>151     pub fn get_uuid_allow_list(&self) -> Option<&'static [Uuid]> {
152         self.uuid_allow_list
153     }
154 }
155 
156 impl TryClone for PortCfg {
157     type Error = AllocError;
158 
try_clone(&self) -> core::result::Result<Self, Self::Error>159     fn try_clone(&self) -> core::result::Result<Self, Self::Error> {
160         Ok(Self { path: self.path.try_clone()?, ..*self })
161     }
162 }
163 
164 pub(crate) struct Channel<D: Dispatcher> {
165     handle: Handle,
166     ty: ChannelTy<D>,
167 }
168 
169 impl<D: Dispatcher> PartialEq for Channel<D> {
eq(&self, other: &Self) -> bool170     fn eq(&self, other: &Self) -> bool {
171         self.handle == other.handle
172     }
173 }
174 
175 impl<D: Dispatcher> Eq for Channel<D> {}
176 
177 impl<D: Dispatcher> fmt::Debug for Channel<D> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result178     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
179         writeln!(f, "Channel {{")?;
180         writeln!(f, "  handle: {:?},", self.handle)?;
181         writeln!(f, "  ty: {:?},", self.ty)?;
182         write!(f, "}}")
183     }
184 }
185 
186 enum ChannelTy<D: Dispatcher> {
187     /// Service port with a configuration describing the port
188     Port(PortCfg),
189 
190     /// Client connection
191     Connection(D::Connection),
192 }
193 
194 impl<D: Dispatcher> fmt::Debug for ChannelTy<D> {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result195     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
196         match self {
197             ChannelTy::Port(cfg) => write!(f, "ChannelTy::Port({:?})", cfg),
198             ChannelTy::Connection(_) => write!(f, "ChannelTy::Connection"),
199         }
200     }
201 }
202 
203 impl<D: Dispatcher> Channel<D> {
handle(&self) -> &Handle204     pub fn handle(&self) -> &Handle {
205         &self.handle
206     }
207 
is_port(&self) -> bool208     pub fn is_port(&self) -> bool {
209         match self.ty {
210             ChannelTy::Port(..) => true,
211             _ => false,
212         }
213     }
214 
is_connection(&self) -> bool215     pub fn is_connection(&self) -> bool {
216         match self.ty {
217             ChannelTy::Connection(..) => true,
218             _ => false,
219         }
220     }
221 
222     /// Reconstruct a reference to this type from an opaque pointer.
223     ///
224     /// SAFETY: The opaque pointer must have been constructed using
225     /// Weak::into_raw, which happens in HandleSet::do_set_ctrl to create a
226     /// connection cookie.
from_opaque_ptr<'a>(ptr: *const c_void) -> Option<Rc<Self>>227     unsafe fn from_opaque_ptr<'a>(ptr: *const c_void) -> Option<Rc<Self>> {
228         if ptr.is_null() {
229             None
230         } else {
231             // We must not drop the weak pointer here, because we are not
232             // actually taking ownership of it.
233             let weak = ManuallyDrop::new(Weak::from_raw(ptr.cast()));
234             weak.upgrade()
235         }
236     }
237 
try_new_port(cfg: &PortCfg) -> Result<Rc<Self>>238     pub(crate) fn try_new_port(cfg: &PortCfg) -> Result<Rc<Self>> {
239         // SAFETY: syscall, config path is borrowed and outlives the call.
240         // Return value is either a negative error code or a valid handle.
241         let rc = unsafe {
242             trusty_sys::port_create(
243                 cfg.path.as_ptr(),
244                 cfg.msg_queue_len,
245                 cfg.msg_max_size,
246                 cfg.flags,
247             )
248         };
249         if rc < 0 {
250             Err(TipcError::from_uapi(rc))
251         } else {
252             Ok(Rc::try_new(Self {
253                 handle: Handle::from_raw(rc as i32)?,
254                 ty: ChannelTy::Port(cfg.try_clone()?),
255             })?)
256         }
257     }
258 
try_new_connection(handle: Handle, data: D::Connection) -> Result<Rc<Self>>259     fn try_new_connection(handle: Handle, data: D::Connection) -> Result<Rc<Self>> {
260         Ok(Rc::try_new(Self { handle, ty: ChannelTy::Connection(data) })?)
261     }
262 }
263 
264 /// Trusty APP UUID
265 #[derive(Clone, Eq, PartialEq)]
266 pub struct Uuid(trusty_sys::uuid);
267 
268 impl Uuid {
269     pub const UUID_BYTE_LEN: usize = std::mem::size_of::<trusty_sys::uuid>();
270     // UUID_STR_SIZE is a u32, conversion to usize is correct on our targeted architectures
271     // Subtracting 1 from UUID_STR_SIZE because we don't need the null terminator on the RUST
272     // implementation.
273     const UUID_STR_LEN: usize = (sys::UUID_STR_SIZE as usize) - 1;
274     const HYPHEN_SKIP_POS: [usize; 4] = [8, 4, 4, 4];
275     const CLOCK_SEQ_AND_NODE_NUM_BYTES: usize = 8;
276 
new( time_low: u32, time_mid: u16, time_hi_and_version: u16, clock_seq_and_node: [u8; 8], ) -> Self277     pub const fn new(
278         time_low: u32,
279         time_mid: u16,
280         time_hi_and_version: u16,
281         clock_seq_and_node: [u8; 8],
282     ) -> Self {
283         Uuid(trusty_sys::uuid { time_low, time_mid, time_hi_and_version, clock_seq_and_node })
284     }
285 
from_bytes(bytes: &[u8; Self::UUID_BYTE_LEN]) -> Self286     pub fn from_bytes(bytes: &[u8; Self::UUID_BYTE_LEN]) -> Self {
287         // SAFETY: `bytes` has the exact same size size as `trusty_sys::uuid`, so this transmute
288         //         copy is safe.
289         let uuid = unsafe { std::mem::transmute_copy(bytes) };
290         Uuid(uuid)
291     }
292 
try_from_bytes(bytes: &[u8]) -> Result<Self>293     pub fn try_from_bytes(bytes: &[u8]) -> Result<Self> {
294         let bytes: &[u8; Self::UUID_BYTE_LEN] = bytes.try_into().or(Err(TipcError::OutOfBounds))?;
295         Ok(Self::from_bytes(bytes))
296     }
297 
as_ptr(&self) -> *const trusty_sys::uuid298     pub unsafe fn as_ptr(&self) -> *const trusty_sys::uuid {
299         &self.0
300     }
301 
as_mut_ptr(&mut self) -> *mut trusty_sys::uuid302     pub unsafe fn as_mut_ptr(&mut self) -> *mut trusty_sys::uuid {
303         &mut self.0
304     }
305 
new_from_string(uuid_str: &str) -> Result<Self>306     pub fn new_from_string(uuid_str: &str) -> Result<Self> {
307         // Helper function that first tries to convert the `uuid_element` bytes into a string and
308         // then uses the provided `conversion_fn` to try to convert it into an integer, interpreting
309         // the string as a hex number
310         fn convert_uuid_element<T>(
311             uuid_element: Option<&str>,
312             conversion_fn: fn(&str, u32) -> core::result::Result<T, ParseIntError>,
313         ) -> Result<T> {
314             let uuid_element = uuid_element.ok_or(TipcError::InvalidData)?;
315             conversion_fn(uuid_element, 16).map_err(|_| TipcError::InvalidData)
316         }
317         // Splitting a string into chunks using only std Rust facilities is not stable yet, so
318         // providing a function for `Uuid` usage until it is stabilized.
319         fn split_convert_string_byte_chunks(
320             string_to_split: &str,
321             result_buffer: &mut [u8],
322         ) -> Result<()> {
323             // Because our input is in hexadecimal format, to get a byte we need a string of size 2.
324             let chunk_size = 2;
325             if (string_to_split.len() % chunk_size) != 0 {
326                 return Err(TipcError::InvalidData);
327             }
328             let mut chunk;
329             let mut remainder = string_to_split;
330             for i in 0..(string_to_split.len() / chunk_size) {
331                 (chunk, remainder) = remainder.split_at(chunk_size);
332                 let converted_byte = convert_uuid_element(Some(chunk), u8::from_str_radix)?;
333                 result_buffer[i] = converted_byte;
334             }
335             Ok(())
336         }
337         // checking first that provided string is ASCII, so we can later split clock_seq_and_node in
338         // byte chunks.
339         if !uuid_str.is_ascii() {
340             return Err(TipcError::InvalidData);
341         }
342         // Check that string has the correct length
343         if uuid_str.len() != Self::UUID_STR_LEN {
344             return Err(TipcError::InvalidData);
345         }
346         // Check that hyphens are in the correct positions.
347         let mut uuid_chr_itr = uuid_str.chars();
348         for skip_pos in Self::HYPHEN_SKIP_POS {
349             if uuid_chr_itr.nth(skip_pos) != Some('-') {
350                 return Err(TipcError::InvalidData);
351             }
352         }
353         // Splitting by the hyphens and checking that we do not end up with more elements than
354         // expected. This checks that we didn't have some unexpected hyphens in the middle of the
355         // string. This, along with the previous 2 checks should also check that all the elements
356         // have the correct number of digits.
357         let uuid_elements = uuid_str.split(|c| c == '-');
358         if uuid_elements.count() != 5 {
359             return Err(TipcError::InvalidData);
360         }
361         // separating uuid at the '-' now that we know that the string is of the correct length and
362         // has the expected number of hyphens.
363         let mut uuid_elements = uuid_str.split(|c| c == '-');
364         let time_low = convert_uuid_element(uuid_elements.next(), u32::from_str_radix)?;
365         let time_mid = convert_uuid_element(uuid_elements.next(), u16::from_str_radix)?;
366         let time_hi_and_version = convert_uuid_element(uuid_elements.next(), u16::from_str_radix)?;
367         // The last 8 bytes are split in 2 elements. RFC 4122 states that it is stored in Big Endian
368         // format, so we are just going to concatenate the individual byte chunks of the 2 elements.
369         let mut clock_seq_and_node = [0u8; Self::CLOCK_SEQ_AND_NODE_NUM_BYTES];
370         let clock_seq = uuid_elements.next().ok_or(TipcError::InvalidData)?;
371         // clock_seq contains the first 2 bytes
372         split_convert_string_byte_chunks(clock_seq, &mut clock_seq_and_node[..2])?;
373         let node = uuid_elements.next().ok_or(TipcError::InvalidData)?;
374         // node contains the remaining 6 bytes
375         split_convert_string_byte_chunks(node, &mut clock_seq_and_node[2..])?;
376         Ok(Self::new(time_low, time_mid, time_hi_and_version, clock_seq_and_node))
377     }
378 }
379 
380 impl fmt::Debug for Uuid {
fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result381     fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
382         write!(
383             f,
384             "{:08x}-{:04x}-{:04x}-",
385             self.0.time_low, self.0.time_mid, self.0.time_hi_and_version
386         )?;
387         for (idx, b) in self.0.clock_seq_and_node.iter().enumerate() {
388             write!(f, "{:02x}", b)?;
389             if idx == 1 {
390                 write!(f, "-")?;
391             }
392         }
393         Ok(())
394     }
395 }
396 
397 impl From<trusty_sys::uuid> for Uuid {
from(uuid: trusty_sys::uuid) -> Self398     fn from(uuid: trusty_sys::uuid) -> Self {
399         Self(uuid)
400     }
401 }
402 
403 impl alloc::string::ToString for Uuid {
to_string(&self) -> String404     fn to_string(&self) -> String {
405         format!("{:?}", self)
406     }
407 }
408 
409 /// A service which handles IPC messages for a collection of ports.
410 ///
411 /// A service which implements this interface can register itself, along with a
412 /// set of ports it handles, with a [`Manager`] which then dispatches
413 /// connection and message events to this service.
414 pub trait Service {
415     /// Generic type to association with a connection. `on_connect()` should
416     /// create this type for a successful connection.
417     type Connection;
418 
419     /// Type of message this service can receive.
420     type Message: Deserialize;
421 
422     /// Called when a client connects
423     ///
424     /// Returns either `Ok(Accept(Connection))` if the connection should be
425     /// accepted or `Ok(CloseConnection)` if the connection should be closed.
on_connect( &self, port: &PortCfg, handle: &Handle, peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>426     fn on_connect(
427         &self,
428         port: &PortCfg,
429         handle: &Handle,
430         peer: &Uuid,
431     ) -> Result<ConnectResult<Self::Connection>>;
432 
433     /// Called when the service receives a message.
434     ///
435     /// The service manager handles deserializing the message, which is then
436     /// passed to this callback.
437     ///
438     /// Should return `Ok(MaintainConnection)` if the connection should be kept open. The
439     /// connection will be closed if `Ok(CloseConnection)` or `Err(_)` is returned.
on_message( &self, connection: &Self::Connection, handle: &Handle, msg: Self::Message, ) -> Result<MessageResult>440     fn on_message(
441         &self,
442         connection: &Self::Connection,
443         handle: &Handle,
444         msg: Self::Message,
445     ) -> Result<MessageResult>;
446 
447     /// Called when the client closes a connection.
on_disconnect(&self, _connection: &Self::Connection)448     fn on_disconnect(&self, _connection: &Self::Connection) {}
449 }
450 
451 pub trait UnbufferedService {
452     /// Generic type to association with a connection. `on_connect()` should
453     /// create this type for a successful connection.
454     type Connection;
455 
456     /// Called when a client connects
457     ///
458     /// Returns either `Ok(Accept(Connection))` if the connection should be
459     /// accepted or `Ok(CloseConnection)` if the connection should be closed.
on_connect( &self, port: &PortCfg, handle: &Handle, peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>460     fn on_connect(
461         &self,
462         port: &PortCfg,
463         handle: &Handle,
464         peer: &Uuid,
465     ) -> Result<ConnectResult<Self::Connection>>;
466 
467     /// Called when the service receives a message.
468     ///
469     /// The service is responsible for deserializing the message.
470     /// A default implementation is provided that panics, for reasons of backwards
471     /// compatibility with existing code. Any unbuffered service should implement this
472     /// method and also provide a simple implementation for `on_message` that e.g. logs
473     /// or panics.
474     ///
475     /// Should return `Ok(MaintainConnection)` if the connection should be kept open. The
476     /// connection will be closed if `Ok(CloseConnection)` or `Err(_)` is returned.
on_message( &self, connection: &Self::Connection, handle: &Handle, buffer: &mut [u8], ) -> Result<MessageResult>477     fn on_message(
478         &self,
479         connection: &Self::Connection,
480         handle: &Handle,
481         buffer: &mut [u8],
482     ) -> Result<MessageResult>;
483 
484     /// Called when the client closes a connection.
on_disconnect(&self, _connection: &Self::Connection)485     fn on_disconnect(&self, _connection: &Self::Connection) {}
486 
487     /// Get the maximum possible length of any message handled by this service
max_message_length(&self) -> usize488     fn max_message_length(&self) -> usize {
489         0
490     }
491 }
492 
493 impl<T, U: Deserialize, V: Service<Connection = T, Message = U>> UnbufferedService for V {
494     type Connection = <Self as Service>::Connection;
495 
on_connect( &self, port: &PortCfg, handle: &Handle, peer: &Uuid, ) -> Result<ConnectResult<<Self as UnbufferedService>::Connection>>496     fn on_connect(
497         &self,
498         port: &PortCfg,
499         handle: &Handle,
500         peer: &Uuid,
501     ) -> Result<ConnectResult<<Self as UnbufferedService>::Connection>> {
502         <Self as Service>::on_connect(self, port, handle, peer)
503     }
504 
on_message( &self, connection: &<Self as UnbufferedService>::Connection, handle: &Handle, buffer: &mut [u8], ) -> Result<MessageResult>505     fn on_message(
506         &self,
507         connection: &<Self as UnbufferedService>::Connection,
508         handle: &Handle,
509         buffer: &mut [u8],
510     ) -> Result<MessageResult> {
511         let mut handles: [Option<Handle>; MAX_MSG_HANDLES] = Default::default();
512         let (byte_count, handle_count) = handle.recv_vectored(&mut [buffer], &mut handles)?;
513         let msg = <Self as Service>::Message::deserialize(
514             &buffer[..byte_count],
515             &mut handles[..handle_count],
516         )
517         .map_err(|e| {
518             error!("Could not parse message: {:?}", e);
519             TipcError::InvalidData
520         })?;
521         <Self as Service>::on_message(self, connection, handle, msg)
522     }
523 
on_disconnect(&self, connection: &<Self as UnbufferedService>::Connection)524     fn on_disconnect(&self, connection: &<Self as UnbufferedService>::Connection) {
525         <Self as Service>::on_disconnect(self, connection)
526     }
527 
max_message_length(&self) -> usize528     fn max_message_length(&self) -> usize {
529         <Self as Service>::Message::MAX_SERIALIZED_SIZE
530     }
531 }
532 
533 /// Wrap a service in a newtype.
534 ///
535 /// This macro wraps an existing service in a newtype
536 /// that forwards the service trait implementation
537 /// (either [`Service`] or [`UnbufferedService`]) to
538 /// the wrapped service. This is useful when passing the
539 /// same service multiple times to the [`service_dispatcher!`]
540 /// macro, which requires that all the service types are distinct.
541 /// The wrapper(s) can be used to serve multiple ports using
542 /// the same service implementation.
543 ///
544 /// [`service_dispatcher!`]: crate::service_dispatcher
545 ///
546 /// # Examples
547 ///
548 /// ```
549 /// // Create a new Service2 type that wraps Service1
550 /// wrap_service!(Service2(Service1: Service));
551 /// service_dispatcher! {
552 ///     enum ServiceDispatcher {
553 ///         Service1,
554 ///         Service2,
555 ///     }
556 /// }
557 /// ```
558 #[macro_export]
559 macro_rules! wrap_service {
560     ($vis:vis $wrapper:ident ($inner:ty: Service)) => {
561         $crate::wrap_service!(@common $vis $wrapper $inner);
562         $crate::wrap_service!(@buffered $wrapper $inner);
563     };
564 
565     ($vis:vis $wrapper:ident ($inner:ty: UnbufferedService)) => {
566         $crate::wrap_service!(@common $vis $wrapper $inner);
567         $crate::wrap_service!(@unbuffered $wrapper $inner);
568     };
569 
570     (@common $vis:vis $wrapper:ident $inner:ty) => {
571         $vis struct $wrapper($inner);
572 
573         #[allow(dead_code)] // These might not be used by anything
574         impl $wrapper {
575             $vis fn new(inner: $inner) -> Self { Self(inner) }
576             $vis fn inner(&self) -> &$inner { &self.0 }
577             $vis fn inner_mut(&mut self) -> &mut $inner { &mut self.0 }
578         }
579     };
580 
581     (@buffered $wrapper:ident $inner:ty) => {
582         impl $crate::Service for $wrapper {
583             type Connection = <$inner as $crate::Service>::Connection;
584             type Message = <$inner as $crate::Service>::Message;
585 
586             fn on_connect(
587                 &self,
588                 port: &$crate::PortCfg,
589                 handle: &$crate::Handle,
590                 peer: &$crate::Uuid,
591             ) -> $crate::Result<$crate::ConnectResult<Self::Connection>> {
592                 <$inner as $crate::Service>::on_connect(&self.0, port, handle, peer)
593             }
594 
595             fn on_message(
596                 &self,
597                 connection: &Self::Connection,
598                 handle: &$crate::Handle,
599                 msg: Self::Message,
600             ) -> $crate::Result<$crate::MessageResult> {
601                 <$inner as $crate::Service>::on_message(&self.0, connection, handle, msg)
602             }
603 
604             fn on_disconnect(&self, connection: &Self::Connection) {
605                 <$inner as $crate::Service>::on_disconnect(&self.0, connection)
606             }
607         }
608     };
609 
610     (@unbuffered $wrapper:ident $inner:ty) => {
611         impl $crate::UnbufferedService for $wrapper {
612             type Connection = <$inner as $crate::UnbufferedService>::Connection;
613 
614             fn on_connect(
615                 &self,
616                 port: &$crate::PortCfg,
617                 handle: &$crate::Handle,
618                 peer: &$crate::Uuid,
619             ) -> $crate::Result<$crate::ConnectResult<Self::Connection>> {
620                 <$inner as $crate::UnbufferedService>::on_connect(&self.0, port, handle, peer)
621             }
622 
623             fn on_message(
624                 &self,
625                 connection: &Self::Connection,
626                 handle: &$crate::Handle,
627                 buffer: &mut [u8],
628             ) -> $crate::Result<$crate::MessageResult> {
629                 <$inner as $crate::UnbufferedService>::on_message(&self.0, connection, handle, buffer)
630             }
631 
632             fn on_disconnect(&self, connection: &Self::Connection) {
633                 <$inner as $crate::UnbufferedService>::on_disconnect(&self.0, connection)
634             }
635 
636             fn max_message_length(&self) -> usize {
637                 <$inner as $crate::UnbufferedService>::max_message_length(&self.0)
638             }
639         }
640     };
641 }
642 
643 pub trait Dispatcher {
644     /// Generic type to association with a connection. `on_connect()` should
645     /// create this type for a successful connection.
646     type Connection;
647 
648     /// Called when a client connects
649     ///
650     /// Returns either `Ok(Accept(Connection))` if the connection should be
651     /// accepted or `Ok(CloseConnection)` if the connection should be closed.
on_connect( &self, port: &PortCfg, handle: &Handle, peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>652     fn on_connect(
653         &self,
654         port: &PortCfg,
655         handle: &Handle,
656         peer: &Uuid,
657     ) -> Result<ConnectResult<Self::Connection>>;
658 
659     /// Called when the service receives a message.
660     ///
661     /// The service manager handles deserializing the message, which is then
662     /// passed to this callback.
663     ///
664     /// Should return `Ok(MaintainConnection)` if the connection should be kept open. The
665     /// connection will be closed if `Ok(CloseConnection)` or `Err(_)` is returned.
on_message( &self, connection: &Self::Connection, handle: &Handle, buffer: &mut [u8], ) -> Result<MessageResult>666     fn on_message(
667         &self,
668         connection: &Self::Connection,
669         handle: &Handle,
670         buffer: &mut [u8],
671     ) -> Result<MessageResult>;
672 
673     /// Called when the client closes a connection.
on_disconnect(&self, _connection: &Self::Connection)674     fn on_disconnect(&self, _connection: &Self::Connection) {}
675 
676     /// Get the list of ports this dispatcher handles.
port_configurations(&self) -> &[PortCfg]677     fn port_configurations(&self) -> &[PortCfg];
678 
679     /// Get the maximum possible length of any message handled by this
680     /// dispatcher.
max_message_length(&self) -> usize681     fn max_message_length(&self) -> usize;
682 }
683 
684 // Implementation of a static dispatcher for services with only a single message
685 // type.
686 pub struct SingleDispatcher<S: Service> {
687     service: S,
688     ports: [PortCfg; 1],
689 }
690 
691 impl<S: Service> SingleDispatcher<S> {
new(service: S, port: PortCfg) -> Self692     fn new(service: S, port: PortCfg) -> Self {
693         Self { service, ports: [port] }
694     }
695 }
696 
697 impl<S: Service> Dispatcher for SingleDispatcher<S> {
698     type Connection = S::Connection;
699 
on_connect( &self, port: &PortCfg, handle: &Handle, peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>700     fn on_connect(
701         &self,
702         port: &PortCfg,
703         handle: &Handle,
704         peer: &Uuid,
705     ) -> Result<ConnectResult<Self::Connection>> {
706         self.service.on_connect(port, handle, peer)
707     }
708 
on_message( &self, connection: &Self::Connection, handle: &Handle, buffer: &mut [u8], ) -> Result<MessageResult>709     fn on_message(
710         &self,
711         connection: &Self::Connection,
712         handle: &Handle,
713         buffer: &mut [u8],
714     ) -> Result<MessageResult> {
715         let mut handles: [Option<Handle>; MAX_MSG_HANDLES] = Default::default();
716         let (byte_count, handle_count) = handle.recv_vectored(&mut [buffer], &mut handles)?;
717         let msg = S::Message::deserialize(&buffer[..byte_count], &mut handles[..handle_count])
718             .map_err(|e| {
719                 error!("Could not parse message: {:?}", e);
720                 TipcError::InvalidData
721             })?;
722         self.service.on_message(connection, handle, msg)
723     }
724 
on_disconnect(&self, connection: &Self::Connection)725     fn on_disconnect(&self, connection: &Self::Connection) {
726         self.service.on_disconnect(connection)
727     }
728 
max_message_length(&self) -> usize729     fn max_message_length(&self) -> usize {
730         S::Message::MAX_SERIALIZED_SIZE
731     }
732 
port_configurations(&self) -> &[PortCfg]733     fn port_configurations(&self) -> &[PortCfg] {
734         &self.ports
735     }
736 }
737 
738 // Implementation of a static dispatcher for unbuffered services.
739 pub struct SingleUnbufferedDispatcher<S: UnbufferedService> {
740     service: S,
741     ports: [PortCfg; 1],
742 }
743 
744 impl<S: UnbufferedService> SingleUnbufferedDispatcher<S> {
new(service: S, port: PortCfg) -> Self745     fn new(service: S, port: PortCfg) -> Self {
746         Self { service, ports: [port] }
747     }
748 }
749 
750 impl<S: UnbufferedService> Dispatcher for SingleUnbufferedDispatcher<S> {
751     type Connection = S::Connection;
752 
on_connect( &self, port: &PortCfg, handle: &Handle, peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>753     fn on_connect(
754         &self,
755         port: &PortCfg,
756         handle: &Handle,
757         peer: &Uuid,
758     ) -> Result<ConnectResult<Self::Connection>> {
759         self.service.on_connect(port, handle, peer)
760     }
761 
on_message( &self, connection: &Self::Connection, handle: &Handle, buffer: &mut [u8], ) -> Result<MessageResult>762     fn on_message(
763         &self,
764         connection: &Self::Connection,
765         handle: &Handle,
766         buffer: &mut [u8],
767     ) -> Result<MessageResult> {
768         self.service.on_message(connection, handle, buffer)
769     }
770 
on_disconnect(&self, connection: &Self::Connection)771     fn on_disconnect(&self, connection: &Self::Connection) {
772         self.service.on_disconnect(connection)
773     }
774 
max_message_length(&self) -> usize775     fn max_message_length(&self) -> usize {
776         self.service.max_message_length()
777     }
778 
port_configurations(&self) -> &[PortCfg]779     fn port_configurations(&self) -> &[PortCfg] {
780         &self.ports
781     }
782 }
783 
784 /// Create a new service dispatcher that can handle a specified set of service
785 /// types.
786 ///
787 /// This macro creates a multi-service dispatcher that holds different types of
788 /// services that should share the same event loop and dispatches to the
789 /// relevant service based on the connection port. Services must implement the
790 /// [`Service`] trait. An instance of this dispatcher must have a single const
791 /// usize parameter specifying how many ports the dispatcher will handle.
792 /// This macro has limited lifetime support. A single lifetime can be
793 /// used for the ServiceDispatcher enum and the included services (see the
794 /// supported definition in the Examples section).
795 ///
796 /// # Examples
797 /// ```
798 /// service_dispatcher! {
799 ///     enum ServiceDispatcher {
800 ///         Service1,
801 ///         Service2,
802 ///     }
803 /// }
804 ///
805 /// // Create a new dispatcher that handles two ports
806 /// let dispatcher = ServiceDispatcher::<2>::new()
807 ///     .expect("Could not allocate service dispatcher");
808 ///
809 /// let cfg = PortCfg::new(&"com.android.trusty.test_port1).unwrap();
810 /// dispatcher.add_service(Rc::new(Service1), cfg).expect("Could not add service 1");
811 ///
812 /// let cfg = PortCfg::new(&"com.android.trusty.test_port2).unwrap();
813 /// dispatcher.add_service(Rc::new(Service2), cfg).expect("Could not add service 2");
814 /// ```
815 ///
816 /// ## defining a dispatcher with multiple lifetimes
817 /// ```
818 /// service_dispatcher! {
819 ///     enum ServiceDispatcher<'a> {
820 ///         Service1<'a>,
821 ///         Service2<'a>,
822 ///     }
823 /// }
824 /// ```
825 #[macro_export]
826 macro_rules! service_dispatcher {
827     ($vis:vis enum $name:ident $(<$elt: lifetime>)? {$($service:ident $(<$slt: lifetime>)? ),+ $(,)*}) => {
828         /// Dispatcher that routes incoming messages to the correct server based on what
829         /// port the message was sent to.
830         ///
831         /// This dispatcher adapts multiple different server types that expect different
832         /// message formats for the same [`Manager`]. By using this dispatcher,
833         /// different servers can be bound to different ports using the same event loop
834         /// in the manager.
835         $vis struct $name<$($elt,)? const PORT_COUNT: usize> {
836             ports: arrayvec::ArrayVec::<$crate::PortCfg, PORT_COUNT>,
837             services: arrayvec::ArrayVec::<ServiceKind$(<$elt>)?, PORT_COUNT>,
838         }
839 
840         impl<$($elt,)? const PORT_COUNT: usize> $name<$($elt,)? PORT_COUNT> {
841             pub fn new() -> $crate::Result<Self> {
842                 Ok(Self {
843                     ports: arrayvec::ArrayVec::<_, PORT_COUNT>::new(),
844                     services: arrayvec::ArrayVec::<_, PORT_COUNT>::new(),
845                 })
846             }
847 
848             pub fn add_service<T>(&mut self, service: alloc::rc::Rc<T>, port: $crate::PortCfg) -> $crate::Result<()>
849             where ServiceKind$(<$elt>)? : From<alloc::rc::Rc<T>> {
850                 if self.ports.is_full() || self.services.is_full() {
851                     return Err($crate::TipcError::OutOfBounds);
852                 }
853                 // SAFETY: We check the size above
854                 unsafe {
855                     self.ports.push_unchecked(port);
856                     self.services.push_unchecked(service.into());
857                 }
858                 Ok(())
859             }
860         }
861 
862         $vis enum ServiceKind$(<$elt>)? {
863             $($service(alloc::rc::Rc<$service$(<$slt>)?>)),+
864         }
865 
866         $(
867             impl$(<$slt>)? From<alloc::rc::Rc<$service$(<$slt>)?>> for ServiceKind$(<$slt>)? {
868                 fn from(service: alloc::rc::Rc<$service$(<$slt>)?>) -> Self {
869                     ServiceKind::$service(service)
870                 }
871             }
872         )+
873 
874         $vis enum ConnectionKind$(<$elt>)?  {
875             $($service(<$service$(<$slt>)? as $crate::UnbufferedService>::Connection)),+
876         }
877 
878         impl<$($elt,)? const PORT_COUNT: usize> $crate::Dispatcher for $name<$($elt,)? PORT_COUNT> {
879             type Connection = (usize, ConnectionKind$(<$elt>)?);
880 
881             fn on_connect(
882                 &self,
883                 port: &$crate::PortCfg,
884                 handle: &$crate::Handle,
885                 peer: &$crate::Uuid,
886             ) -> $crate::Result<$crate::ConnectResult<Self::Connection>> {
887                 let port_idx = self.ports.iter()
888                                          .position(|cfg| cfg == port)
889                                          .ok_or($crate::TipcError::InvalidPort)?;
890 
891                 match &self.services[port_idx] {
892                     $(ServiceKind::$service(s) => {
893                         $crate::UnbufferedService::on_connect(&**s, port, handle, peer)
894                             .map(|c| c.map(|c| (port_idx, ConnectionKind::$service(c))))
895                     })+
896                 }
897             }
898 
899             fn on_message(
900                 &self,
901                 connection: &Self::Connection,
902                 handle: &$crate::Handle,
903                 buffer: &mut [u8],
904             ) -> $crate::Result<$crate::MessageResult> {
905                 match &self.services[connection.0] {
906                     $(ServiceKind::$service(s) => {
907                         if let ConnectionKind::$service(conn) = &connection.1 {
908                             $crate::UnbufferedService::on_message(&**s, conn, handle, buffer)
909                         } else {
910                             Err($crate::TipcError::InvalidData)
911                         }
912                     })*
913                 }
914             }
915 
916             fn on_disconnect(&self, connection: &Self::Connection) {
917                 match &self.services[connection.0] {
918                     $(ServiceKind::$service(s) => {
919                         if let ConnectionKind::$service(conn) = &connection.1 {
920                             $crate::UnbufferedService::on_disconnect(&**s, conn)
921                         }
922                     })*
923                 }
924             }
925 
926             fn port_configurations(&self) -> &[$crate::PortCfg] {
927                 self.ports.as_slice()
928             }
929 
930             fn max_message_length(&self) -> usize {
931                 self.services.iter().map(|s| {
932                     match s {
933                         $(ServiceKind::$service(service) => {
934                             <$service as $crate::UnbufferedService>::max_message_length(&**service)
935                         })+
936                     }
937                 }).max().unwrap_or(0usize)
938             }
939         }
940     };
941 
942     (@make_none $service:ident) => { None };
943 }
944 
945 /// A manager that handles the IPC event loop and dispatches connections and
946 /// messages to a generic service.
947 pub struct Manager<
948     D: Dispatcher,
949     B: AsMut<[u8]> + AsRef<[u8]>,
950     const PORT_COUNT: usize,
951     const MAX_CONNECTION_COUNT: usize,
952 > {
953     dispatcher: D,
954     handle_set: HandleSet<D, PORT_COUNT, MAX_CONNECTION_COUNT>,
955     buffer: B,
956 }
957 
958 impl<
959         S: Service,
960         B: AsMut<[u8]> + AsRef<[u8]>,
961         const PORT_COUNT: usize,
962         const MAX_CONNECTION_COUNT: usize,
963     > Manager<SingleDispatcher<S>, B, PORT_COUNT, MAX_CONNECTION_COUNT>
964 {
965     /// Create a new service manager for the given service and port.
966     ///
967     /// The manager will receive data into the buffer `B`, so this buffer needs
968     /// to be at least as large as the largest message this service can handle.
969     ///
970     /// # Examples
971     ///
972     /// ```
973     /// struct MyService;
974     ///
975     /// impl Service for MyService {
976     ///     type Connection = ();
977     ///     type Message = ();
978     ///
979     ///     fn on_connect(
980     ///         &self,
981     ///         _port: &PortCfg,
982     ///         _handle: &Handle,
983     ///         _peer: &Uuid,
984     ///     ) -> Result<ConnectResult<Self::Connection>> {
985     ///         Ok(ConnectResult::Accept(()))
986     ///     }
987     ///
988     ///     fn on_message(
989     ///         &self,
990     ///         _connection: &Self::Connection,
991     ///         _handle: &Handle,
992     ///         _msg: Self::Message,
993     ///     ) -> Result<MessageResult> {
994     ///         Ok(MessageResult::MaintainConnection)
995     ///     }
996     /// }
997     ///
998     /// let service = MyService;
999     /// let cfg = PortCfg::new("com.android.trusty.rust_port_test");
1000     /// let buffer = [0u8; 4096];
1001     /// let mut manager = Manager::<_, _, 1, 1>::new(service, &[cfg], buffer);
1002     ///
1003     /// manager.run_event_loop()
1004     ///     .expect("Service manager encountered an error");
1005     /// ```
new(service: S, port_cfg: PortCfg, buffer: B) -> Result<Self>1006     pub fn new(service: S, port_cfg: PortCfg, buffer: B) -> Result<Self> {
1007         let dispatcher = SingleDispatcher::new(service, port_cfg);
1008         Self::new_with_dispatcher(dispatcher, buffer)
1009     }
1010 }
1011 
1012 impl<S: UnbufferedService, const PORT_COUNT: usize, const MAX_CONNECTION_COUNT: usize>
1013     Manager<SingleUnbufferedDispatcher<S>, [u8; 0], PORT_COUNT, MAX_CONNECTION_COUNT>
1014 {
1015     /// Create a new unbuffered service manager for the given service and port.
1016     ///
1017     /// The newly created manager will not have an internal buffer.
1018     /// The service is responsible for reading messages explicitly from the handler.
new_unbuffered(service: S, port_cfg: PortCfg) -> Result<Self>1019     pub fn new_unbuffered(service: S, port_cfg: PortCfg) -> Result<Self> {
1020         let dispatcher = SingleUnbufferedDispatcher::new(service, port_cfg);
1021         Self::new_with_dispatcher(dispatcher, [])
1022     }
1023 }
1024 
1025 impl<
1026         D: Dispatcher,
1027         B: AsMut<[u8]> + AsRef<[u8]>,
1028         const PORT_COUNT: usize,
1029         const MAX_CONNECTION_COUNT: usize,
1030     > Manager<D, B, PORT_COUNT, MAX_CONNECTION_COUNT>
1031 {
1032     /// Create a manager that can handle multiple services and ports
1033     ///
1034     /// A dispatcher handles mapping connections to services and parsing
1035     /// messages for the relevant service depending on which port the connection
1036     /// was made to. This allows multiple distinct services, each with their own
1037     /// message format and port to share the same event loop in the manager.
1038     ///
1039     /// See [`service_dispatcher!`] for details on how to create a dispatcher
1040     /// for use with this API.
1041     ///
1042     /// [`service_dispatcher!`]: crate::service_dispatcher
1043     ///
1044     /// # Examples
1045     /// ```
1046     /// service_dispatcher! {
1047     ///     enum ServiceDispatcher {
1048     ///         Service1,
1049     ///         Service2,
1050     ///     }
1051     /// }
1052     ///
1053     /// // Create a new dispatcher that handles two ports
1054     /// let dispatcher = ServiceDispatcher::<2>::new()
1055     ///     .expect("Could not allocate service dispatcher");
1056     ///
1057     /// let cfg = PortCfg::new(&"com.android.trusty.test_port1).unwrap();
1058     /// dispatcher.add_service(Rc::new(Service1), cfg).expect("Could not add service 1");
1059     ///
1060     /// let cfg = PortCfg::new(&"com.android.trusty.test_port2).unwrap();
1061     /// dispatcher.add_service(Rc::new(Service2), cfg).expect("Could not add service 2");
1062     ///
1063     /// Manager::<_, _, 2, 4>::new_with_dispatcher(dispatcher, [0u8; 4096])
1064     ///     .expect("Could not create service manager")
1065     ///     .run_event_loop()
1066     ///     .expect("Service manager exited unexpectedly");
1067     /// ```
new_with_dispatcher(dispatcher: D, buffer: B) -> Result<Self>1068     pub fn new_with_dispatcher(dispatcher: D, buffer: B) -> Result<Self> {
1069         if buffer.as_ref().len() < dispatcher.max_message_length() {
1070             return Err(TipcError::NotEnoughBuffer);
1071         }
1072 
1073         let ports: Vec<Rc<Channel<D>>> = dispatcher
1074             .port_configurations()
1075             .iter()
1076             .map(Channel::try_new_port)
1077             .collect::<Result<_>>()?;
1078         let ports: [Rc<Channel<D>>; PORT_COUNT] = ports
1079             .try_into()
1080             .expect("This is impossible. Array size must match expected PORT_COUNT");
1081         let handle_set = HandleSet::try_new(ports)?;
1082 
1083         Ok(Self { dispatcher, handle_set, buffer })
1084     }
1085 
1086     /// Run the service event loop.
1087     ///
1088     /// Only returns if an error occurs.
run_event_loop(mut self) -> Result<()>1089     pub fn run_event_loop(mut self) -> Result<()> {
1090         use trusty_sys::Error;
1091 
1092         loop {
1093             // Process the next incoming event, extracting any returned error for further
1094             // checking.
1095             let err = match self.event_loop_inner() {
1096                 Ok(()) => continue,
1097                 Err(err) => err,
1098             };
1099 
1100             // Check if the error is recoverable or not. If the error is not one of a
1101             // limited set of recoverable errors, we break from the event loop.
1102             match err {
1103                 // Recoverable errors that are always ignored.
1104                 | TipcError::SystemError(Error::TimedOut)
1105                 | TipcError::SystemError(Error::ChannelClosed)
1106 
1107                 // returned when peer UUID connection is not allowed.
1108                 | TipcError::SystemError(Error::NotAllowed)
1109 
1110                 // These are always caused by the client and so shouldn't be treated as an
1111                 // internal error or cause the event loop to exit.
1112                 | TipcError::ChannelClosed
1113                 => {
1114                     debug!("Recoverable error ignored: {:?}", err)
1115                 }
1116 
1117                 // These are legitimate errors and we should be handling them, but they would be
1118                 // better handled lower in the event loop closer to where they originate. If
1119                 // they get propagated up here then we can't meaningfully handle them anymore,
1120                 // so just log them and continue the loop.
1121                 | TipcError::IncompleteWrite { .. }
1122                 | TipcError::NotEnoughBuffer
1123                 | TipcError::Busy
1124                 => {
1125                     warn!(
1126                         "Received error {:?} in main event loop. This should have been handled closer to where it originated",
1127                         err,
1128                     )
1129                 }
1130 
1131                 _ => {
1132                     error!("Error occurred while handling incoming event: {:?}", err);
1133                     return Err(err);
1134                 }
1135             }
1136         }
1137     }
1138 
event_loop_inner(&mut self) -> Result<()>1139     fn event_loop_inner(&mut self) -> Result<()> {
1140         let event = self.handle_set.wait(None)?;
1141         // SAFETY: This cookie was previously initialized by the handle set.
1142         // Its lifetime is managed by the handle set, so we are sure that
1143         // the cookie is still valid if the channel is still in this handle
1144         // set.
1145         let channel: Rc<Channel<D>> = unsafe { Channel::from_opaque_ptr(event.cookie) }
1146             .ok_or_else(|| {
1147                 // The opaque pointer associated with this handle could not
1148                 // be converted back into a `Channel`. This should never
1149                 // happen, but throw an internal error if it does.
1150                 error!("Connection cookie was invalid");
1151                 TipcError::InvalidData
1152             })?;
1153         self.handler(channel, &event)
1154     }
1155 
handler(&mut self, channel: Rc<Channel<D>>, event: &trusty_sys::uevent) -> Result<()>1156     fn handler(&mut self, channel: Rc<Channel<D>>, event: &trusty_sys::uevent) -> Result<()> {
1157         // TODO: Abort on port errors?
1158         match &channel.ty {
1159             ChannelTy::Port(cfg) if event.event & (sys::IPC_HANDLE_POLL_READY as u32) != 0 => {
1160                 self.handle_connect(&channel.handle, cfg)
1161             }
1162             ChannelTy::Connection(data) if event.event & (sys::IPC_HANDLE_POLL_MSG as u32) != 0 => {
1163                 match self.handle_message(&channel.handle, &data) {
1164                     Ok(MessageResult::MaintainConnection) => Ok(()),
1165                     Ok(MessageResult::CloseConnection) => {
1166                         self.handle_set.close(channel);
1167                         Ok(())
1168                     }
1169                     Err(e) => {
1170                         error!("Could not handle message, closing connection: {:?}", e);
1171                         self.handle_set.close(channel);
1172                         Ok(())
1173                     }
1174                 }
1175             }
1176             ChannelTy::Connection(data) if event.event & (sys::IPC_HANDLE_POLL_HUP as u32) != 0 => {
1177                 self.handle_disconnect(&channel.handle, &data);
1178                 self.handle_set.close(channel);
1179                 Ok(())
1180             }
1181 
1182             // `SEND_UNBLOCKED` means that some previous attempt to send a message was
1183             // blocked and has now become unblocked. This should normally be handled by
1184             // the code trying to send the message, but if the sending code doesn't do so
1185             // then we can end up getting it here.
1186             _ if event.event & (sys::IPC_HANDLE_POLL_SEND_UNBLOCKED as u32) != 0 => {
1187                 warn!("Received `SEND_UNBLOCKED` event received in main event loop. This likely means that a sent message was lost somewhere");
1188                 Ok(())
1189             }
1190 
1191             // `NONE` is not an event we should get in practice, but if it does then it
1192             // shouldn't trigger an error.
1193             _ if event.event == (sys::IPC_HANDLE_POLL_NONE as u32) => Ok(()),
1194 
1195             // Treat any unrecognized events as errors by default.
1196             _ => {
1197                 error!("Could not handle event {}", event.event);
1198                 Err(TipcError::UnknownError)
1199             }
1200         }
1201     }
1202 
handle_connect(&mut self, handle: &Handle, cfg: &PortCfg) -> Result<()>1203     fn handle_connect(&mut self, handle: &Handle, cfg: &PortCfg) -> Result<()> {
1204         let mut peer = MaybeUninit::zeroed();
1205         // SAFETY: syscall. The port owns its handle, so it is still valid as
1206         // a raw fd. The peer structure outlives this call and is mutably
1207         // borrowed by the call to initialize the structure's data.
1208         let rc = unsafe { trusty_sys::accept(handle.as_raw_fd(), peer.as_mut_ptr()) as i32 };
1209         let connection_handle = Handle::from_raw(rc)?;
1210         // SAFETY: accept did not return an error, so it has successfully
1211         // initialized the peer structure.
1212         let peer = unsafe { Uuid(peer.assume_init()) };
1213 
1214         // Check against access control list if we were given one
1215         if let Some(uuids) = cfg.uuid_allow_list {
1216             if !uuids.contains(&peer) {
1217                 error!("UUID {peer:?} isn't supported.\n");
1218                 return Err(TipcError::SystemError(trusty_sys::Error::NotAllowed));
1219             }
1220         }
1221 
1222         let connection_data = self.dispatcher.on_connect(&cfg, &connection_handle, &peer)?;
1223         if let ConnectResult::Accept(data) = connection_data {
1224             let connection_channel = Channel::try_new_connection(connection_handle, data)?;
1225             self.handle_set.add_connection(connection_channel)?;
1226         }
1227 
1228         Ok(())
1229     }
1230 
handle_message(&mut self, handle: &Handle, data: &D::Connection) -> Result<MessageResult>1231     fn handle_message(&mut self, handle: &Handle, data: &D::Connection) -> Result<MessageResult> {
1232         self.dispatcher.on_message(data, handle, self.buffer.as_mut())
1233     }
1234 
handle_disconnect(&mut self, _handle: &Handle, data: &D::Connection)1235     fn handle_disconnect(&mut self, _handle: &Handle, data: &D::Connection) {
1236         self.dispatcher.on_disconnect(data);
1237     }
1238 }
1239 
1240 #[cfg(test)]
1241 mod test {
1242     use super::{PortCfg, Service};
1243     use crate::handle::test::{first_free_handle_index, MAX_USER_HANDLES};
1244     use crate::{
1245         ConnectResult, Deserialize, Handle, Manager, MessageResult, Result, TipcError,
1246         UnbufferedService, Uuid,
1247     };
1248     use test::{expect, expect_eq};
1249     use trusty_std::alloc::FallibleVec;
1250     use trusty_std::ffi::{CString, FallibleCString};
1251     use trusty_std::format;
1252     use trusty_std::rc::Rc;
1253     use trusty_std::vec::Vec;
1254     use trusty_sys::Error;
1255 
1256     /// Maximum length of port path name
1257     const MAX_PORT_PATH_LEN: usize = 64;
1258 
1259     /// Maximum number of buffers per port
1260     const MAX_PORT_BUF_NUM: u32 = 64;
1261 
1262     /// Maximum size of port buffer
1263     const MAX_PORT_BUF_SIZE: u32 = 4096;
1264 
1265     const SRV_PATH_BASE: &str = "com.android.ipc-unittest";
1266 
1267     impl Service for () {
1268         type Connection = ();
1269         type Message = ();
1270 
on_connect( &self, _port: &PortCfg, _handle: &Handle, _peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>1271         fn on_connect(
1272             &self,
1273             _port: &PortCfg,
1274             _handle: &Handle,
1275             _peer: &Uuid,
1276         ) -> Result<ConnectResult<Self::Connection>> {
1277             Ok(ConnectResult::Accept(()))
1278         }
1279 
on_message( &self, _connection: &Self::Connection, _handle: &Handle, _msg: Self::Message, ) -> Result<MessageResult>1280         fn on_message(
1281             &self,
1282             _connection: &Self::Connection,
1283             _handle: &Handle,
1284             _msg: Self::Message,
1285         ) -> Result<MessageResult> {
1286             Ok(MessageResult::MaintainConnection)
1287         }
1288     }
1289 
1290     type Channel = super::Channel<super::SingleDispatcher<()>>;
1291 
1292     #[test]
port_create_negative()1293     fn port_create_negative() {
1294         let path = [0u8; 0];
1295 
1296         expect_eq!(
1297             Channel::try_new_port(&PortCfg::new_raw(CString::try_new(&path[..]).unwrap())).err(),
1298             Some(TipcError::SystemError(Error::InvalidArgs)),
1299             "empty server path",
1300         );
1301 
1302         let mut path = format!("{}.port", SRV_PATH_BASE);
1303 
1304         let cfg = PortCfg::new(&path).unwrap().msg_queue_len(0);
1305         expect_eq!(
1306             Channel::try_new_port(&cfg).err(),
1307             Some(TipcError::SystemError(Error::InvalidArgs)),
1308             "no buffers",
1309         );
1310 
1311         let cfg = PortCfg::new(&path).unwrap().msg_max_size(0);
1312         expect_eq!(
1313             Channel::try_new_port(&cfg).err(),
1314             Some(TipcError::SystemError(Error::InvalidArgs)),
1315             "zero buffer size",
1316         );
1317 
1318         let cfg = PortCfg::new(&path).unwrap().msg_queue_len(MAX_PORT_BUF_NUM * 100);
1319         expect_eq!(
1320             Channel::try_new_port(&cfg).err(),
1321             Some(TipcError::SystemError(Error::InvalidArgs)),
1322             "large number of buffers",
1323         );
1324 
1325         let cfg = PortCfg::new(&path).unwrap().msg_max_size(MAX_PORT_BUF_SIZE * 100);
1326         expect_eq!(
1327             Channel::try_new_port(&cfg).err(),
1328             Some(TipcError::SystemError(Error::InvalidArgs)),
1329             "large buffers size",
1330         );
1331 
1332         while path.len() < MAX_PORT_PATH_LEN + 16 {
1333             path.push('a');
1334         }
1335 
1336         let cfg = PortCfg::new(&path).unwrap();
1337         expect_eq!(
1338             Channel::try_new_port(&cfg).err(),
1339             Some(TipcError::SystemError(Error::InvalidArgs)),
1340             "path is too long",
1341         );
1342     }
1343 
1344     #[test]
port_create()1345     fn port_create() {
1346         let mut channels: Vec<Rc<Channel>> = Vec::new();
1347 
1348         for i in first_free_handle_index()..MAX_USER_HANDLES - 1 {
1349             let path = format!("{}.port.{}{}", SRV_PATH_BASE, "test", i);
1350             let cfg = PortCfg::new(path).unwrap();
1351             let channel = Channel::try_new_port(&cfg);
1352             expect!(channel.is_ok(), "create ports");
1353             channels.try_push(channel.unwrap()).unwrap();
1354 
1355             expect_eq!(
1356                 Channel::try_new_port(&cfg).err(),
1357                 Some(TipcError::SystemError(Error::AlreadyExists)),
1358                 "collide with existing port",
1359             );
1360         }
1361 
1362         // Creating one more port should succeed
1363         let path = format!("{}.port.{}{}", SRV_PATH_BASE, "test", MAX_USER_HANDLES - 1);
1364         let cfg = PortCfg::new(path).unwrap();
1365         let channel = Channel::try_new_port(&cfg);
1366         expect!(channel.is_ok(), "create ports");
1367         channels.try_push(channel.unwrap()).unwrap();
1368 
1369         // but creating colliding port should fail with different error code
1370         // because we actually exceeded max number of handles instead of
1371         // colliding with an existing path
1372         expect_eq!(
1373             Channel::try_new_port(&cfg).err(),
1374             Some(TipcError::SystemError(Error::NoResources)),
1375             "collide with existing port",
1376         );
1377 
1378         let path = format!("{}.port.{}{}", SRV_PATH_BASE, "test", MAX_USER_HANDLES);
1379         let cfg = PortCfg::new(path).unwrap();
1380         expect_eq!(
1381             Channel::try_new_port(&cfg).err(),
1382             Some(TipcError::SystemError(Error::NoResources)),
1383             "max number of ports reached",
1384         );
1385     }
1386 
1387     #[test]
wait_on_port()1388     fn wait_on_port() {
1389         let mut channels: Vec<Rc<Channel>> = Vec::new();
1390 
1391         for i in first_free_handle_index()..MAX_USER_HANDLES {
1392             let path = format!("{}.port.{}{}", SRV_PATH_BASE, "test", i);
1393             let cfg = PortCfg::new(path).unwrap();
1394             let channel = Channel::try_new_port(&cfg);
1395             expect!(channel.is_ok(), "create ports");
1396             channels.try_push(channel.unwrap()).unwrap();
1397         }
1398 
1399         for chan in &channels {
1400             expect_eq!(
1401                 chan.handle.wait(Some(0)).err(),
1402                 Some(TipcError::SystemError(Error::TimedOut)),
1403                 "zero timeout",
1404             );
1405 
1406             expect_eq!(
1407                 chan.handle.wait(Some(100)).err(),
1408                 Some(TipcError::SystemError(Error::TimedOut)),
1409                 "non-zero timeout",
1410             );
1411         }
1412     }
1413 
1414     impl Deserialize for i32 {
1415         type Error = TipcError;
1416 
1417         const MAX_SERIALIZED_SIZE: usize = 4;
1418 
deserialize( bytes: &[u8], _handles: &mut [Option<Handle>], ) -> core::result::Result<Self, Self::Error>1419         fn deserialize(
1420             bytes: &[u8],
1421             _handles: &mut [Option<Handle>],
1422         ) -> core::result::Result<Self, Self::Error> {
1423             Ok(i32::from_ne_bytes(bytes[0..4].try_into().map_err(|_| TipcError::OutOfBounds)?))
1424         }
1425     }
1426 
1427     struct Service1;
1428 
1429     impl Service for Service1 {
1430         type Connection = ();
1431         type Message = ();
1432 
on_connect( &self, _port: &PortCfg, _handle: &Handle, _peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>1433         fn on_connect(
1434             &self,
1435             _port: &PortCfg,
1436             _handle: &Handle,
1437             _peer: &Uuid,
1438         ) -> Result<ConnectResult<Self::Connection>> {
1439             Ok(ConnectResult::Accept(()))
1440         }
1441 
on_message( &self, _connection: &Self::Connection, handle: &Handle, _msg: Self::Message, ) -> Result<MessageResult>1442         fn on_message(
1443             &self,
1444             _connection: &Self::Connection,
1445             handle: &Handle,
1446             _msg: Self::Message,
1447         ) -> Result<MessageResult> {
1448             handle.send(&1i32)?;
1449             Ok(MessageResult::MaintainConnection)
1450         }
1451     }
1452 
1453     struct Service2;
1454 
1455     impl Service for Service2 {
1456         type Connection = ();
1457         type Message = ();
1458 
on_connect( &self, _port: &PortCfg, _handle: &Handle, _peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>1459         fn on_connect(
1460             &self,
1461             _port: &PortCfg,
1462             _handle: &Handle,
1463             _peer: &Uuid,
1464         ) -> Result<ConnectResult<Self::Connection>> {
1465             Ok(ConnectResult::Accept(()))
1466         }
1467 
on_message( &self, _connection: &Self::Connection, handle: &Handle, _msg: Self::Message, ) -> Result<MessageResult>1468         fn on_message(
1469             &self,
1470             _connection: &Self::Connection,
1471             handle: &Handle,
1472             _msg: Self::Message,
1473         ) -> Result<MessageResult> {
1474             handle.send(&2i32)?;
1475             Ok(MessageResult::MaintainConnection)
1476         }
1477     }
1478 
1479     struct Service3;
1480 
1481     impl UnbufferedService for Service3 {
1482         type Connection = ();
1483 
on_connect( &self, _port: &PortCfg, _handle: &Handle, _peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>1484         fn on_connect(
1485             &self,
1486             _port: &PortCfg,
1487             _handle: &Handle,
1488             _peer: &Uuid,
1489         ) -> Result<ConnectResult<Self::Connection>> {
1490             Ok(ConnectResult::Accept(()))
1491         }
1492 
on_message( &self, _connection: &Self::Connection, handle: &Handle, _buffer: &mut [u8], ) -> Result<MessageResult>1493         fn on_message(
1494             &self,
1495             _connection: &Self::Connection,
1496             handle: &Handle,
1497             _buffer: &mut [u8],
1498         ) -> Result<MessageResult> {
1499             handle.send(&3i32)?;
1500             Ok(MessageResult::MaintainConnection)
1501         }
1502     }
1503 
1504     wrap_service!(WrappedService2(Service2: Service));
1505     wrap_service!(WrappedService3(Service3: UnbufferedService));
1506 
1507     service_dispatcher! {
1508         enum TestServiceDispatcher {
1509             Service1,
1510             Service2,
1511             Service3,
1512             WrappedService2,
1513             WrappedService3,
1514         }
1515     }
1516 
1517     #[test]
multiple_services()1518     fn multiple_services() {
1519         let mut dispatcher = TestServiceDispatcher::<5>::new().unwrap();
1520 
1521         let path1 = format!("{}.port.{}", SRV_PATH_BASE, "testService1");
1522         let cfg = PortCfg::new(&path1).unwrap();
1523         dispatcher.add_service(Rc::new(Service1), cfg).expect("Could not add service 1");
1524 
1525         let path2 = format!("{}.port.{}", SRV_PATH_BASE, "testService2");
1526         let cfg = PortCfg::new(&path2).unwrap();
1527         dispatcher.add_service(Rc::new(Service2), cfg).expect("Could not add service 2");
1528 
1529         let path = format!("{}.port.{}", SRV_PATH_BASE, "testService3");
1530         let cfg = PortCfg::new(&path).unwrap();
1531         dispatcher.add_service(Rc::new(Service3), cfg).expect("Could not add service 3");
1532 
1533         let path = format!("{}.port.{}", SRV_PATH_BASE, "testWrappedService2");
1534         let cfg = PortCfg::new(&path).unwrap();
1535         dispatcher
1536             .add_service(Rc::new(WrappedService2(Service2)), cfg)
1537             .expect("Could not add wrapped service 2");
1538 
1539         let path = format!("{}.port.{}", SRV_PATH_BASE, "testWrappedService3");
1540         let cfg = PortCfg::new(&path).unwrap();
1541         dispatcher
1542             .add_service(Rc::new(WrappedService3(Service3)), cfg)
1543             .expect("Could not add wrapped service 3");
1544 
1545         let buffer = [0u8; 4096];
1546         Manager::<_, _, 5, 4>::new_with_dispatcher(dispatcher, buffer)
1547             .expect("Could not create service manager");
1548     }
1549 
1550     #[test]
unbuffered_service()1551     fn unbuffered_service() {
1552         let path = format!("{}.port.{}", SRV_PATH_BASE, "unbufferedService");
1553         let cfg = PortCfg::new(&path).unwrap();
1554         Manager::<_, _, 1, 4>::new_unbuffered(Service3, cfg)
1555             .expect("Could not create service manager");
1556     }
1557 }
1558 
1559 #[cfg(test)]
1560 mod multiservice_with_lifetimes_tests {
1561     use super::*;
1562     use core::marker::PhantomData;
1563     #[allow(unused)]
1564     use trusty_std::alloc::FallibleVec;
1565 
1566     const SRV_PATH_BASE: &str = "com.android.ipc-unittest-lifetimes";
1567 
1568     pub(crate) struct Service1<'a> {
1569         phantom: PhantomData<&'a u32>,
1570     }
1571 
1572     impl<'a> Service for Service1<'a> {
1573         type Connection = ();
1574         type Message = ();
1575 
on_connect( &self, _port: &PortCfg, _handle: &Handle, _peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>1576         fn on_connect(
1577             &self,
1578             _port: &PortCfg,
1579             _handle: &Handle,
1580             _peer: &Uuid,
1581         ) -> Result<ConnectResult<Self::Connection>> {
1582             Ok(ConnectResult::Accept(()))
1583         }
1584 
on_message( &self, _connection: &Self::Connection, handle: &Handle, _msg: Self::Message, ) -> Result<MessageResult>1585         fn on_message(
1586             &self,
1587             _connection: &Self::Connection,
1588             handle: &Handle,
1589             _msg: Self::Message,
1590         ) -> Result<MessageResult> {
1591             handle.send(&2i32)?;
1592             Ok(MessageResult::MaintainConnection)
1593         }
1594     }
1595 
1596     pub(crate) struct Service2<'a> {
1597         phantom: PhantomData<&'a u32>,
1598     }
1599 
1600     impl<'a> Service for Service2<'a> {
1601         type Connection = ();
1602         type Message = ();
1603 
on_connect( &self, _port: &PortCfg, _handle: &Handle, _peer: &Uuid, ) -> Result<ConnectResult<Self::Connection>>1604         fn on_connect(
1605             &self,
1606             _port: &PortCfg,
1607             _handle: &Handle,
1608             _peer: &Uuid,
1609         ) -> Result<ConnectResult<Self::Connection>> {
1610             Ok(ConnectResult::Accept(()))
1611         }
1612 
on_message( &self, _connection: &Self::Connection, handle: &Handle, _msg: Self::Message, ) -> Result<MessageResult>1613         fn on_message(
1614             &self,
1615             _connection: &Self::Connection,
1616             handle: &Handle,
1617             _msg: Self::Message,
1618         ) -> Result<MessageResult> {
1619             handle.send(&2i32)?;
1620             Ok(MessageResult::MaintainConnection)
1621         }
1622     }
1623 
1624     service_dispatcher! {
1625         pub(crate) enum TestServiceLifetimeDispatcher<'a> {
1626             Service1<'a>,
1627             Service2<'a>,
1628         }
1629     }
1630 
1631     #[test]
manager_creation()1632     fn manager_creation() {
1633         let mut dispatcher = TestServiceLifetimeDispatcher::<2>::new().unwrap();
1634 
1635         let path1 = format!("{}.port.{}", SRV_PATH_BASE, "testService1");
1636         let cfg = PortCfg::new(&path1).unwrap();
1637         dispatcher
1638             .add_service(Rc::new(Service1 { phantom: PhantomData }), cfg)
1639             .expect("Could not add service 1");
1640 
1641         let path2 = format!("{}.port.{}", SRV_PATH_BASE, "testService2");
1642         let cfg = PortCfg::new(&path2).unwrap();
1643         dispatcher
1644             .add_service(Rc::new(Service2 { phantom: PhantomData }), cfg)
1645             .expect("Could not add service 2");
1646 
1647         let buffer = [0u8; 4096];
1648         Manager::<_, _, 2, 4>::new_with_dispatcher(dispatcher, buffer)
1649             .expect("Could not create service manager");
1650     }
1651 }
1652 
1653 #[cfg(test)]
1654 mod uuid_tests {
1655     use super::Uuid;
1656     use test::{expect, expect_eq};
1657 
1658     #[test]
uuid_parsing()1659     fn uuid_parsing() {
1660         let uuid = Uuid::new(0, 0, 0, [0; 8]);
1661         let uuid_string = "00000000-0000-0000-0000-000000000000".to_string();
1662         expect_eq!(uuid.to_string(), uuid_string);
1663         let uuid_from_str = Uuid::new_from_string(&uuid_string);
1664         expect!(uuid_from_str.is_ok(), "couldn't parse uuid string");
1665         let uuid_from_str = uuid_from_str.unwrap();
1666         expect_eq!(uuid, uuid_from_str, "uuid should match");
1667         let uuid2 = Uuid::new(1262561249, 51804, 17255, [189, 181, 5, 22, 64, 5, 183, 196]);
1668         let uuid_string_2 = "4b4127e1-ca5c-4367-bdb5-05164005b7c4".to_string();
1669         let uuid2_from_str = Uuid::new_from_string(&uuid_string_2);
1670         expect!(uuid2_from_str.is_ok(), "couldn't parse uuid string");
1671         let uuid2_from_str = uuid2_from_str.unwrap();
1672         expect_eq!(uuid2, uuid2_from_str, "uuid should match");
1673         let bad_uuid_from_str = Uuid::new_from_string("4b4127e1-ca5c-4367-bdb5-05164005b7c45");
1674         expect!(bad_uuid_from_str.is_err(), "shouldn't be able to parse string");
1675         let bad_uuid_from_str = Uuid::new_from_string("4b4127e1-ca5c-4367-bdbq-05164005b7c4");
1676         expect!(bad_uuid_from_str.is_err(), "shouldn't be able to parse string");
1677         let bad_uuid_from_str = Uuid::new_from_string("4b4127e1-ca5c-4367-bdb5005164005b7c4");
1678         expect!(bad_uuid_from_str.is_err(), "shouldn't be able to parse string");
1679         let bad_uuid_from_str = Uuid::new_from_string("4b41-7e1-ca5c-4367-bdb5-05164005b7c4");
1680         expect!(bad_uuid_from_str.is_err(), "shouldn't be able to parse string");
1681         let bad_uuid_from_str = Uuid::new_from_string("4b4127e1-ca5c-4367-bd-b505164005b7c4");
1682         expect!(bad_uuid_from_str.is_err(), "shouldn't be able to parse string");
1683     }
1684 }
1685