diff options
| author | Rasmus Melchior Jacobsen <[email protected]> | 2023-04-01 17:26:32 +0200 |
|---|---|---|
| committer | Rasmus Melchior Jacobsen <[email protected]> | 2023-04-01 17:26:32 +0200 |
| commit | e11eebfa577b143b8a19fcf6d9d5398c3058c3eb (patch) | |
| tree | 19ba9a751cd8d818aacf860a2f1a0df29d73483e | |
| parent | 268e29b153c9c8a6e3a798a01757669ee31e5409 (diff) | |
Ensure that ranges are validated with the region size
| -rw-r--r-- | embassy-stm32/src/flash/common.rs | 57 |
1 files changed, 22 insertions, 35 deletions
diff --git a/embassy-stm32/src/flash/common.rs b/embassy-stm32/src/flash/common.rs index 59429e344..287c54f55 100644 --- a/embassy-stm32/src/flash/common.rs +++ b/embassy-stm32/src/flash/common.rs | |||
| @@ -20,21 +20,15 @@ impl<'d> Flash<'d> { | |||
| 20 | } | 20 | } |
| 21 | 21 | ||
| 22 | pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { | 22 | pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { |
| 23 | let start_address = FLASH_BASE as u32 + offset; | 23 | blocking_read(FLASH_BASE as u32, FLASH_SIZE as u32, offset, bytes) |
| 24 | blocking_read(start_address, bytes) | ||
| 25 | } | 24 | } |
| 26 | 25 | ||
| 27 | pub fn blocking_write(&mut self, offset: u32, buf: &[u8]) -> Result<(), Error> { | 26 | pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> { |
| 28 | let start_address = FLASH_BASE as u32 + offset; | 27 | unsafe { blocking_write(FLASH_BASE as u32, FLASH_SIZE as u32, offset, bytes) } |
| 29 | |||
| 30 | unsafe { blocking_write(start_address, buf) } | ||
| 31 | } | 28 | } |
| 32 | 29 | ||
| 33 | pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> { | 30 | pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> { |
| 34 | let start_address = FLASH_BASE as u32 + from; | 31 | unsafe { blocking_erase(FLASH_BASE as u32, from, to) } |
| 35 | let end_address = FLASH_BASE as u32 + to; | ||
| 36 | |||
| 37 | unsafe { blocking_erase(start_address, end_address) } | ||
| 38 | } | 32 | } |
| 39 | 33 | ||
| 40 | pub(crate) fn release(self) -> PeripheralRef<'d, crate::peripherals::FLASH> { | 34 | pub(crate) fn release(self) -> PeripheralRef<'d, crate::peripherals::FLASH> { |
| @@ -55,30 +49,29 @@ impl Drop for FlashLayout<'_> { | |||
| 55 | } | 49 | } |
| 56 | } | 50 | } |
| 57 | 51 | ||
| 58 | fn blocking_read(start_address: u32, bytes: &mut [u8]) -> Result<(), Error> { | 52 | fn blocking_read(base: u32, size: u32, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { |
| 59 | assert!(start_address >= FLASH_BASE as u32); | 53 | if offset + bytes.len() as u32 > size { |
| 60 | if start_address as usize + bytes.len() > FLASH_BASE + FLASH_SIZE { | ||
| 61 | return Err(Error::Size); | 54 | return Err(Error::Size); |
| 62 | } | 55 | } |
| 63 | 56 | ||
| 57 | let start_address = base + offset; | ||
| 64 | let flash_data = unsafe { core::slice::from_raw_parts(start_address as *const u8, bytes.len()) }; | 58 | let flash_data = unsafe { core::slice::from_raw_parts(start_address as *const u8, bytes.len()) }; |
| 65 | bytes.copy_from_slice(flash_data); | 59 | bytes.copy_from_slice(flash_data); |
| 66 | Ok(()) | 60 | Ok(()) |
| 67 | } | 61 | } |
| 68 | 62 | ||
| 69 | unsafe fn blocking_write(start_address: u32, buf: &[u8]) -> Result<(), Error> { | 63 | unsafe fn blocking_write(base: u32, size: u32, offset: u32, bytes: &[u8]) -> Result<(), Error> { |
| 70 | assert!(start_address >= FLASH_BASE as u32); | 64 | if offset + bytes.len() as u32 > size { |
| 71 | if start_address as usize + buf.len() > FLASH_BASE + FLASH_SIZE { | ||
| 72 | return Err(Error::Size); | 65 | return Err(Error::Size); |
| 73 | } | 66 | } |
| 74 | if (start_address as usize - FLASH_BASE) % WRITE_SIZE != 0 || buf.len() as usize % WRITE_SIZE != 0 { | 67 | if offset % WRITE_SIZE as u32 != 0 || bytes.len() % WRITE_SIZE != 0 { |
| 75 | return Err(Error::Unaligned); | 68 | return Err(Error::Unaligned); |
| 76 | } | 69 | } |
| 77 | 70 | ||
| 78 | trace!("Writing {} bytes at 0x{:x}", buf.len(), start_address); | 71 | let mut address = base + offset; |
| 72 | trace!("Writing {} bytes at 0x{:x}", bytes.len(), address); | ||
| 79 | 73 | ||
| 80 | let mut address = start_address; | 74 | for chunk in bytes.chunks(WRITE_SIZE) { |
| 81 | for chunk in buf.chunks(WRITE_SIZE) { | ||
| 82 | critical_section::with(|_| { | 75 | critical_section::with(|_| { |
| 83 | family::clear_all_err(); | 76 | family::clear_all_err(); |
| 84 | family::unlock(); | 77 | family::unlock(); |
| @@ -94,7 +87,9 @@ unsafe fn blocking_write(start_address: u32, buf: &[u8]) -> Result<(), Error> { | |||
| 94 | Ok(()) | 87 | Ok(()) |
| 95 | } | 88 | } |
| 96 | 89 | ||
| 97 | unsafe fn blocking_erase(start_address: u32, end_address: u32) -> Result<(), Error> { | 90 | unsafe fn blocking_erase(base: u32, from: u32, to: u32) -> Result<(), Error> { |
| 91 | let start_address = base + from; | ||
| 92 | let end_address = base + to; | ||
| 98 | let regions = family::get_flash_regions(); | 93 | let regions = family::get_flash_regions(); |
| 99 | 94 | ||
| 100 | // Test if the address range is aligned at sector base addresses | 95 | // Test if the address range is aligned at sector base addresses |
| @@ -157,19 +152,15 @@ pub(crate) fn get_sector(address: u32, regions: &[&FlashRegion]) -> FlashSector | |||
| 157 | 152 | ||
| 158 | impl FlashRegion { | 153 | impl FlashRegion { |
| 159 | pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { | 154 | pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { |
| 160 | let start_address = self.base + offset; | 155 | blocking_read(self.base, self.size, offset, bytes) |
| 161 | blocking_read(start_address, bytes) | ||
| 162 | } | 156 | } |
| 163 | 157 | ||
| 164 | pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> { | 158 | pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> { |
| 165 | let start_address = self.base + offset; | 159 | unsafe { blocking_write(self.base, self.size, offset, bytes) } |
| 166 | unsafe { blocking_write(start_address, bytes) } | ||
| 167 | } | 160 | } |
| 168 | 161 | ||
| 169 | pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> { | 162 | pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> { |
| 170 | let start_address = self.base + from; | 163 | unsafe { blocking_erase(self.base, from, to) } |
| 171 | let end_address = self.base + to; | ||
| 172 | unsafe { blocking_erase(start_address, end_address) } | ||
| 173 | } | 164 | } |
| 174 | } | 165 | } |
| 175 | 166 | ||
| @@ -177,19 +168,15 @@ foreach_flash_region! { | |||
| 177 | ($type_name:ident, $write_size:literal, $erase_size:literal) => { | 168 | ($type_name:ident, $write_size:literal, $erase_size:literal) => { |
| 178 | impl crate::_generated::flash_regions::$type_name { | 169 | impl crate::_generated::flash_regions::$type_name { |
| 179 | pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { | 170 | pub fn blocking_read(&mut self, offset: u32, bytes: &mut [u8]) -> Result<(), Error> { |
| 180 | let start_address = self.0.base + offset; | 171 | blocking_read(self.0.base, self.0.size, offset, bytes) |
| 181 | blocking_read(start_address, bytes) | ||
| 182 | } | 172 | } |
| 183 | 173 | ||
| 184 | pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> { | 174 | pub fn blocking_write(&mut self, offset: u32, bytes: &[u8]) -> Result<(), Error> { |
| 185 | let start_address = self.0.base + offset; | 175 | unsafe { blocking_write(self.0.base, self.0.size, offset, bytes) } |
| 186 | unsafe { blocking_write(start_address, bytes) } | ||
| 187 | } | 176 | } |
| 188 | 177 | ||
| 189 | pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> { | 178 | pub fn blocking_erase(&mut self, from: u32, to: u32) -> Result<(), Error> { |
| 190 | let start_address = self.0.base + from; | 179 | unsafe { blocking_erase(self.0.base, from, to) } |
| 191 | let end_address = self.0.base + to; | ||
| 192 | unsafe { blocking_erase(start_address, end_address) } | ||
| 193 | } | 180 | } |
| 194 | } | 181 | } |
| 195 | 182 | ||
