mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2026-08-05 02:19:16 +00:00
tpm: drop cmd from Emulator struct
The command is not done asynchronously. And there is no way to propagate this error anywhere. Signed-off-by: Wei Liu <liuwe@microsoft.com>
This commit is contained in:
@@ -72,7 +72,6 @@ pub struct BackendCmd {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct Emulator {
|
pub struct Emulator {
|
||||||
cmd: Option<BackendCmd>,
|
|
||||||
caps: PtmCap, /* capabilities of the TPM */
|
caps: PtmCap, /* capabilities of the TPM */
|
||||||
control_socket: SocketDev,
|
control_socket: SocketDev,
|
||||||
data_fd: RawFd,
|
data_fd: RawFd,
|
||||||
@@ -100,7 +99,6 @@ impl Emulator {
|
|||||||
})?;
|
})?;
|
||||||
|
|
||||||
let mut emulator = Self {
|
let mut emulator = Self {
|
||||||
cmd: None,
|
|
||||||
caps: 0,
|
caps: 0,
|
||||||
control_socket: socket,
|
control_socket: socket,
|
||||||
data_fd: -1,
|
data_fd: -1,
|
||||||
@@ -287,109 +285,94 @@ impl Emulator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Function to write to data socket and read the response from it
|
/// Function to write to data socket and read the response from it
|
||||||
fn unix_tx_bufs(&mut self) -> Result<()> {
|
fn unix_tx_bufs(&mut self, cmd: &mut BackendCmd) -> Result<()> {
|
||||||
let isselftest: bool;
|
let isselftest: bool;
|
||||||
// SAFETY: type "sockaddr_storage" is valid with an all-zero byte-pattern value
|
// SAFETY: type "sockaddr_storage" is valid with an all-zero byte-pattern value
|
||||||
let mut addr: sockaddr_storage = unsafe { mem::zeroed() };
|
let mut addr: sockaddr_storage = unsafe { mem::zeroed() };
|
||||||
let mut len = mem::size_of::<sockaddr_storage>() as socklen_t;
|
let mut len = mem::size_of::<sockaddr_storage>() as socklen_t;
|
||||||
|
|
||||||
if let Some(ref mut cmd) = self.cmd {
|
cmd.selftest_done = false;
|
||||||
cmd.selftest_done = false;
|
isselftest = is_selftest(cmd.input.to_vec(), cmd.input_len);
|
||||||
isselftest = is_selftest(cmd.input.to_vec(), cmd.input_len);
|
|
||||||
|
|
||||||
debug!(
|
debug!(
|
||||||
"Send cmd: {:02X?} of len {:?} on data_ioc ",
|
"Send cmd: {:02X?} of len {:?} on data_ioc ",
|
||||||
cmd.input, cmd.input_len
|
cmd.input, cmd.input_len
|
||||||
|
);
|
||||||
|
|
||||||
|
let data_vecs = [libc::iovec {
|
||||||
|
iov_base: cmd.input.as_mut_ptr() as *mut libc::c_void,
|
||||||
|
iov_len: cmd.input.len(),
|
||||||
|
}; 1];
|
||||||
|
|
||||||
|
// SAFETY: all zero values from the unsafe method are updated before usage
|
||||||
|
let mut msghdr: libc::msghdr = unsafe { mem::zeroed() };
|
||||||
|
msghdr.msg_name = ptr::null_mut();
|
||||||
|
msghdr.msg_namelen = 0;
|
||||||
|
msghdr.msg_iov = data_vecs.as_ptr() as *mut libc::iovec;
|
||||||
|
msghdr.msg_iovlen = data_vecs.len() as _;
|
||||||
|
msghdr.msg_control = ptr::null_mut();
|
||||||
|
msghdr.msg_controllen = 0;
|
||||||
|
msghdr.msg_flags = 0;
|
||||||
|
// SAFETY: FFI call and the return value of the unsafe method is checked
|
||||||
|
unsafe {
|
||||||
|
let ret = libc::sendmsg(self.data_fd, &msghdr, 0);
|
||||||
|
if ret == -1 {
|
||||||
|
return Err(Error::SendReceive(anyhow!(
|
||||||
|
"Failed to send tpm command over Data FD. Error Code {:?}",
|
||||||
|
std::io::Error::last_os_error()
|
||||||
|
)));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
cmd.output.fill(0);
|
||||||
|
// SAFETY: FFI calls and return value from unsafe method is checked
|
||||||
|
unsafe {
|
||||||
|
let ret = libc::recvfrom(
|
||||||
|
self.data_fd,
|
||||||
|
cmd.output.as_ptr() as *mut c_void,
|
||||||
|
cmd.output.len(),
|
||||||
|
0,
|
||||||
|
&mut addr as *mut libc::sockaddr_storage as *mut libc::sockaddr,
|
||||||
|
&mut len as *mut socklen_t,
|
||||||
);
|
);
|
||||||
|
if ret == -1 {
|
||||||
let data_vecs = [libc::iovec {
|
return Err(Error::SendReceive(anyhow!(
|
||||||
iov_base: cmd.input.as_mut_ptr() as *mut libc::c_void,
|
"Failed to receive response for tpm command over Data FD. Error Code {:?}",
|
||||||
iov_len: cmd.input.len(),
|
std::io::Error::last_os_error()
|
||||||
}; 1];
|
)));
|
||||||
|
|
||||||
// SAFETY: all zero values from the unsafe method are updated before usage
|
|
||||||
let mut msghdr: libc::msghdr = unsafe { mem::zeroed() };
|
|
||||||
msghdr.msg_name = ptr::null_mut();
|
|
||||||
msghdr.msg_namelen = 0;
|
|
||||||
msghdr.msg_iov = data_vecs.as_ptr() as *mut libc::iovec;
|
|
||||||
msghdr.msg_iovlen = data_vecs.len() as _;
|
|
||||||
msghdr.msg_control = ptr::null_mut();
|
|
||||||
msghdr.msg_controllen = 0;
|
|
||||||
msghdr.msg_flags = 0;
|
|
||||||
// SAFETY: FFI call and the return value of the unsafe method is checked
|
|
||||||
unsafe {
|
|
||||||
let ret = libc::sendmsg(self.data_fd, &msghdr, 0);
|
|
||||||
if ret == -1 {
|
|
||||||
return Err(Error::SendReceive(anyhow!(
|
|
||||||
"Failed to send tpm command over Data FD. Error Code {:?}",
|
|
||||||
std::io::Error::last_os_error()
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
cmd.output_len = ret as usize;
|
||||||
|
}
|
||||||
|
debug!(
|
||||||
|
"response = {:02X?} len = {:?} selftest = {:?}",
|
||||||
|
cmd.output, cmd.output_len, isselftest
|
||||||
|
);
|
||||||
|
|
||||||
cmd.output.fill(0);
|
if isselftest {
|
||||||
// SAFETY: FFI calls and return value from unsafe method is checked
|
if cmd.output_len < 10 {
|
||||||
unsafe {
|
return Err(Error::SelfTest(anyhow!(
|
||||||
let ret = libc::recvfrom(
|
"Self test response should have 10 bytes. Only {:?} returned",
|
||||||
self.data_fd,
|
cmd.output_len
|
||||||
cmd.output.as_ptr() as *mut c_void,
|
)));
|
||||||
cmd.output.len(),
|
|
||||||
0,
|
|
||||||
&mut addr as *mut libc::sockaddr_storage as *mut libc::sockaddr,
|
|
||||||
&mut len as *mut socklen_t,
|
|
||||||
);
|
|
||||||
if ret == -1 {
|
|
||||||
return Err(Error::SendReceive(anyhow!(
|
|
||||||
"Failed to receive response for tpm command over Data FD. Error Code {:?}",
|
|
||||||
std::io::Error::last_os_error()
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
cmd.output_len = ret as usize;
|
|
||||||
}
|
|
||||||
debug!(
|
|
||||||
"response = {:02X?} len = {:?} selftest = {:?}",
|
|
||||||
cmd.output, cmd.output_len, isselftest
|
|
||||||
);
|
|
||||||
|
|
||||||
if isselftest {
|
|
||||||
if cmd.output_len < 10 {
|
|
||||||
return Err(Error::SelfTest(anyhow!(
|
|
||||||
"Self test response should have 10 bytes. Only {:?} returned",
|
|
||||||
cmd.output_len
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
let mut errcode: [u8; 4] = [0; 4];
|
|
||||||
errcode.copy_from_slice(&cmd.output[6..6 + 4]);
|
|
||||||
cmd.selftest_done = u32::from_ne_bytes(errcode).to_be() == 0;
|
|
||||||
}
|
}
|
||||||
|
let mut errcode: [u8; 4] = [0; 4];
|
||||||
|
errcode.copy_from_slice(&cmd.output[6..6 + 4]);
|
||||||
|
cmd.selftest_done = u32::from_ne_bytes(errcode).to_be() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn deliver_request(&mut self, in_cmd: &mut BackendCmd) -> Result<Vec<u8>> {
|
pub fn deliver_request(&mut self, cmd: &mut BackendCmd) -> Result<Vec<u8>> {
|
||||||
if self.cmd.is_some() {
|
self.unix_tx_bufs(cmd)?;
|
||||||
//previous request did not finish cleanly
|
|
||||||
return Err(Error::DeliverRequest(anyhow!(
|
|
||||||
"Cannot deliver tpm Request as previous cmd did not complete."
|
|
||||||
)));
|
|
||||||
}
|
|
||||||
self.cmd = Some(in_cmd.clone());
|
|
||||||
|
|
||||||
self.unix_tx_bufs()?;
|
let output = cmd.output.clone();
|
||||||
|
cmd.output.fill(0);
|
||||||
|
cmd.output.clone_from(&output);
|
||||||
|
|
||||||
let output = self.cmd.as_ref().unwrap().output.clone();
|
|
||||||
in_cmd.output.fill(0);
|
|
||||||
in_cmd.output.clone_from(&output);
|
|
||||||
|
|
||||||
self.backend_request_completed();
|
|
||||||
Ok(output)
|
Ok(output)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn backend_request_completed(&mut self) {
|
|
||||||
self.cmd = None;
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn cancel_cmd(&mut self) -> Result<()> {
|
pub fn cancel_cmd(&mut self) -> Result<()> {
|
||||||
let mut res: PtmResult = 0;
|
let mut res: PtmResult = 0;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user