From 6d81397eed302d75c56f1b46791befcc1290837f Mon Sep 17 00:00:00 2001 From: Manos Pitsidianakis Date: Wed, 13 Dec 2023 10:59:31 +0200 Subject: [PATCH] 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 --- staging/vhost-device-sound/src/device.rs | 18 +++++++++++++++--- staging/vhost-device-sound/src/lib.rs | 4 ++-- 2 files changed, 17 insertions(+), 5 deletions(-) diff --git a/staging/vhost-device-sound/src/device.rs b/staging/vhost-device-sound/src/device.rs index c31567a..4bd9ea2 100644 --- a/staging/vhost-device-sound/src/device.rs +++ b/staging/vhost-device-sound/src/device.rs @@ -91,7 +91,9 @@ impl VhostUserSoundThread { vrings: &[VringRwLock], audio_backend: &RwLock>, ) -> 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(); } } diff --git a/staging/vhost-device-sound/src/lib.rs b/staging/vhost-device-sound/src/lib.rs index 50cd753..438ba38 100644 --- a/staging/vhost-device-sound/src/lib.rs +++ b/staging/vhost-device-sound/src/lib.rs @@ -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}")]