block: fix status value size

As per VirtIO spec 1.2 section 5.2.6, the `status` field is a byte, not
u32. cloud-hypervisor writes an `u32` to guest memory, which
accidentally zeros out the following 3 bytes, and may corrupt guest OS
internal state.

Signed-off-by: Changyuan Lyu <changyuanl@google.com>
This commit is contained in:
Changyuan Lyu 2024-07-12 22:54:12 -07:00 committed by Liu Wei
parent d89f1f4f21
commit bc6acb842f
3 changed files with 7 additions and 6 deletions

View File

@ -164,8 +164,8 @@ pub enum ExecuteError {
}
impl ExecuteError {
pub fn status(&self) -> u32 {
match *self {
pub fn status(&self) -> u8 {
let status = match *self {
ExecuteError::BadRequest(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Flush(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::Read(_) => VIRTIO_BLK_S_IOERR,
@ -180,7 +180,8 @@ impl ExecuteError {
ExecuteError::AsyncWrite(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::AsyncFlush(_) => VIRTIO_BLK_S_IOERR,
ExecuteError::TemporaryBufferAllocation(_) => VIRTIO_BLK_S_IOERR,
}
};
status as u8
}
}

View File

@ -148,7 +148,7 @@ impl VhostUserBlkThread {
) {
Ok(l) => {
len = l;
VIRTIO_BLK_S_OK
VIRTIO_BLK_S_OK as u8
}
Err(e) => {
len = 1;

View File

@ -215,7 +215,7 @@ impl BlockEpollHandler {
} else {
desc_chain
.memory()
.write_obj(VIRTIO_BLK_S_OK, request.status_addr)
.write_obj(VIRTIO_BLK_S_OK as u8, request.status_addr)
.map_err(Error::RequestStatus)?;
// If no asynchronous operation has been submitted, we can
@ -361,7 +361,7 @@ impl BlockEpollHandler {
.write_latency_avg
.store(write_avg, Ordering::Relaxed);
(VIRTIO_BLK_S_OK, result as u32)
(VIRTIO_BLK_S_OK as u8, result as u32)
} else {
error!(
"Request failed: {:x?} {:?}",