Improve data checks for VHD events
For some reason I got strange events on channel 1 (ASYNCEVENT_HEADER): 0.647329 WARN unexpected ehternet type 0x0508, expected Qualcom ether type 0x886c This patch improves the validation of BCD WHD events to minimize the risk for panic.
This commit is contained in:
parent
ddfbfa0132
commit
3388b5cecf
@ -1,4 +1,5 @@
|
||||
#![allow(unused)]
|
||||
#![allow(non_camel_case_types)]
|
||||
|
||||
use core::num;
|
||||
|
||||
|
53
src/lib.rs
53
src/lib.rs
@ -815,20 +815,55 @@ where
|
||||
trace!(" {:?}", bcd_header);
|
||||
|
||||
let packet_start = BcdHeader::SIZE + 4 * bcd_header.data_offset as usize;
|
||||
if packet_start > payload.len() {
|
||||
warn!("packet start out of range.");
|
||||
|
||||
if packet_start + EventPacket::SIZE > payload.len() {
|
||||
warn!("BCD event, incomplete header");
|
||||
return;
|
||||
}
|
||||
let packet = &payload[packet_start..];
|
||||
trace!(" {:02x}", &packet[..(packet.len() as usize).min(36)]);
|
||||
let bcd_packet = &payload[packet_start..];
|
||||
trace!(" {:02x}", &bcd_packet[..(bcd_packet.len() as usize).min(36)]);
|
||||
|
||||
let mut evt = EventHeader::from_bytes(&packet[24..][..EventHeader::SIZE].try_into().unwrap());
|
||||
evt.byteswap();
|
||||
let evt_data = &packet[24 + EventHeader::SIZE..][..evt.datalen as usize];
|
||||
let mut event_packet = EventPacket::from_bytes(&bcd_packet[..EventPacket::SIZE].try_into().unwrap());
|
||||
event_packet.byteswap();
|
||||
|
||||
const ETH_P_LINK_CTL: u16 = 0x886c; // HPNA, wlan link local tunnel, according to linux if_ether.h
|
||||
if event_packet.eth.ether_type != ETH_P_LINK_CTL {
|
||||
warn!(
|
||||
"unexpected ethernet type 0x{:04x}, expected Broadcom ether type 0x{:04x}",
|
||||
event_packet.eth.ether_type, ETH_P_LINK_CTL
|
||||
);
|
||||
return;
|
||||
}
|
||||
const BROADCOM_OUI: &[u8] = &[0x00, 0x10, 0x18];
|
||||
if event_packet.hdr.oui != BROADCOM_OUI {
|
||||
warn!(
|
||||
"unexpected ethernet OUI {:02x}, expected Broadcom OUI {:02x}",
|
||||
event_packet.hdr.oui, BROADCOM_OUI
|
||||
);
|
||||
return;
|
||||
}
|
||||
const BCMILCP_SUBTYPE_VENDOR_LONG: u16 = 32769;
|
||||
if event_packet.hdr.subtype != BCMILCP_SUBTYPE_VENDOR_LONG {
|
||||
warn!("unexpected subtype {}", event_packet.hdr.subtype);
|
||||
return;
|
||||
}
|
||||
|
||||
const BCMILCP_BCM_SUBTYPE_EVENT: u16 = 1;
|
||||
if event_packet.hdr.user_subtype != BCMILCP_BCM_SUBTYPE_EVENT {
|
||||
warn!("unexpected user_subtype {}", event_packet.hdr.subtype);
|
||||
return;
|
||||
}
|
||||
|
||||
if event_packet.msg.datalen as usize >= (bcd_packet.len() - EventMessage::SIZE) {
|
||||
warn!("BCD event, incomplete data");
|
||||
return;
|
||||
}
|
||||
|
||||
let evt_data = &bcd_packet[EventMessage::SIZE..][..event_packet.msg.datalen as usize];
|
||||
debug!(
|
||||
"=== EVENT {}: {} {:02x}",
|
||||
events::Event::from(evt.event_type as u8),
|
||||
evt,
|
||||
events::Event::from(event_packet.msg.event_type as u8),
|
||||
event_packet.msg,
|
||||
evt_data
|
||||
);
|
||||
}
|
||||
|
@ -64,10 +64,44 @@ pub struct BcdHeader {
|
||||
}
|
||||
impl_bytes!(BcdHeader);
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
#[repr(C)]
|
||||
pub struct EthernetHeader {
|
||||
pub destination_mac: [u8; 6],
|
||||
pub source_mac: [u8; 6],
|
||||
pub ether_type: u16,
|
||||
}
|
||||
|
||||
impl EthernetHeader {
|
||||
pub fn byteswap(&mut self) {
|
||||
self.ether_type = self.ether_type.to_be();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
#[repr(C)]
|
||||
pub struct EventHeader {
|
||||
pub subtype: u16,
|
||||
pub length: u16,
|
||||
pub version: u8,
|
||||
pub oui: [u8; 3],
|
||||
pub user_subtype: u16,
|
||||
}
|
||||
|
||||
impl EventHeader {
|
||||
pub fn byteswap(&mut self) {
|
||||
self.subtype = self.subtype.to_be();
|
||||
self.length = self.length.to_be();
|
||||
self.user_subtype = self.user_subtype.to_be();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
#[repr(C)]
|
||||
pub struct EventMessage {
|
||||
/// version
|
||||
pub version: u16,
|
||||
/// see flags below
|
||||
@ -91,9 +125,9 @@ pub struct EventHeader {
|
||||
/// source bsscfg index
|
||||
pub bsscfgidx: u8,
|
||||
}
|
||||
impl_bytes!(EventHeader);
|
||||
impl_bytes!(EventMessage);
|
||||
|
||||
impl EventHeader {
|
||||
impl EventMessage {
|
||||
pub fn byteswap(&mut self) {
|
||||
self.version = self.version.to_be();
|
||||
self.flags = self.flags.to_be();
|
||||
@ -105,6 +139,24 @@ impl EventHeader {
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[cfg_attr(feature = "defmt", derive(defmt::Format))]
|
||||
#[repr(C)]
|
||||
pub struct EventPacket {
|
||||
pub eth: EthernetHeader,
|
||||
pub hdr: EventHeader,
|
||||
pub msg: EventMessage,
|
||||
}
|
||||
impl_bytes!(EventPacket);
|
||||
|
||||
impl EventPacket {
|
||||
pub fn byteswap(&mut self) {
|
||||
self.eth.byteswap();
|
||||
self.hdr.byteswap();
|
||||
self.msg.byteswap();
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone, Copy)]
|
||||
#[repr(C)]
|
||||
pub struct DownloadHeader {
|
||||
|
Loading…
Reference in New Issue
Block a user