diff --git a/esp-ieee802154/CHANGELOG.md b/esp-ieee802154/CHANGELOG.md index 390b351dd12..48aa0fa47e5 100644 --- a/esp-ieee802154/CHANGELOG.md +++ b/esp-ieee802154/CHANGELOG.md @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 ### Added +- Added additional checks to prevent various array access panics while processing frames - Added range check to avoid panic when indexing into RX_BUFFER slice ### Changed diff --git a/esp-ieee802154/src/frame.rs b/esp-ieee802154/src/frame.rs index 756b1763d0c..d855777648c 100644 --- a/esp-ieee802154/src/frame.rs +++ b/esp-ieee802154/src/frame.rs @@ -37,9 +37,15 @@ pub struct ReceivedFrame { } pub(crate) fn frame_is_ack_required(frame: &[u8]) -> bool { + if frame.len() <= FRAME_AR_OFFSET { + return false; + } (frame[FRAME_AR_OFFSET] & FRAME_AR_BIT) != 0 } pub(crate) fn frame_get_version(frame: &[u8]) -> u8 { + if frame.len() <= FRAME_VERSION_OFFSET { + return 0; + } frame[FRAME_VERSION_OFFSET] & FRAME_VERSION_MASK } diff --git a/esp-ieee802154/src/lib.rs b/esp-ieee802154/src/lib.rs index b4f1d7bb27e..90d05c4590e 100644 --- a/esp-ieee802154/src/lib.rs +++ b/esp-ieee802154/src/lib.rs @@ -159,12 +159,21 @@ impl<'a> Ieee802154<'a> { /// Get a received frame, if available pub fn get_received(&mut self) -> Option> { if let Some(raw) = ieee802154_poll() { - let maybe_decoded = - mac::Frame::try_read(&raw.data[1..][..raw.data[0] as usize], FooterMode::Explicit); + let maybe_decoded = if raw.data[0] as usize > raw.data.len() { + // try to decode up to data.len() + mac::Frame::try_read(&raw.data[1..][..raw.data.len()], FooterMode::Explicit) + } else { + mac::Frame::try_read(&raw.data[1..][..raw.data[0] as usize], FooterMode::Explicit) + }; let result = match maybe_decoded { Ok((decoded, _)) => { - let rssi = raw.data[raw.data[0] as usize - 1] as i8; // crc is not written to rx buffer + // crc is not written to rx buffer + let rssi = if raw.data[0] as usize > raw.data.len() { + raw.data[raw.data.len() - 1] as i8 + } else { + raw.data[raw.data[0] as usize - 1] as i8 + }; Ok(ReceivedFrame { frame: Frame { diff --git a/esp-ieee802154/src/raw.rs b/esp-ieee802154/src/raw.rs index 93d7dedbcaa..ebea31c54a5 100644 --- a/esp-ieee802154/src/raw.rs +++ b/esp-ieee802154/src/raw.rs @@ -19,13 +19,17 @@ use esp_wifi_sys::include::{ use heapless::spsc::Queue; use crate::{ - frame::{frame_get_version, frame_is_ack_required, FRAME_VERSION_1, FRAME_VERSION_2}, + frame::{ + frame_get_version, + frame_is_ack_required, + FRAME_SIZE, + FRAME_VERSION_1, + FRAME_VERSION_2, + }, hal::*, pib::*, }; -pub(crate) const FRAME_SIZE: usize = 129; - const PHY_ENABLE_VERSION_PRINT: u32 = 1; static mut RX_BUFFER: [u8; FRAME_SIZE] = [0u8; FRAME_SIZE]; @@ -391,9 +395,9 @@ fn ZB_MAC() { log::warn!("Receive queue full"); } - let frm = if RX_BUFFER[0] > FRAME_SIZE as u8 { + let frm = if RX_BUFFER[0] >= FRAME_SIZE as u8 { log::warn!("RX_BUFFER[0] {:} is larger than frame size", RX_BUFFER[0]); - &RX_BUFFER[1..][..FRAME_SIZE] + &RX_BUFFER[1..][..FRAME_SIZE - 1] } else { &RX_BUFFER[1..][..RX_BUFFER[0] as usize] };