diff options
author | Sergio Lopez <slp@redhat.com> | 2019-10-23 16:07:03 +0200 |
---|---|---|
committer | Andreea Florescu <andreea.florescu15@gmail.com> | 2020-09-04 17:59:53 +0300 |
commit | ead9be163d2fc0012b67b4328c5a3a0e41011ff7 (patch) | |
tree | cc444cf70fe9ce788ce6d2c9e793e944de34a7cd /src/vhost_user | |
parent | 0b38d99a64019222a88e296904345a3cf515c39d (diff) | |
download | vmm_vhost-ead9be163d2fc0012b67b4328c5a3a0e41011ff7.tar.gz |
vhost-user: fix VhostUserConfig payload management
The VhostUserConfig carries a message with a payload, the contents of
which depend on the kind of device being emulated.
With this change, we calculate the offset of the payload within the
message, check its size corresponds to the expected one, and pass it
to the backend as a reference to a slice adjusted to the payload
dimensions.
The backend will be responsible of validating the payload, as it's the
one aware of its expected contents.
Signed-off-by: Sergio Lopez <slp@redhat.com>
Diffstat (limited to 'src/vhost_user')
-rw-r--r-- | src/vhost_user/slave_req_handler.rs | 14 |
1 files changed, 9 insertions, 5 deletions
diff --git a/src/vhost_user/slave_req_handler.rs b/src/vhost_user/slave_req_handler.rs index 934c6d4..480689f 100644 --- a/src/vhost_user/slave_req_handler.rs +++ b/src/vhost_user/slave_req_handler.rs @@ -265,7 +265,6 @@ impl<S: VhostUserSlaveReqHandler> SlaveReqHandler<S> { if self.acked_protocol_features & VhostUserProtocolFeatures::CONFIG.bits() == 0 { return Err(Error::InvalidOperation); } - self.check_request_size(&hdr, size, mem::size_of::<VhostUserConfig>())?; self.get_config(&hdr, &buf)?; } MasterReq::SET_CONFIG => { @@ -341,6 +340,10 @@ impl<S: VhostUserSlaveReqHandler> SlaveReqHandler<S> { if !msg.is_valid() { return Err(Error::InvalidMessage); } + let payload_offset = mem::size_of::<VhostUserConfig>(); + if buf.len() - payload_offset != msg.size as usize { + return Err(Error::InvalidMessage); + } let flags = match VhostUserConfigFlags::from_bits(msg.flags) { Some(val) => val, None => return Err(Error::InvalidMessage), @@ -519,6 +522,7 @@ impl<S: VhostUserSlaveReqHandler> SlaveReqHandler<S> { fn new_reply_header<T: Sized>( &self, req: &VhostUserMsgHeader<MasterReq>, + payload_size: usize, ) -> Result<VhostUserMsgHeader<MasterReq>> { if mem::size_of::<T>() > MAX_MSG_SIZE { return Err(Error::InvalidParam); @@ -527,7 +531,7 @@ impl<S: VhostUserSlaveReqHandler> SlaveReqHandler<S> { Ok(VhostUserMsgHeader::new( req.get_code(), VhostUserHeaderFlag::REPLY.bits(), - mem::size_of::<T>() as u32, + (mem::size_of::<T>() + payload_size) as u32, )) } @@ -537,7 +541,7 @@ impl<S: VhostUserSlaveReqHandler> SlaveReqHandler<S> { res: Result<()>, ) -> Result<()> { if self.reply_ack_enabled { - let hdr = self.new_reply_header::<VhostUserU64>(req)?; + let hdr = self.new_reply_header::<VhostUserU64>(req, 0)?; let val = match res { Ok(_) => 0, Err(_) => 1, @@ -553,7 +557,7 @@ impl<S: VhostUserSlaveReqHandler> SlaveReqHandler<S> { req: &VhostUserMsgHeader<MasterReq>, msg: &T, ) -> Result<()> { - let hdr = self.new_reply_header::<T>(req)?; + let hdr = self.new_reply_header::<T>(req, 0)?; self.main_sock.send_message(&hdr, msg, None)?; Ok(()) } @@ -568,7 +572,7 @@ impl<S: VhostUserSlaveReqHandler> SlaveReqHandler<S> { T: Sized, P: Sized, { - let hdr = self.new_reply_header::<T>(req)?; + let hdr = self.new_reply_header::<T>(req, payload.len())?; self.main_sock .send_message_with_payload(&hdr, msg, payload, None)?; Ok(()) |