vsock: Compare packet src_cid with the configured guest CID

Cross-check the packet `src_cid` with the CID configured for the guest.
This will forbid a VM from impersonating another.

Signed-off-by: Priyansh Rathi <techiepriyansh@gmail.com>
This commit is contained in:
Priyansh Rathi 2023-06-26 15:54:16 +05:30 committed by Viresh Kumar
parent d6b953e958
commit 4346438bff
2 changed files with 23 additions and 1 deletions

View File

@ -59,6 +59,8 @@ pub(crate) struct VsockThreadBackend {
host_socket_path: String,
/// epoll for registering new host-side connections.
epoll_fd: i32,
/// CID of the guest.
guest_cid: u64,
/// Set of allocated local ports.
pub local_port_set: HashSet<u32>,
tx_buffer_size: u32,
@ -73,6 +75,7 @@ impl VsockThreadBackend {
pub fn new(
host_socket_path: String,
epoll_fd: i32,
guest_cid: u64,
tx_buffer_size: u32,
cid_map: Arc<RwLock<CidMap>>,
) -> Self {
@ -85,6 +88,7 @@ impl VsockThreadBackend {
stream_map: HashMap::new(),
host_socket_path,
epoll_fd,
guest_cid,
local_port_set: HashSet::new(),
tx_buffer_size,
cid_map,
@ -162,6 +166,14 @@ impl VsockThreadBackend {
/// Returns:
/// - always `Ok(())` if packet has been consumed correctly
pub fn send_pkt<B: BitmapSlice>(&mut self, pkt: &VsockPacket<B>) -> Result<()> {
if pkt.src_cid() != self.guest_cid {
warn!(
"vsock: dropping packet with inconsistent src_cid: {:?} from guest configured with CID: {:?}",
pkt.src_cid(), self.guest_cid
);
return Ok(());
}
let dst_cid = pkt.dst_cid();
if dst_cid != VSOCK_HOST_CID {
let cid_map = self.cid_map.read().unwrap();
@ -331,6 +343,7 @@ mod tests {
#[test]
#[serial]
fn test_vsock_thread_backend() {
const CID: u64 = 3;
const VSOCK_SOCKET_PATH: &str = "test_vsock_thread_backend.vsock";
const VSOCK_PEER_PORT: u32 = 1234;
const VSOCK_PEER_PATH: &str = "test_vsock_thread_backend.vsock_1234";
@ -345,6 +358,7 @@ mod tests {
let mut vtp = VsockThreadBackend::new(
VSOCK_SOCKET_PATH.to_string(),
epoll_fd,
CID,
CONN_TX_BUF_SIZE,
cid_map,
);
@ -367,6 +381,7 @@ mod tests {
packet.set_type(VSOCK_TYPE_STREAM);
assert!(vtp.send_pkt(&packet).is_ok());
packet.set_src_cid(CID);
packet.set_dst_cid(VSOCK_HOST_CID);
packet.set_dst_port(VSOCK_PEER_PORT);
assert!(vtp.send_pkt(&packet).is_ok());
@ -417,6 +432,7 @@ mod tests {
let mut vtp = VsockThreadBackend::new(
VSOCK_SOCKET_PATH.to_string(),
epoll_fd,
CID,
CONN_TX_BUF_SIZE,
cid_map,
);

View File

@ -100,7 +100,13 @@ impl VhostUserVsockThread {
host_listener: host_sock,
vring_worker: None,
epoll_file,
thread_backend: VsockThreadBackend::new(uds_path, epoll_fd, tx_buffer_size, cid_map),
thread_backend: VsockThreadBackend::new(
uds_path,
epoll_fd,
guest_cid,
tx_buffer_size,
cid_map,
),
guest_cid,
pool: ThreadPoolBuilder::new()
.pool_size(1)