sound: fix invalid HandleUnknownEvent detection

Error event HandleUnknownEvent was not detected correctly, since we
first assume `device_event` is correct, use it as an index value to
access `vrings` slice, possible panic, and then match on the `queue_idx`
from the `vring`.

Signed-off-by: Manos Pitsidianakis <manos.pitsidianakis@linaro.org>
This commit is contained in:
Manos Pitsidianakis 2023-12-13 10:59:31 +02:00 committed by Manos Pitsidianakis
parent 83d5951a45
commit 6d81397eed
2 changed files with 17 additions and 5 deletions

View File

@ -91,7 +91,9 @@ impl VhostUserSoundThread {
vrings: &[VringRwLock],
audio_backend: &RwLock<Box<dyn AudioBackend + Send + Sync>>,
) -> IoResult<()> {
let vring = &vrings[device_event as usize];
let vring = &vrings
.get(device_event as usize)
.ok_or_else(|| Error::HandleUnknownEvent(device_event))?;
let queue_idx = self.queue_indexes[device_event as usize];
if self.event_idx {
// vm-virtio's Queue implementation only checks avail_index
@ -105,7 +107,7 @@ impl VhostUserSoundThread {
EVENT_QUEUE_IDX => self.process_event(vring),
TX_QUEUE_IDX => self.process_io(vring, audio_backend, Direction::Output),
RX_QUEUE_IDX => self.process_io(vring, audio_backend, Direction::Input),
_ => Err(Error::HandleUnknownEvent.into()),
_ => Err(Error::HandleUnknownEvent(queue_idx).into()),
}?;
if !vring.enable_notification().unwrap() {
break;
@ -118,7 +120,7 @@ impl VhostUserSoundThread {
EVENT_QUEUE_IDX => self.process_event(vring),
TX_QUEUE_IDX => self.process_io(vring, audio_backend, Direction::Output),
RX_QUEUE_IDX => self.process_io(vring, audio_backend, Direction::Input),
_ => Err(Error::HandleUnknownEvent.into()),
_ => Err(Error::HandleUnknownEvent(queue_idx).into()),
}?;
}
Ok(())
@ -1058,6 +1060,9 @@ mod tests {
backend
.handle_event(RX_QUEUE_IDX, EventSet::IN, &vrings, 0)
.unwrap();
backend
.handle_event(RX_QUEUE_IDX * 2, EventSet::IN, &vrings, 0)
.unwrap_err();
test_dir.close().unwrap();
}
@ -1116,6 +1121,13 @@ mod tests {
Error::HandleEventNotEpollIn.to_string()
);
// Unknown event.
let ret = backend.handle_event(RX_QUEUE_IDX * 2, EventSet::IN, &vrings, 0);
assert_eq!(
ret.unwrap_err().to_string(),
Error::HandleUnknownEvent(RX_QUEUE_IDX * 2).to_string()
);
test_dir.close().unwrap();
}
}

View File

@ -106,8 +106,8 @@ pub enum Error {
DescriptorWriteFailed,
#[error("Failed to handle event other than EPOLLIN event")]
HandleEventNotEpollIn,
#[error("Failed to handle unknown event")]
HandleUnknownEvent,
#[error("Failed to handle unknown event with id {0}")]
HandleUnknownEvent(u16),
#[error("Invalid control message code {0}")]
InvalidControlMessage(u32),
#[error("Invalid value in {0}: {1}")]