summary refs log tree commit diff
path: root/msg_socket
diff options
context:
space:
mode:
authorZach Reizner <zachr@google.com>2019-02-13 17:33:32 -0800
committerchrome-bot <chrome-bot@chromium.org>2019-02-28 03:24:24 -0800
commita60744b42ee2589e9318029cf3fd7d87fd73f29d (patch)
tree4819c7b24caab92956d95474e638eb067a5ce926 /msg_socket
parentb7196e2a1c1eb7123e7eace5418b7eb4a3e24dbe (diff)
downloadcrosvm-a60744b42ee2589e9318029cf3fd7d87fd73f29d.tar
crosvm-a60744b42ee2589e9318029cf3fd7d87fd73f29d.tar.gz
crosvm-a60744b42ee2589e9318029cf3fd7d87fd73f29d.tar.bz2
crosvm-a60744b42ee2589e9318029cf3fd7d87fd73f29d.tar.lz
crosvm-a60744b42ee2589e9318029cf3fd7d87fd73f29d.tar.xz
crosvm-a60744b42ee2589e9318029cf3fd7d87fd73f29d.tar.zst
crosvm-a60744b42ee2589e9318029cf3fd7d87fd73f29d.zip
crosvm: use seqpacket rather than datagram sockets
The advantage of seqpacket is that they are connection oriented. A
listener can be created that accepts new connections, useful for the
path based VM control sockets. Previously, the only bidirectional
sockets in crosvm were either stream based or made using socketpair.

This change also whitelists sendmsg and recvmsg for the common device
policy.

TEST=cargo test
BUG=chromium:848187

Change-Id: I83fd46f54bce105a7730632cd013b5e7047db22b
Reviewed-on: https://chromium-review.googlesource.com/1470917
Commit-Ready: Zach Reizner <zachr@chromium.org>
Tested-by: kokoro <noreply+kokoro@google.com>
Tested-by: Zach Reizner <zachr@chromium.org>
Reviewed-by: Daniel Verkamp <dverkamp@chromium.org>
Diffstat (limited to 'msg_socket')
-rw-r--r--msg_socket/src/lib.rs77
-rw-r--r--msg_socket/src/msg_on_socket.rs10
2 files changed, 34 insertions, 53 deletions
diff --git a/msg_socket/src/lib.rs b/msg_socket/src/lib.rs
index cc2cdc9..fd1f2bc 100644
--- a/msg_socket/src/lib.rs
+++ b/msg_socket/src/lib.rs
@@ -13,9 +13,9 @@ mod msg_on_socket;
 
 use std::io::Result;
 use std::marker::PhantomData;
+use std::ops::Deref;
 use std::os::unix::io::{AsRawFd, RawFd};
-use std::os::unix::net::UnixDatagram;
-use sys_util::{Error as SysError, ScmSocket, UnlinkUnixDatagram};
+use sys_util::{net::UnixSeqpacket, Error as SysError, ScmSocket};
 
 pub use msg_on_socket::*;
 pub use msg_on_socket_derive::*;
@@ -24,7 +24,7 @@ pub use msg_on_socket_derive::*;
 /// direction.
 pub fn pair<Request: MsgOnSocket, Response: MsgOnSocket>(
 ) -> Result<(MsgSocket<Request, Response>, MsgSocket<Response, Request>)> {
-    let (sock1, sock2) = UnixDatagram::pair()?;
+    let (sock1, sock2) = UnixSeqpacket::pair()?;
     let requester = MsgSocket {
         sock: sock1,
         _i: PhantomData,
@@ -40,14 +40,14 @@ pub fn pair<Request: MsgOnSocket, Response: MsgOnSocket>(
 
 /// Bidirection sock that support both send and recv.
 pub struct MsgSocket<I: MsgOnSocket, O: MsgOnSocket> {
-    sock: UnixDatagram,
+    sock: UnixSeqpacket,
     _i: PhantomData<I>,
     _o: PhantomData<O>,
 }
 
 impl<I: MsgOnSocket, O: MsgOnSocket> MsgSocket<I, O> {
     // Create a new MsgSocket.
-    pub fn new(s: UnixDatagram) -> MsgSocket<I, O> {
+    pub fn new(s: UnixSeqpacket) -> MsgSocket<I, O> {
         MsgSocket {
             sock: s,
             _i: PhantomData,
@@ -56,33 +56,22 @@ impl<I: MsgOnSocket, O: MsgOnSocket> MsgSocket<I, O> {
     }
 }
 
-/// Bidirection sock that support both send and recv.
-pub struct UnlinkMsgSocket<I: MsgOnSocket, O: MsgOnSocket> {
-    sock: UnlinkUnixDatagram,
-    _i: PhantomData<I>,
-    _o: PhantomData<O>,
-}
-
-impl<I: MsgOnSocket, O: MsgOnSocket> UnlinkMsgSocket<I, O> {
-    // Create a new MsgSocket.
-    pub fn new(s: UnlinkUnixDatagram) -> UnlinkMsgSocket<I, O> {
-        UnlinkMsgSocket {
-            sock: s,
-            _i: PhantomData,
-            _o: PhantomData,
-        }
+impl<I: MsgOnSocket, O: MsgOnSocket> Deref for MsgSocket<I, O> {
+    type Target = UnixSeqpacket;
+    fn deref(&self) -> &Self::Target {
+        &self.sock
     }
 }
 
 /// One direction socket that only supports sending.
 pub struct Sender<M: MsgOnSocket> {
-    sock: UnixDatagram,
+    sock: UnixSeqpacket,
     _m: PhantomData<M>,
 }
 
 impl<M: MsgOnSocket> Sender<M> {
     /// Create a new sender sock.
-    pub fn new(s: UnixDatagram) -> Sender<M> {
+    pub fn new(s: UnixSeqpacket) -> Sender<M> {
         Sender {
             sock: s,
             _m: PhantomData,
@@ -92,13 +81,13 @@ impl<M: MsgOnSocket> Sender<M> {
 
 /// One direction socket that only supports receiving.
 pub struct Receiver<M: MsgOnSocket> {
-    sock: UnixDatagram,
+    sock: UnixSeqpacket,
     _m: PhantomData<M>,
 }
 
 impl<M: MsgOnSocket> Receiver<M> {
     /// Create a new receiver sock.
-    pub fn new(s: UnixDatagram) -> Receiver<M> {
+    pub fn new(s: UnixSeqpacket) -> Receiver<M> {
         Receiver {
             sock: s,
             _m: PhantomData,
@@ -106,8 +95,8 @@ impl<M: MsgOnSocket> Receiver<M> {
     }
 }
 
-impl<I: MsgOnSocket, O: MsgOnSocket> AsRef<UnixDatagram> for MsgSocket<I, O> {
-    fn as_ref(&self) -> &UnixDatagram {
+impl<I: MsgOnSocket, O: MsgOnSocket> AsRef<UnixSeqpacket> for MsgSocket<I, O> {
+    fn as_ref(&self) -> &UnixSeqpacket {
         &self.sock
     }
 }
@@ -118,20 +107,8 @@ impl<I: MsgOnSocket, O: MsgOnSocket> AsRawFd for MsgSocket<I, O> {
     }
 }
 
-impl<I: MsgOnSocket, O: MsgOnSocket> AsRef<UnixDatagram> for UnlinkMsgSocket<I, O> {
-    fn as_ref(&self) -> &UnixDatagram {
-        self.sock.as_ref()
-    }
-}
-
-impl<I: MsgOnSocket, O: MsgOnSocket> AsRawFd for UnlinkMsgSocket<I, O> {
-    fn as_raw_fd(&self) -> RawFd {
-        self.as_ref().as_raw_fd()
-    }
-}
-
-impl<M: MsgOnSocket> AsRef<UnixDatagram> for Sender<M> {
-    fn as_ref(&self) -> &UnixDatagram {
+impl<M: MsgOnSocket> AsRef<UnixSeqpacket> for Sender<M> {
+    fn as_ref(&self) -> &UnixSeqpacket {
         &self.sock
     }
 }
@@ -142,8 +119,8 @@ impl<M: MsgOnSocket> AsRawFd for Sender<M> {
     }
 }
 
-impl<M: MsgOnSocket> AsRef<UnixDatagram> for Receiver<M> {
-    fn as_ref(&self) -> &UnixDatagram {
+impl<M: MsgOnSocket> AsRef<UnixSeqpacket> for Receiver<M> {
+    fn as_ref(&self) -> &UnixSeqpacket {
         &self.sock
     }
 }
@@ -155,7 +132,7 @@ impl<M: MsgOnSocket> AsRawFd for Receiver<M> {
 }
 
 /// Types that could send a message.
-pub trait MsgSender<M: MsgOnSocket>: AsRef<UnixDatagram> {
+pub trait MsgSender<M: MsgOnSocket>: AsRef<UnixSeqpacket> {
     fn send(&self, msg: &M) -> MsgResult<()> {
         let msg_size = M::msg_size();
         let fd_size = M::max_fd_count();
@@ -163,7 +140,7 @@ pub trait MsgSender<M: MsgOnSocket>: AsRef<UnixDatagram> {
         let mut fd_buffer: Vec<RawFd> = vec![0; fd_size];
 
         let fd_size = msg.write_to_buffer(&mut msg_buffer, &mut fd_buffer)?;
-        let sock: &UnixDatagram = self.as_ref();
+        let sock: &UnixSeqpacket = self.as_ref();
         if fd_size == 0 {
             handle_eintr!(sock.send(&msg_buffer))
                 .map_err(|e| MsgError::Send(SysError::new(e.raw_os_error().unwrap_or(0))))?;
@@ -176,14 +153,14 @@ pub trait MsgSender<M: MsgOnSocket>: AsRef<UnixDatagram> {
 }
 
 /// Types that could receive a message.
-pub trait MsgReceiver<M: MsgOnSocket>: AsRef<UnixDatagram> {
+pub trait MsgReceiver<M: MsgOnSocket>: AsRef<UnixSeqpacket> {
     fn recv(&self) -> MsgResult<M> {
         let msg_size = M::msg_size();
         let fd_size = M::max_fd_count();
         let mut msg_buffer: Vec<u8> = vec![0; msg_size];
         let mut fd_buffer: Vec<RawFd> = vec![0; fd_size];
 
-        let sock: &UnixDatagram = self.as_ref();
+        let sock: &UnixSeqpacket = self.as_ref();
 
         let (recv_msg_size, recv_fd_size) = {
             if fd_size == 0 {
@@ -197,7 +174,10 @@ pub trait MsgReceiver<M: MsgOnSocket>: AsRef<UnixDatagram> {
             }
         };
         if msg_size != recv_msg_size {
-            return Err(MsgError::BadRecvSize(msg_size));
+            return Err(MsgError::BadRecvSize {
+                expected: msg_size,
+                actual: recv_msg_size,
+            });
         }
         // Safe because fd buffer is read from socket.
         let (v, read_fd_size) = unsafe {
@@ -213,8 +193,5 @@ pub trait MsgReceiver<M: MsgOnSocket>: AsRef<UnixDatagram> {
 impl<I: MsgOnSocket, O: MsgOnSocket> MsgSender<I> for MsgSocket<I, O> {}
 impl<I: MsgOnSocket, O: MsgOnSocket> MsgReceiver<O> for MsgSocket<I, O> {}
 
-impl<I: MsgOnSocket, O: MsgOnSocket> MsgSender<I> for UnlinkMsgSocket<I, O> {}
-impl<I: MsgOnSocket, O: MsgOnSocket> MsgReceiver<O> for UnlinkMsgSocket<I, O> {}
-
 impl<M: MsgOnSocket> MsgSender<M> for Sender<M> {}
 impl<M: MsgOnSocket> MsgReceiver<M> for Receiver<M> {}
diff --git a/msg_socket/src/msg_on_socket.rs b/msg_socket/src/msg_on_socket.rs
index 493c57c..8b01850 100644
--- a/msg_socket/src/msg_on_socket.rs
+++ b/msg_socket/src/msg_on_socket.rs
@@ -23,8 +23,8 @@ pub enum MsgError {
     /// The type of a received request or response is unknown.
     InvalidType,
     /// There was not the expected amount of data when receiving a message. The inner
-    /// value is how much data is needed.
-    BadRecvSize(usize),
+    /// value is how much data is expected and how much data was actually received.
+    BadRecvSize { expected: usize, actual: usize },
     /// There was no associated file descriptor received for a request that expected it.
     ExpectFd,
     /// There was some associated file descriptor received but not used when deserialize.
@@ -47,7 +47,11 @@ impl Display for MsgError {
             Send(e) => write!(f, "failed to send request or response: {}", e),
             Recv(e) => write!(f, "failed to receive request or response: {}", e),
             InvalidType => write!(f, "invalid type"),
-            BadRecvSize(n) => write!(f, "wrong amount of data received; expected {} bytes", n),
+            BadRecvSize { expected, actual } => write!(
+                f,
+                "wrong amount of data received; expected {} bytes; got {} bytes",
+                expected, actual
+            ),
             ExpectFd => write!(f, "missing associated file descriptor for request"),
             NotExpectFd => write!(f, "unexpected file descriptor is unused"),
             WrongFdBufferSize => write!(f, "fd buffer size too small"),