diff --git a/vhost/CHANGELOG.md b/vhost/CHANGELOG.md index 4867f17..f72ae24 100644 --- a/vhost/CHANGELOG.md +++ b/vhost/CHANGELOG.md @@ -8,6 +8,7 @@ ### Changed ### Deprecated ### Fixed +- [[#338]](https://github.com/rust-vmm/vhost/pull/338) vhost: fix double-locking in Backend to Frontend request handlers ## v0.15.0 diff --git a/vhost/src/vhost_user/backend_req.rs b/vhost/src/vhost_user/backend_req.rs index 02efeee..3b28bcf 100644 --- a/vhost/src/vhost_user/backend_req.rs +++ b/vhost/src/vhost_user/backend_req.rs @@ -107,19 +107,6 @@ impl Backend { } } - fn send_message( - &self, - request: BackendReq, - body: &T, - fds: Option<&[RawFd]>, - ) -> io::Result { - Ok(self - .inner - .lock() - .unwrap() - .send_message(request, body, fds)?) - } - /// Create a new instance from a `UnixStream` object. pub fn from_stream(sock: UnixStream) -> Self { Self::new(Endpoint::>::from_stream( @@ -161,18 +148,20 @@ impl Backend { impl VhostUserFrontendReqHandler for Backend { /// Forward vhost-user shared-object add request to the frontend. fn shared_object_add(&self, uuid: &VhostUserSharedMsg) -> HandlerResult { - if !self.inner.lock().unwrap().shared_object_negotiated { + let mut guard = self.inner.lock().unwrap(); + if !guard.shared_object_negotiated { return Err(io::Error::other("Shared Object feature not negotiated")); } - self.send_message(BackendReq::SHARED_OBJECT_ADD, uuid, None) + Ok(guard.send_message(BackendReq::SHARED_OBJECT_ADD, uuid, None)?) } /// Forward vhost-user shared-object remove request to the frontend. fn shared_object_remove(&self, uuid: &VhostUserSharedMsg) -> HandlerResult { - if !self.inner.lock().unwrap().shared_object_negotiated { + let mut guard = self.inner.lock().unwrap(); + if !guard.shared_object_negotiated { return Err(io::Error::other("Shared Object feature not negotiated")); } - self.send_message(BackendReq::SHARED_OBJECT_REMOVE, uuid, None) + Ok(guard.send_message(BackendReq::SHARED_OBJECT_REMOVE, uuid, None)?) } /// Forward vhost-user shared-object lookup request to the frontend. @@ -181,30 +170,33 @@ impl VhostUserFrontendReqHandler for Backend { uuid: &VhostUserSharedMsg, fd: &dyn AsRawFd, ) -> HandlerResult { - if !self.inner.lock().unwrap().shared_object_negotiated { + let mut guard = self.inner.lock().unwrap(); + if !guard.shared_object_negotiated { return Err(io::Error::other("Shared Object feature not negotiated")); } - self.send_message( + Ok(guard.send_message( BackendReq::SHARED_OBJECT_LOOKUP, uuid, Some(&[fd.as_raw_fd()]), - ) + )?) } /// Forward vhost-user memory map file request to the frontend. fn shmem_map(&self, req: &VhostUserMMap, fd: &dyn AsRawFd) -> HandlerResult { - if !self.inner.lock().unwrap().shmem_negotiated { + let mut guard = self.inner.lock().unwrap(); + if !guard.shmem_negotiated { return Err(io::Error::other("SHMEM feature not negotiated")); } - self.send_message(BackendReq::SHMEM_MAP, req, Some(&[fd.as_raw_fd()])) + Ok(guard.send_message(BackendReq::SHMEM_MAP, req, Some(&[fd.as_raw_fd()]))?) } /// Forward vhost-user memory unmap file request to the frontend. fn shmem_unmap(&self, req: &VhostUserMMap) -> HandlerResult { - if !self.inner.lock().unwrap().shmem_negotiated { + let mut guard = self.inner.lock().unwrap(); + if !guard.shmem_negotiated { return Err(io::Error::other("SHMEM feature not negotiated")); } - self.send_message(BackendReq::SHMEM_UNMAP, req, None) + Ok(guard.send_message(BackendReq::SHMEM_UNMAP, req, None)?) } }