From b360ab33d71bfafe4aed0e7094f11ae3adc69b8e Mon Sep 17 00:00:00 2001 From: sigil-03 Date: Wed, 14 Aug 2024 15:55:28 -0600 Subject: [PATCH] fix OOB read bug in read_mailbox NOTE: There was a bug with read_mailbox() where it would return all 8 bytes of the frame, even if only a few of them were valid. If these bytes crossed a word boundary (4 byte) - garbage data would be loaded from the mailbox into the data frame. For example, the can frame: 01#01 would cause the following output: `[0x1, 0x0, 0x0, 0x0, ?, ?, ?, ?]` Where `?` indicates an unknown value. --- src/common/can/mod.rs | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) diff --git a/src/common/can/mod.rs b/src/common/can/mod.rs index e11d5221..c29a36e3 100644 --- a/src/common/can/mod.rs +++ b/src/common/can/mod.rs @@ -850,6 +850,7 @@ impl CAN { } let code = self.read_mailbox_code(mailbox_number); + let cr = CodeReg::new(code); let c = FlexCanMailboxCSCode::from_code_reg(code); let mailbox_addr = self.mailbox_number_to_address(mailbox_number); @@ -859,14 +860,22 @@ impl CAN { c if c.is_tx_mailbox() => None, // full or overrun c if (c == FlexCanMailboxCSCode::RxFull) | (c == FlexCanMailboxCSCode::RxOverrun) => { + let dlc = cr.dlc(); let id = unsafe { core::ptr::read_volatile((mailbox_addr + 0x4_u32) as *const u32) }; let data0 = unsafe { core::ptr::read_volatile((mailbox_addr + 0x8_u32) as *const u32) }; - let data1 = - unsafe { core::ptr::read_volatile((mailbox_addr + 0xC_u32) as *const u32) }; + // Only valid if the DLC is > 4 + let data1 = { + if dlc > 4 { + unsafe { core::ptr::read_volatile((mailbox_addr + 0xC_u32) as *const u32) } + } else { + 0_u32 + } + }; let mut data: [u8; 8] = [0, 0, 0, 0, 0, 0, 0, 0]; + for i in 0..4 { data[3 - i] = (data0 >> (8 * i)) as u8; }