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