1 // Copyright 2021 The Chromium OS Authors. All rights reserved. 2 // SPDX-License-Identifier: Apache-2.0 3 4 //! Structs for Unix Domain Socket listener and endpoint. 5 6 use std::any::Any; 7 use std::fs::File; 8 use std::io::ErrorKind; 9 use std::io::IoSlice; 10 use std::io::IoSliceMut; 11 use std::marker::PhantomData; 12 use std::path::Path; 13 use std::path::PathBuf; 14 15 use base::AsRawDescriptor; 16 use base::FromRawDescriptor; 17 use base::IntoRawDescriptor; 18 use base::RawDescriptor; 19 use base::ScmSocket; 20 21 use crate::connection::Endpoint as EndpointTrait; 22 use crate::connection::Listener as ListenerTrait; 23 use crate::connection::Req; 24 use crate::message::*; 25 use crate::take_single_file; 26 use crate::unix::SystemListener; 27 use crate::Error; 28 use crate::Result; 29 use crate::SystemStream; 30 31 /// Unix domain socket listener for accepting incoming connections. 32 pub struct Listener { 33 fd: SystemListener, 34 drop_path: Option<Box<dyn Any>>, 35 } 36 37 impl Listener { 38 /// Create a unix domain socket listener. 39 /// 40 /// # Return: 41 /// * - the new Listener object on success. 42 /// * - SocketError: failed to create listener socket. new<P: AsRef<Path>>(path: P, unlink: bool) -> Result<Self>43 pub fn new<P: AsRef<Path>>(path: P, unlink: bool) -> Result<Self> { 44 if unlink { 45 let _ = std::fs::remove_file(&path); 46 } 47 let fd = SystemListener::bind(&path).map_err(Error::SocketError)?; 48 49 struct DropPath { 50 path: PathBuf, 51 } 52 53 impl Drop for DropPath { 54 fn drop(&mut self) { 55 let _ = std::fs::remove_file(&self.path); 56 } 57 } 58 59 Ok(Listener { 60 fd, 61 drop_path: Some(Box::new(DropPath { 62 path: path.as_ref().to_owned(), 63 })), 64 }) 65 } 66 67 /// Take and return the resources that the parent process needs to keep alive as long as the 68 /// child process lives, in case of incoming fork. take_resources_for_parent(&mut self) -> Option<Box<dyn Any>>69 pub fn take_resources_for_parent(&mut self) -> Option<Box<dyn Any>> { 70 self.drop_path.take() 71 } 72 } 73 74 impl ListenerTrait for Listener { 75 type Connection = SystemStream; 76 type Endpoint = Endpoint<MasterReq>; 77 78 /// Accept an incoming connection. 79 /// 80 /// # Return: 81 /// * - Some(SystemListener): new SystemListener object if new incoming connection is available. 82 /// * - None: no incoming connection available. 83 /// * - SocketError: errors from accept(). accept(&mut self) -> Result<Option<Self::Endpoint>>84 fn accept(&mut self) -> Result<Option<Self::Endpoint>> { 85 loop { 86 match self.fd.accept() { 87 Ok((stream, _addr)) => { 88 return Ok(Some(Endpoint { 89 sock: stream, 90 _r: PhantomData, 91 })) 92 } 93 Err(e) => { 94 match e.kind() { 95 // No incoming connection available. 96 ErrorKind::WouldBlock => return Ok(None), 97 // New connection closed by peer. 98 ErrorKind::ConnectionAborted => return Ok(None), 99 // Interrupted by signals, retry 100 ErrorKind::Interrupted => continue, 101 _ => return Err(Error::SocketError(e)), 102 } 103 } 104 } 105 } 106 } 107 108 /// Change blocking status on the listener. 109 /// 110 /// # Return: 111 /// * - () on success. 112 /// * - SocketError: failure from set_nonblocking(). set_nonblocking(&self, block: bool) -> Result<()>113 fn set_nonblocking(&self, block: bool) -> Result<()> { 114 self.fd.set_nonblocking(block).map_err(Error::SocketError) 115 } 116 } 117 118 impl AsRawDescriptor for Listener { as_raw_descriptor(&self) -> RawDescriptor119 fn as_raw_descriptor(&self) -> RawDescriptor { 120 self.fd.as_raw_descriptor() 121 } 122 } 123 124 /// Unix domain socket endpoint for vhost-user connection. 125 pub struct Endpoint<R: Req> { 126 sock: SystemStream, 127 _r: PhantomData<R>, 128 } 129 130 impl<R: Req> From<SystemStream> for Endpoint<R> { from(sock: SystemStream) -> Self131 fn from(sock: SystemStream) -> Self { 132 Self { 133 sock, 134 _r: PhantomData, 135 } 136 } 137 } 138 139 impl<R: Req> EndpointTrait<R> for Endpoint<R> { 140 /// Create a new stream by connecting to server at `str`. 141 /// 142 /// # Return: 143 /// * - the new Endpoint object on success. 144 /// * - SocketConnect: failed to connect to peer. connect<P: AsRef<Path>>(path: P) -> Result<Self>145 fn connect<P: AsRef<Path>>(path: P) -> Result<Self> { 146 let sock = SystemStream::connect(path).map_err(Error::SocketConnect)?; 147 Ok(Self::from(sock)) 148 } 149 150 /// Sends bytes from scatter-gather vectors over the socket with optional attached file 151 /// descriptors. 152 /// 153 /// # Return: 154 /// * - number of bytes sent on success 155 /// * - SocketRetry: temporary error caused by signals or short of resources. 156 /// * - SocketBroken: the underline socket is broken. 157 /// * - SocketError: other socket related errors. send_iovec(&mut self, iovs: &[IoSlice], fds: Option<&[RawDescriptor]>) -> Result<usize>158 fn send_iovec(&mut self, iovs: &[IoSlice], fds: Option<&[RawDescriptor]>) -> Result<usize> { 159 let rfds = match fds { 160 Some(rfds) => rfds, 161 _ => &[], 162 }; 163 self.sock.send_bufs_with_fds(iovs, rfds).map_err(Into::into) 164 } 165 166 /// Reads bytes from the socket into the given scatter/gather vectors with optional attached 167 /// file. 168 /// 169 /// The underlying communication channel is a Unix domain socket in STREAM mode. It's a little 170 /// tricky to pass file descriptors through such a communication channel. Let's assume that a 171 /// sender sending a message with some file descriptors attached. To successfully receive those 172 /// attached file descriptors, the receiver must obey following rules: 173 /// 1) file descriptors are attached to a message. 174 /// 2) message(packet) boundaries must be respected on the receive side. 175 /// In other words, recvmsg() operations must not cross the packet boundary, otherwise the 176 /// attached file descriptors will get lost. 177 /// Note that this function wraps received file descriptors as `File`. 178 /// 179 /// # Return: 180 /// * - (number of bytes received, [received files]) on success 181 /// * - Disconnect: the connection is closed. 182 /// * - SocketRetry: temporary error caused by signals or short of resources. 183 /// * - SocketBroken: the underline socket is broken. 184 /// * - SocketError: other socket related errors. recv_into_bufs( &mut self, bufs: &mut [IoSliceMut], allow_fd: bool, ) -> Result<(usize, Option<Vec<File>>)>185 fn recv_into_bufs( 186 &mut self, 187 bufs: &mut [IoSliceMut], 188 allow_fd: bool, 189 ) -> Result<(usize, Option<Vec<File>>)> { 190 let mut fd_array = if allow_fd { 191 vec![0; MAX_ATTACHED_FD_ENTRIES] 192 } else { 193 vec![] 194 }; 195 let mut iovs: Vec<_> = bufs.iter_mut().map(|s| IoSliceMut::new(s)).collect(); 196 let (bytes, fds) = self.sock.recv_iovecs_with_fds(&mut iovs, &mut fd_array)?; 197 198 // 0-bytes indicates that the connection is closed. 199 if bytes == 0 { 200 return Err(Error::Disconnect); 201 } 202 203 let files = match fds { 204 0 => None, 205 n => { 206 let files = fd_array 207 .iter() 208 .take(n) 209 .map(|fd| { 210 // Safe because we have the ownership of `fd`. 211 unsafe { File::from_raw_descriptor(*fd as RawDescriptor) } 212 }) 213 .collect(); 214 Some(files) 215 } 216 }; 217 218 Ok((bytes, files)) 219 } 220 create_slave_request_endpoint( &mut self, files: Option<Vec<File>>, ) -> Result<Box<dyn EndpointTrait<SlaveReq>>>221 fn create_slave_request_endpoint( 222 &mut self, 223 files: Option<Vec<File>>, 224 ) -> Result<Box<dyn EndpointTrait<SlaveReq>>> { 225 let file = take_single_file(files).ok_or(Error::InvalidMessage)?; 226 // Safe because we own the file 227 let tube = unsafe { SystemStream::from_raw_descriptor(file.into_raw_descriptor()) }; 228 Ok(Box::new(Endpoint::from(tube))) 229 } 230 } 231 232 impl<T: Req> AsRawDescriptor for Endpoint<T> { as_raw_descriptor(&self) -> RawDescriptor233 fn as_raw_descriptor(&self) -> RawDescriptor { 234 self.sock.as_raw_descriptor() 235 } 236 } 237 238 impl<T: Req> AsMut<SystemStream> for Endpoint<T> { as_mut(&mut self) -> &mut SystemStream239 fn as_mut(&mut self) -> &mut SystemStream { 240 &mut self.sock 241 } 242 } 243 244 #[cfg(test)] 245 mod tests { 246 use std::io::Read; 247 use std::io::Seek; 248 use std::io::SeekFrom; 249 use std::io::Write; 250 use std::mem; 251 use std::slice; 252 253 use tempfile::tempfile; 254 use tempfile::Builder; 255 use tempfile::TempDir; 256 257 use super::*; 258 use crate::connection::EndpointExt; 259 temp_dir() -> TempDir260 fn temp_dir() -> TempDir { 261 Builder::new().prefix("/tmp/vhost_test").tempdir().unwrap() 262 } 263 264 #[test] create_listener()265 fn create_listener() { 266 let dir = temp_dir(); 267 let mut path = dir.path().to_owned(); 268 path.push("sock"); 269 let listener = Listener::new(&path, true).unwrap(); 270 271 assert!(listener.as_raw_descriptor() > 0); 272 } 273 274 #[test] accept_connection()275 fn accept_connection() { 276 let dir = temp_dir(); 277 let mut path = dir.path().to_owned(); 278 path.push("sock"); 279 let mut listener = Listener::new(&path, true).unwrap(); 280 listener.set_nonblocking(true).unwrap(); 281 282 // accept on a fd without incoming connection 283 let conn = listener.accept().unwrap(); 284 assert!(conn.is_none()); 285 } 286 287 #[test] send_data()288 fn send_data() { 289 let dir = temp_dir(); 290 let mut path = dir.path().to_owned(); 291 path.push("sock"); 292 let mut listener = Listener::new(&path, true).unwrap(); 293 listener.set_nonblocking(true).unwrap(); 294 let mut master = Endpoint::<MasterReq>::connect(&path).unwrap(); 295 let mut slave = listener.accept().unwrap().unwrap(); 296 297 let buf1 = vec![0x1, 0x2, 0x3, 0x4]; 298 let mut len = master.send_slice(IoSlice::new(&buf1[..]), None).unwrap(); 299 assert_eq!(len, 4); 300 let (bytes, buf2, _) = slave.recv_into_buf(0x1000).unwrap(); 301 assert_eq!(bytes, 4); 302 assert_eq!(&buf1[..], &buf2[..bytes]); 303 304 len = master.send_slice(IoSlice::new(&buf1[..]), None).unwrap(); 305 assert_eq!(len, 4); 306 let (bytes, buf2, _) = slave.recv_into_buf(0x2).unwrap(); 307 assert_eq!(bytes, 2); 308 assert_eq!(&buf1[..2], &buf2[..]); 309 let (bytes, buf2, _) = slave.recv_into_buf(0x2).unwrap(); 310 assert_eq!(bytes, 2); 311 assert_eq!(&buf1[2..], &buf2[..]); 312 } 313 314 #[test] send_fd()315 fn send_fd() { 316 let dir = temp_dir(); 317 let mut path = dir.path().to_owned(); 318 path.push("sock"); 319 let mut listener = Listener::new(&path, true).unwrap(); 320 listener.set_nonblocking(true).unwrap(); 321 let mut master = Endpoint::<MasterReq>::connect(&path).unwrap(); 322 let mut slave = listener.accept().unwrap().unwrap(); 323 324 let mut fd = tempfile().unwrap(); 325 write!(fd, "test").unwrap(); 326 327 // Normal case for sending/receiving file descriptors 328 let buf1 = vec![0x1, 0x2, 0x3, 0x4]; 329 let len = master 330 .send_slice(IoSlice::new(&buf1[..]), Some(&[fd.as_raw_descriptor()])) 331 .unwrap(); 332 assert_eq!(len, 4); 333 334 let (bytes, buf2, files) = slave.recv_into_buf(4).unwrap(); 335 assert_eq!(bytes, 4); 336 assert_eq!(&buf1[..], &buf2[..]); 337 assert!(files.is_some()); 338 let files = files.unwrap(); 339 { 340 assert_eq!(files.len(), 1); 341 let mut file = &files[0]; 342 let mut content = String::new(); 343 file.seek(SeekFrom::Start(0)).unwrap(); 344 file.read_to_string(&mut content).unwrap(); 345 assert_eq!(content, "test"); 346 } 347 348 // Following communication pattern should work: 349 // Sending side: data(header, body) with fds 350 // Receiving side: data(header) with fds, data(body) 351 let len = master 352 .send_slice( 353 IoSlice::new(&buf1[..]), 354 Some(&[ 355 fd.as_raw_descriptor(), 356 fd.as_raw_descriptor(), 357 fd.as_raw_descriptor(), 358 ]), 359 ) 360 .unwrap(); 361 assert_eq!(len, 4); 362 363 let (bytes, buf2, files) = slave.recv_into_buf(0x2).unwrap(); 364 assert_eq!(bytes, 2); 365 assert_eq!(&buf1[..2], &buf2[..]); 366 assert!(files.is_some()); 367 let files = files.unwrap(); 368 { 369 assert_eq!(files.len(), 3); 370 let mut file = &files[1]; 371 let mut content = String::new(); 372 file.seek(SeekFrom::Start(0)).unwrap(); 373 file.read_to_string(&mut content).unwrap(); 374 assert_eq!(content, "test"); 375 } 376 let (bytes, buf2, files) = slave.recv_into_buf(0x2).unwrap(); 377 assert_eq!(bytes, 2); 378 assert_eq!(&buf1[2..], &buf2[..]); 379 assert!(files.is_none()); 380 381 // Following communication pattern should not work: 382 // Sending side: data(header, body) with fds 383 // Receiving side: data(header), data(body) with fds 384 let len = master 385 .send_slice( 386 IoSlice::new(&buf1[..]), 387 Some(&[ 388 fd.as_raw_descriptor(), 389 fd.as_raw_descriptor(), 390 fd.as_raw_descriptor(), 391 ]), 392 ) 393 .unwrap(); 394 assert_eq!(len, 4); 395 396 let buf4 = slave.recv_data(2).unwrap(); 397 assert_eq!(buf4.len(), 2); 398 assert_eq!(&buf1[..2], &buf4[..]); 399 let (bytes, buf2, files) = slave.recv_into_buf(0x2).unwrap(); 400 assert_eq!(bytes, 2); 401 assert_eq!(&buf1[2..], &buf2[..]); 402 assert!(files.is_none()); 403 404 // Following communication pattern should work: 405 // Sending side: data, data with fds 406 // Receiving side: data, data with fds 407 let len = master.send_slice(IoSlice::new(&buf1[..]), None).unwrap(); 408 assert_eq!(len, 4); 409 let len = master 410 .send_slice( 411 IoSlice::new(&buf1[..]), 412 Some(&[ 413 fd.as_raw_descriptor(), 414 fd.as_raw_descriptor(), 415 fd.as_raw_descriptor(), 416 ]), 417 ) 418 .unwrap(); 419 assert_eq!(len, 4); 420 421 let (bytes, buf2, files) = slave.recv_into_buf(0x4).unwrap(); 422 assert_eq!(bytes, 4); 423 assert_eq!(&buf1[..], &buf2[..]); 424 assert!(files.is_none()); 425 426 let (bytes, buf2, files) = slave.recv_into_buf(0x2).unwrap(); 427 assert_eq!(bytes, 2); 428 assert_eq!(&buf1[..2], &buf2[..]); 429 assert!(files.is_some()); 430 let files = files.unwrap(); 431 { 432 assert_eq!(files.len(), 3); 433 let mut file = &files[1]; 434 let mut content = String::new(); 435 file.seek(SeekFrom::Start(0)).unwrap(); 436 file.read_to_string(&mut content).unwrap(); 437 assert_eq!(content, "test"); 438 } 439 let (bytes, buf2, files) = slave.recv_into_buf(0x2).unwrap(); 440 assert_eq!(bytes, 2); 441 assert_eq!(&buf1[2..], &buf2[..]); 442 assert!(files.is_none()); 443 444 // Following communication pattern should not work: 445 // Sending side: data1, data2 with fds 446 // Receiving side: data + partial of data2, left of data2 with fds 447 let len = master.send_slice(IoSlice::new(&buf1[..]), None).unwrap(); 448 assert_eq!(len, 4); 449 let len = master 450 .send_slice( 451 IoSlice::new(&buf1[..]), 452 Some(&[ 453 fd.as_raw_descriptor(), 454 fd.as_raw_descriptor(), 455 fd.as_raw_descriptor(), 456 ]), 457 ) 458 .unwrap(); 459 assert_eq!(len, 4); 460 461 let v = slave.recv_data(5).unwrap(); 462 assert_eq!(v.len(), 5); 463 464 let (bytes, _, files) = slave.recv_into_buf(0x4).unwrap(); 465 assert_eq!(bytes, 3); 466 assert!(files.is_none()); 467 468 // If the target fd array is too small, extra file descriptors will get lost. 469 let len = master 470 .send_slice( 471 IoSlice::new(&buf1[..]), 472 Some(&[ 473 fd.as_raw_descriptor(), 474 fd.as_raw_descriptor(), 475 fd.as_raw_descriptor(), 476 ]), 477 ) 478 .unwrap(); 479 assert_eq!(len, 4); 480 481 let (bytes, _, files) = slave.recv_into_buf(0x4).unwrap(); 482 assert_eq!(bytes, 4); 483 assert!(files.is_some()); 484 } 485 486 #[test] send_recv()487 fn send_recv() { 488 let dir = temp_dir(); 489 let mut path = dir.path().to_owned(); 490 path.push("sock"); 491 let mut listener = Listener::new(&path, true).unwrap(); 492 listener.set_nonblocking(true).unwrap(); 493 let mut master = Endpoint::<MasterReq>::connect(&path).unwrap(); 494 let mut slave = listener.accept().unwrap().unwrap(); 495 496 let mut hdr1 = 497 VhostUserMsgHeader::new(MasterReq::GET_FEATURES, 0, mem::size_of::<u64>() as u32); 498 hdr1.set_need_reply(true); 499 let features1 = 0x1u64; 500 master.send_message(&hdr1, &features1, None).unwrap(); 501 502 let mut features2 = 0u64; 503 let slice = unsafe { 504 slice::from_raw_parts_mut( 505 (&mut features2 as *mut u64) as *mut u8, 506 mem::size_of::<u64>(), 507 ) 508 }; 509 let (hdr2, bytes, files) = slave.recv_body_into_buf(slice).unwrap(); 510 assert_eq!(hdr1, hdr2); 511 assert_eq!(bytes, 8); 512 assert_eq!(features1, features2); 513 assert!(files.is_none()); 514 515 master.send_header(&hdr1, None).unwrap(); 516 let (hdr2, files) = slave.recv_header().unwrap(); 517 assert_eq!(hdr1, hdr2); 518 assert!(files.is_none()); 519 } 520 } 521