tpm: Add recv timeout while running recvmsg

If swtpm becomes unresponsive, guest gets blocked at "recvmsg" on tpm's
data FD. This change adds a timeout to the data fd socket. If swtpm
becomes unresponsive guest waits for "timeout" (secs) and continues to
run after returning an I/O error to tpm commands.

Signed-off-by: Praveen K Paladugu <prapal@linux.microsoft.com>
This commit is contained in:
Praveen K Paladugu 2023-01-31 17:45:02 +00:00 committed by Rob Bradford
parent 934b20a77a
commit 1143d54ee0
4 changed files with 24 additions and 0 deletions

1
Cargo.lock generated
View File

@ -1292,6 +1292,7 @@ dependencies = [
"byteorder",
"libc",
"log",
"net_gen",
"thiserror",
"vmm-sys-util",
]

View File

@ -10,5 +10,6 @@ anyhow = "1.0.66"
byteorder = "1.4.3"
libc = "0.2.138"
log = "0.4.17"
net_gen = { path = "../net_gen" }
thiserror = "1.0.37"
vmm-sys-util = "0.11.0"

View File

@ -143,6 +143,27 @@ impl Emulator {
self.run_control_cmd(Commands::CmdSetDatafd, &mut res, 0, mem::size_of::<u32>())?;
debug!("data fd in cloud-hypervisor = {:?}", fds[0]);
self.data_fd = fds[0];
// SAFETY: FFI calls and return value of the unsafe call is checked
unsafe {
let tv = net_gen::iff::timeval {
tv_sec: 0,
tv_usec: 100000, // Set recv timeout to 100ms
};
let ret = net_gen::setsockopt(
fds[0],
net_gen::iff::SOL_SOCKET as i32,
net_gen::iff::SO_RCVTIMEO as i32,
&tv as *const _ as *const libc::c_void,
std::mem::size_of::<net_gen::iff::timeval>() as u32,
);
if ret == -1 {
return Err(Error::PrepareDataFd(anyhow!(
"Failed to set receive timeout on data fd socket. Error Code {:?}",
std::io::Error::last_os_error()
)));
}
}
self.control_socket.set_datafd(fds[0]);
Ok(())
}

View File

@ -584,6 +584,7 @@ fn vmm_thread_rules(
(libc::SYS_sendto, vec![]),
(libc::SYS_set_robust_list, vec![]),
(libc::SYS_setsid, vec![]),
(libc::SYS_setsockopt, vec![]),
(libc::SYS_shutdown, vec![]),
(libc::SYS_sigaltstack, vec![]),
(