aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMattias Grönlund <[email protected]>2022-08-09 00:53:32 +0200
committerDario Nieuwenhuis <[email protected]>2022-08-13 15:25:34 +0200
commit3388b5cecf95d6b0bc9cf5c952e9f0aa1e019b8a (patch)
tree1c6f65c26f8b64620195b4a9fb7d708d076c341b
parentddfbfa0132285963382a4d7290d506186da31369 (diff)
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.
-rw-r--r--src/events.rs1
-rw-r--r--src/lib.rs53
-rw-r--r--src/structs.rs56
3 files changed, 99 insertions, 11 deletions
diff --git a/src/events.rs b/src/events.rs
index b35b12faa..a828eec98 100644
--- a/src/events.rs
+++ b/src/events.rs
@@ -1,4 +1,5 @@
1#![allow(unused)] 1#![allow(unused)]
2#![allow(non_camel_case_types)]
2 3
3use core::num; 4use core::num;
4 5
diff --git a/src/lib.rs b/src/lib.rs
index 133ce3161..3d08370c7 100644
--- a/src/lib.rs
+++ b/src/lib.rs
@@ -815,20 +815,55 @@ where
815 trace!(" {:?}", bcd_header); 815 trace!(" {:?}", bcd_header);
816 816
817 let packet_start = BcdHeader::SIZE + 4 * bcd_header.data_offset as usize; 817 let packet_start = BcdHeader::SIZE + 4 * bcd_header.data_offset as usize;
818 if packet_start > payload.len() { 818
819 warn!("packet start out of range."); 819 if packet_start + EventPacket::SIZE > payload.len() {
820 warn!("BCD event, incomplete header");
821 return;
822 }
823 let bcd_packet = &payload[packet_start..];
824 trace!(" {:02x}", &bcd_packet[..(bcd_packet.len() as usize).min(36)]);
825
826 let mut event_packet = EventPacket::from_bytes(&bcd_packet[..EventPacket::SIZE].try_into().unwrap());
827 event_packet.byteswap();
828
829 const ETH_P_LINK_CTL: u16 = 0x886c; // HPNA, wlan link local tunnel, according to linux if_ether.h
830 if event_packet.eth.ether_type != ETH_P_LINK_CTL {
831 warn!(
832 "unexpected ethernet type 0x{:04x}, expected Broadcom ether type 0x{:04x}",
833 event_packet.eth.ether_type, ETH_P_LINK_CTL
834 );
835 return;
836 }
837 const BROADCOM_OUI: &[u8] = &[0x00, 0x10, 0x18];
838 if event_packet.hdr.oui != BROADCOM_OUI {
839 warn!(
840 "unexpected ethernet OUI {:02x}, expected Broadcom OUI {:02x}",
841 event_packet.hdr.oui, BROADCOM_OUI
842 );
843 return;
844 }
845 const BCMILCP_SUBTYPE_VENDOR_LONG: u16 = 32769;
846 if event_packet.hdr.subtype != BCMILCP_SUBTYPE_VENDOR_LONG {
847 warn!("unexpected subtype {}", event_packet.hdr.subtype);
848 return;
849 }
850
851 const BCMILCP_BCM_SUBTYPE_EVENT: u16 = 1;
852 if event_packet.hdr.user_subtype != BCMILCP_BCM_SUBTYPE_EVENT {
853 warn!("unexpected user_subtype {}", event_packet.hdr.subtype);
854 return;
855 }
856
857 if event_packet.msg.datalen as usize >= (bcd_packet.len() - EventMessage::SIZE) {
858 warn!("BCD event, incomplete data");
820 return; 859 return;
821 } 860 }
822 let packet = &payload[packet_start..];
823 trace!(" {:02x}", &packet[..(packet.len() as usize).min(36)]);
824 861
825 let mut evt = EventHeader::from_bytes(&packet[24..][..EventHeader::SIZE].try_into().unwrap()); 862 let evt_data = &bcd_packet[EventMessage::SIZE..][..event_packet.msg.datalen as usize];
826 evt.byteswap();
827 let evt_data = &packet[24 + EventHeader::SIZE..][..evt.datalen as usize];
828 debug!( 863 debug!(
829 "=== EVENT {}: {} {:02x}", 864 "=== EVENT {}: {} {:02x}",
830 events::Event::from(evt.event_type as u8), 865 events::Event::from(event_packet.msg.event_type as u8),
831 evt, 866 event_packet.msg,
832 evt_data 867 evt_data
833 ); 868 );
834 } 869 }
diff --git a/src/structs.rs b/src/structs.rs
index 060c2b060..7a7c25b26 100644
--- a/src/structs.rs
+++ b/src/structs.rs
@@ -67,7 +67,41 @@ impl_bytes!(BcdHeader);
67#[derive(Clone, Copy)] 67#[derive(Clone, Copy)]
68#[cfg_attr(feature = "defmt", derive(defmt::Format))] 68#[cfg_attr(feature = "defmt", derive(defmt::Format))]
69#[repr(C)] 69#[repr(C)]
70pub struct EthernetHeader {
71 pub destination_mac: [u8; 6],
72 pub source_mac: [u8; 6],
73 pub ether_type: u16,
74}
75
76impl EthernetHeader {
77 pub fn byteswap(&mut self) {
78 self.ether_type = self.ether_type.to_be();
79 }
80}
81
82#[derive(Clone, Copy)]
83#[cfg_attr(feature = "defmt", derive(defmt::Format))]
84#[repr(C)]
70pub struct EventHeader { 85pub struct EventHeader {
86 pub subtype: u16,
87 pub length: u16,
88 pub version: u8,
89 pub oui: [u8; 3],
90 pub user_subtype: u16,
91}
92
93impl EventHeader {
94 pub fn byteswap(&mut self) {
95 self.subtype = self.subtype.to_be();
96 self.length = self.length.to_be();
97 self.user_subtype = self.user_subtype.to_be();
98 }
99}
100
101#[derive(Clone, Copy)]
102#[cfg_attr(feature = "defmt", derive(defmt::Format))]
103#[repr(C)]
104pub struct EventMessage {
71 /// version 105 /// version
72 pub version: u16, 106 pub version: u16,
73 /// see flags below 107 /// see flags below
@@ -91,9 +125,9 @@ pub struct EventHeader {
91 /// source bsscfg index 125 /// source bsscfg index
92 pub bsscfgidx: u8, 126 pub bsscfgidx: u8,
93} 127}
94impl_bytes!(EventHeader); 128impl_bytes!(EventMessage);
95 129
96impl EventHeader { 130impl EventMessage {
97 pub fn byteswap(&mut self) { 131 pub fn byteswap(&mut self) {
98 self.version = self.version.to_be(); 132 self.version = self.version.to_be();
99 self.flags = self.flags.to_be(); 133 self.flags = self.flags.to_be();
@@ -106,6 +140,24 @@ impl EventHeader {
106} 140}
107 141
108#[derive(Clone, Copy)] 142#[derive(Clone, Copy)]
143#[cfg_attr(feature = "defmt", derive(defmt::Format))]
144#[repr(C)]
145pub struct EventPacket {
146 pub eth: EthernetHeader,
147 pub hdr: EventHeader,
148 pub msg: EventMessage,
149}
150impl_bytes!(EventPacket);
151
152impl EventPacket {
153 pub fn byteswap(&mut self) {
154 self.eth.byteswap();
155 self.hdr.byteswap();
156 self.msg.byteswap();
157 }
158}
159
160#[derive(Clone, Copy)]
109#[repr(C)] 161#[repr(C)]
110pub struct DownloadHeader { 162pub struct DownloadHeader {
111 pub flag: u16, // 163 pub flag: u16, //