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