Skip to content

Commit

Permalink
vsock: Fail to parse VsockArgs if duplicate CIDs specified
Browse files Browse the repository at this point in the history
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 parse
VsockArgs if there exist multiple VMs configured with the same CID.

Signed-off-by: Priyansh Rathi <techiepriyansh@gmail.com>
  • Loading branch information
techiepriyansh committed Aug 30, 2023
1 parent 9926e75 commit 9f9a7a7
Showing 1 changed file with 37 additions and 3 deletions.
40 changes: 37 additions & 3 deletions crates/vsock/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ mod vhu_vsock_thread;
mod vsock_conn;

use std::{
collections::HashMap,
collections::{HashMap, HashSet},
convert::TryFrom,
process::exit,
sync::{Arc, RwLock},
Expand All @@ -35,6 +35,8 @@ enum CliError {
NoArgsProvided,
#[error("Failed to parse configuration file")]
ConfigParse,
#[error("Multiple VMs configured with the same CID: {0}")]
DuplicateCids(u64),
}

#[derive(Debug, ThisError)]
Expand Down Expand Up @@ -194,8 +196,8 @@ impl TryFrom<VsockArgs> for Vec<VsockConfig> {
type Error = CliError;

fn try_from(cmd_args: VsockArgs) -> Result<Self, CliError> {
// we try to use the configuration first, if failed, then fall back to the manual settings.
match cmd_args.parse_config() {
let configs = match cmd_args.parse_config() {
// we try to use the configuration first, if failed, then fall back to the manual settings.
Some(c) => c,
_ => match cmd_args.vm {
Some(v) => Ok(v),
Expand All @@ -209,7 +211,18 @@ impl TryFrom<VsockArgs> for Vec<VsockConfig> {
)])
}),
},
}?;

// check if there are duplicate CIDs
let mut cid_set: HashSet<u64> = HashSet::new();
for c in &configs {
let cid = c.get_guest_cid();
if !cid_set.insert(cid) {
return Err(CliError::DuplicateCids(cid));
}
}

Ok(configs)
}
}

Expand Down Expand Up @@ -432,6 +445,27 @@ mod tests {
vec!["group2".to_string(), "group3".to_string()]
);

// Test parse failure with duplicate CIDs
let params = format!(
"--vm socket={vhost3_socket},uds_path={vm3_vsock} \
--vm socket={vhost4_socket},uds-path={vm4_vsock},guest-cid=3,tx_buffer_size=65536,groups=group1 \
--vm groups=group2+group3,guest-cid=5,socket={vhost5_socket},uds_path={vm5_vsock},tx-buffer-size=32768",
vhost3_socket = socket_paths[0].display(),
vhost4_socket = socket_paths[1].display(),
vhost5_socket = socket_paths[2].display(),
vm3_vsock = uds_paths[0].display(),
vm4_vsock = uds_paths[1].display(),
vm5_vsock = uds_paths[2].display(),
);

let mut params = params.split_whitespace().collect::<Vec<&str>>();
params.insert(0, "");

let args = VsockArgs::parse_from(params);

let configs = Vec::<VsockConfig>::try_from(args);
assert!(configs.is_err());

test_dir.close().unwrap();
}

Expand Down

0 comments on commit 9f9a7a7

Please sign in to comment.