{"record":{"id":"b6a19995954c2c72","repo":"embassy-rs/embassy","slug":"failed-to-read-volume","errorCode":null,"errorMessage":"Failed to read volume.","messagePattern":"Failed to read volume\\.","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"embassy-usb/src/class/uac1/speaker.rs","lineNumber":521,"sourceCode":"                audio_settings.muted[channel_index as usize] = mute_state;\n            }\n            _ => {\n                debug!(\"Failed to set channel {} mute state: {}\", channel_index, mute_state);\n                return OutResponse::Rejected;\n            }\n        }\n\n        debug!(\"Set channel {} mute state: {}\", channel_index, mute_state);\n        OutResponse::Accepted\n    }\n\n    fn interface_set_volume(\n        &mut self,\n        audio_settings: &mut AudioSettings,\n        channel_index: u8,\n        data: &[u8],\n    ) -> OutResponse {\n        let volume = i16::from_ne_bytes(data[..2].try_into().expect(\"Failed to read volume.\"));\n\n        match channel_index as usize {\n            ..=MAX_AUDIO_CHANNEL_INDEX => {\n                audio_settings.volume_8q8_db[channel_index as usize] = volume;\n            }\n            _ => {\n                debug!(\"Failed to set channel {} volume: {}\", channel_index, volume);\n                return OutResponse::Rejected;\n            }\n        }\n\n        debug!(\"Set channel {} volume: {}\", channel_index, volume);\n        OutResponse::Accepted\n    }\n\n    fn interface_set_request(&mut self, req: control::Request, data: &[u8]) -> Option<OutResponse> {\n        let interface_number = req.index as u8;\n        let entity_index = (req.index >> 8) as u8;","sourceCodeStart":503,"sourceCodeEnd":539,"githubUrl":"https://github.com/embassy-rs/embassy/blob/463a07b963419a1bfe61d5d597c44acb810afb8b/embassy-usb/src/class/uac1/speaker.rs#L503-L539","documentation":"UAC1 speaker volume-set handling parses the host's volume payload with `i16::from_ne_bytes(data[..2])` and expects the conversion to succeed. The host sent a SET_CUR(VOLUME) control request whose data is shorter than 2 bytes, so the slice-to-array conversion fails. This is a malformed or truncated control transfer payload.","triggerScenarios":"Host issues SET_CUR on the volume control with `data.len() < 2` (empty or 1-byte wValue payload), then `interface_set_volume` panics slicing `data[..2]`.","commonSituations":"Non-conformant USB audio hosts/drivers sending malformed SET_CUR requests; test tools (e.g. custom control scripts) issuing volume requests with wrong wLength; OS drivers sending per-channel requests with unexpected payload framing.","solutions":["Guard the length before parsing: if `data.len() < 2`, return `OutResponse::Rejected` instead of slicing","Use `data.first_chunk::<2>()` and handle None by rejecting the request","Check the descriptor's volume control sizes match what the host expects (b SUBFRAME / feature-unit wMaxClaimed settings) so hosts send 2-byte payloads"],"exampleFix":"// before\nlet volume = i16::from_ne_bytes(data[..2].try_into().expect(\"Failed to read volume.\"));\n// after\nlet volume = match data.first_chunk::<2>() {\n    Some(b) => i16::from_ne_bytes(*b),\n    None => return OutResponse::Rejected,\n};","handlingStrategy":"validation","validationCode":"if data.len() < 2 { return OutResponse::Rejected; }\nlet volume = i16::from_ne_bytes(data[..2].try_into().unwrap());","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Never slice fixed-size windows out of host-supplied control data without length checks","Return Rejected/Stall for malformed control requests instead of panicking","Validate that descriptor-declared control sizes match the parser's expectations","Test with control transfer fuzzing or short-payload SET_CUR requests"],"tags":["rust","embedded","usb","audio","malformed-payload"],"backgroundTag":"invalid-argument-format","analyzedSha":"463a07b963419a1bfe61d5d597c44acb810afb8b","analyzedAt":"2026-09-10T13:38:26.660Z","contentChangedAt":"2026-09-10T13:38:26.660Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}