From 7554d06ff4dbf3c4d7e5c6ac7cb02f83387eac27 Mon Sep 17 00:00:00 2001 From: Alyssa Ross Date: Sat, 8 Jun 2024 14:20:45 +0100 Subject: [PATCH] vhost_user: ignore unknown features from backend virtiofsd 1.11.0 added support for VHOST_USER_PROTOCOL_F_DEVICE_STATE. Upgrading virtiofsd meant that the latest released version of Cloud Hypervisor (39.0) was no longer able to communicate with it, because rather than just ignoring the unsupported feature, it got an unrecoverable "invalid message" error. This demonstrates that it's better for frontends to just ignore offers of unsupported features. If the backend requires some feature, it'll get a chance to know that when we send VHOST_USER_SET_PROTOCOL_FEATURES anyway. Signed-off-by: Alyssa Ross --- vhost/CHANGELOG.md | 1 + vhost/src/vhost_user/frontend.rs | 14 +++++++------- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/vhost/CHANGELOG.md b/vhost/CHANGELOG.md index f92973bb..c0aa5815 100644 --- a/vhost/CHANGELOG.md +++ b/vhost/CHANGELOG.md @@ -5,6 +5,7 @@ - [[#241]](/~https://github.com/rust-vmm/vhost/pull/241) Add shared objects support ### Changed +- [[#243]](/~https://github.com/rust-vmm/vhost/pull/243) Ignore unknown bits in `VHOST_USER_GET_PROTOCOL_FEATURES` response. ### Remove - [[#246]](/~https://github.com/rust-vmm/vhost/pull/246) Remove support for FS_* requests diff --git a/vhost/src/vhost_user/frontend.rs b/vhost/src/vhost_user/frontend.rs index 8f625ead..1b58187a 100644 --- a/vhost/src/vhost_user/frontend.rs +++ b/vhost/src/vhost_user/frontend.rs @@ -362,12 +362,9 @@ impl VhostUserFrontend for Frontend { let hdr = node.send_request_header(FrontendReq::GET_PROTOCOL_FEATURES, None)?; let val = node.recv_reply::(&hdr)?; node.protocol_features = val.value; - // Should we support forward compatibility? - // If so just mask out unrecognized flags instead of return errors. - match VhostUserProtocolFeatures::from_bits(node.protocol_features) { - Some(val) => Ok(val), - None => error_code(VhostUserError::InvalidMessage), - } + Ok(VhostUserProtocolFeatures::from_bits_truncate( + node.protocol_features, + )) } fn set_protocol_features(&mut self, features: VhostUserProtocolFeatures) -> Result<()> { @@ -811,6 +808,8 @@ mod tests { use std::path::PathBuf; + const INVALID_PROTOCOL_FEATURE: u64 = 1 << 63; + fn temp_path() -> PathBuf { PathBuf::from(format!( "/tmp/vhost_test_{}", @@ -935,7 +934,8 @@ mod tests { let pfeatures = VhostUserProtocolFeatures::all(); let hdr = VhostUserMsgHeader::new(FrontendReq::GET_PROTOCOL_FEATURES, 0x4, 8); - let msg = VhostUserU64::new(pfeatures.bits()); + // Unknown feature bits should be ignored. + let msg = VhostUserU64::new(pfeatures.bits() | INVALID_PROTOCOL_FEATURE); peer.send_message(&hdr, &msg, None).unwrap(); let features = frontend.get_protocol_features().unwrap(); assert_eq!(features, pfeatures);