vsock: Don't allow duplicate CIDs

Currently, while updating the `cid_map`, it is not checked if the map
already contained a key with the same CID before. So, fail to create the
vsock thread if the CID is already in use.

Signed-off-by: Priyansh Rathi <techiepriyansh@gmail.com>
This commit is contained in:
Priyansh Rathi 2023-09-11 20:37:45 -07:00 committed by Viresh Kumar
parent a3fc80b269
commit 38caab24c5
2 changed files with 35 additions and 11 deletions

View File

@ -135,6 +135,8 @@ pub(crate) enum Error {
EventFdCreate(std::io::Error), EventFdCreate(std::io::Error),
#[error("Raw vsock packets queue is empty")] #[error("Raw vsock packets queue is empty")]
EmptyRawPktsQueue, EmptyRawPktsQueue,
#[error("CID already in use by another vsock device")]
CidAlreadyInUse,
} }
impl std::convert::From<Error> for std::io::Error { impl std::convert::From<Error> for std::io::Error {

View File

@ -111,14 +111,21 @@ impl VhostUserVsockThread {
cid_map.clone(), cid_map.clone(),
); );
cid_map.write().unwrap().insert( {
guest_cid, let mut cid_map = cid_map.write().unwrap();
( if cid_map.contains_key(&guest_cid) {
thread_backend.raw_pkts_queue.clone(), return Err(Error::CidAlreadyInUse);
groups_set, }
sibling_event_fd.try_clone().unwrap(),
), cid_map.insert(
); guest_cid,
(
thread_backend.raw_pkts_queue.clone(),
groups_set,
sibling_event_fd.try_clone().unwrap(),
),
);
}
let thread = VhostUserVsockThread { let thread = VhostUserVsockThread {
mem: None, mem: None,
@ -824,9 +831,14 @@ mod tests {
.join("test_vsock_thread_failures.vsock") .join("test_vsock_thread_failures.vsock")
.display() .display()
.to_string(); .to_string();
let mut t = let mut t = VhostUserVsockThread::new(
VhostUserVsockThread::new(vsock_socket_path, 3, CONN_TX_BUF_SIZE, groups, cid_map) vsock_socket_path,
.unwrap(); 3,
CONN_TX_BUF_SIZE,
groups.clone(),
cid_map.clone(),
)
.unwrap();
assert!(VhostUserVsockThread::epoll_register(-1, -1, epoll::Events::EPOLLIN).is_err()); assert!(VhostUserVsockThread::epoll_register(-1, -1, epoll::Events::EPOLLIN).is_err());
assert!(VhostUserVsockThread::epoll_modify(-1, -1, epoll::Events::EPOLLIN).is_err()); assert!(VhostUserVsockThread::epoll_modify(-1, -1, epoll::Events::EPOLLIN).is_err());
assert!(VhostUserVsockThread::epoll_unregister(-1, -1).is_err()); assert!(VhostUserVsockThread::epoll_unregister(-1, -1).is_err());
@ -848,6 +860,16 @@ mod tests {
assert!(t.process_rx(&vring, false).is_err()); assert!(t.process_rx(&vring, false).is_err());
assert!(t.process_rx(&vring, true).is_err()); assert!(t.process_rx(&vring, true).is_err());
// trying to use a CID that is already in use should fail
let vsock_socket_path2 = test_dir
.path()
.join("test_vsock_thread_failures2.vsock")
.display()
.to_string();
let t2 =
VhostUserVsockThread::new(vsock_socket_path2, 3, CONN_TX_BUF_SIZE, groups, cid_map);
assert!(t2.is_err());
test_dir.close().unwrap(); test_dir.close().unwrap();
} }
} }