From ba6d9c1a971db3c42bf0b054ebb64f72b3e3ddba Mon Sep 17 00:00:00 2001 From: Dean Camera Date: Mon, 22 Jan 2018 16:14:44 +1100 Subject: Fixed bootloaders accepting flash writes to the bootloader region (thanks to NicoHood). --- Bootloaders/CDC/BootloaderAPI.c | 15 +++++++++++++++ Bootloaders/DFU/BootloaderAPI.c | 15 +++++++++++++++ Bootloaders/HID/BootloaderHID.c | 6 +++++- Bootloaders/MassStorage/BootloaderAPI.c | 15 +++++++++++++++ Bootloaders/Printer/BootloaderAPI.c | 15 +++++++++++++++ LUFA/DoxygenPages/ChangeLog.txt | 1 + 6 files changed, 66 insertions(+), 1 deletion(-) diff --git a/Bootloaders/CDC/BootloaderAPI.c b/Bootloaders/CDC/BootloaderAPI.c index 5e8083ed3..c1e76d3bd 100644 --- a/Bootloaders/CDC/BootloaderAPI.c +++ b/Bootloaders/CDC/BootloaderAPI.c @@ -35,8 +35,20 @@ #include "BootloaderAPI.h" +static bool IsPageAddressValid(const uint32_t Address) +{ + /* Determine if the given page address is correctly aligned to the + start of a flash page. */ + bool PageAddressIsAligned = !(Address & (SPM_PAGESIZE - 1)); + + return (Address < BOOT_START_ADDR) && PageAddressIsAligned; +} + void BootloaderAPI_ErasePage(const uint32_t Address) { + if (! IsPageAddressValid(Address)) + return; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { boot_page_erase_safe(Address); @@ -47,6 +59,9 @@ void BootloaderAPI_ErasePage(const uint32_t Address) void BootloaderAPI_WritePage(const uint32_t Address) { + if (! IsPageAddressValid(Address)) + return; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { boot_page_write_safe(Address); diff --git a/Bootloaders/DFU/BootloaderAPI.c b/Bootloaders/DFU/BootloaderAPI.c index 5e8083ed3..c1e76d3bd 100644 --- a/Bootloaders/DFU/BootloaderAPI.c +++ b/Bootloaders/DFU/BootloaderAPI.c @@ -35,8 +35,20 @@ #include "BootloaderAPI.h" +static bool IsPageAddressValid(const uint32_t Address) +{ + /* Determine if the given page address is correctly aligned to the + start of a flash page. */ + bool PageAddressIsAligned = !(Address & (SPM_PAGESIZE - 1)); + + return (Address < BOOT_START_ADDR) && PageAddressIsAligned; +} + void BootloaderAPI_ErasePage(const uint32_t Address) { + if (! IsPageAddressValid(Address)) + return; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { boot_page_erase_safe(Address); @@ -47,6 +59,9 @@ void BootloaderAPI_ErasePage(const uint32_t Address) void BootloaderAPI_WritePage(const uint32_t Address) { + if (! IsPageAddressValid(Address)) + return; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { boot_page_write_safe(Address); diff --git a/Bootloaders/HID/BootloaderHID.c b/Bootloaders/HID/BootloaderHID.c index c21bf5692..e5b7d3258 100644 --- a/Bootloaders/HID/BootloaderHID.c +++ b/Bootloaders/HID/BootloaderHID.c @@ -152,6 +152,10 @@ void EVENT_USB_Device_ControlRequest(void) uint16_t PageAddress = Endpoint_Read_16_LE(); #endif + /* Determine if the given page address is correctly aligned to the + start of a flash page. */ + bool PageAddressIsAligned = !(PageAddress & (SPM_PAGESIZE - 1)); + /* Check if the command is a program page command, or a start application command */ #if (FLASHEND > 0xFFFF) if ((uint16_t)(PageAddress >> 8) == COMMAND_STARTAPPLICATION) @@ -161,7 +165,7 @@ void EVENT_USB_Device_ControlRequest(void) { RunBootloader = false; } - else if (PageAddress < BOOT_START_ADDR) + else if ((PageAddress < BOOT_START_ADDR) && PageAddressIsAligned) { /* Erase the given FLASH page, ready to be programmed */ ATOMIC_BLOCK(ATOMIC_RESTORESTATE) diff --git a/Bootloaders/MassStorage/BootloaderAPI.c b/Bootloaders/MassStorage/BootloaderAPI.c index 5e8083ed3..c1e76d3bd 100644 --- a/Bootloaders/MassStorage/BootloaderAPI.c +++ b/Bootloaders/MassStorage/BootloaderAPI.c @@ -35,8 +35,20 @@ #include "BootloaderAPI.h" +static bool IsPageAddressValid(const uint32_t Address) +{ + /* Determine if the given page address is correctly aligned to the + start of a flash page. */ + bool PageAddressIsAligned = !(Address & (SPM_PAGESIZE - 1)); + + return (Address < BOOT_START_ADDR) && PageAddressIsAligned; +} + void BootloaderAPI_ErasePage(const uint32_t Address) { + if (! IsPageAddressValid(Address)) + return; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { boot_page_erase_safe(Address); @@ -47,6 +59,9 @@ void BootloaderAPI_ErasePage(const uint32_t Address) void BootloaderAPI_WritePage(const uint32_t Address) { + if (! IsPageAddressValid(Address)) + return; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { boot_page_write_safe(Address); diff --git a/Bootloaders/Printer/BootloaderAPI.c b/Bootloaders/Printer/BootloaderAPI.c index 5e8083ed3..c1e76d3bd 100644 --- a/Bootloaders/Printer/BootloaderAPI.c +++ b/Bootloaders/Printer/BootloaderAPI.c @@ -35,8 +35,20 @@ #include "BootloaderAPI.h" +static bool IsPageAddressValid(const uint32_t Address) +{ + /* Determine if the given page address is correctly aligned to the + start of a flash page. */ + bool PageAddressIsAligned = !(Address & (SPM_PAGESIZE - 1)); + + return (Address < BOOT_START_ADDR) && PageAddressIsAligned; +} + void BootloaderAPI_ErasePage(const uint32_t Address) { + if (! IsPageAddressValid(Address)) + return; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { boot_page_erase_safe(Address); @@ -47,6 +59,9 @@ void BootloaderAPI_ErasePage(const uint32_t Address) void BootloaderAPI_WritePage(const uint32_t Address) { + if (! IsPageAddressValid(Address)) + return; + ATOMIC_BLOCK(ATOMIC_RESTORESTATE) { boot_page_write_safe(Address); diff --git a/LUFA/DoxygenPages/ChangeLog.txt b/LUFA/DoxygenPages/ChangeLog.txt index 8f299f7ea..147cacc36 100644 --- a/LUFA/DoxygenPages/ChangeLog.txt +++ b/LUFA/DoxygenPages/ChangeLog.txt @@ -14,6 +14,7 @@ * character after a successful write (thanks to NicoHood) * - Library Applications: * - Fixed bootloaders not disabling global interrupts during erase and write operations (thanks to Zoltan) + * - Fixed bootloaders accepting flash writes to the bootloader region (thanks to NicoHood) * * \section Sec_ChangeLog170418 Version 170418 * New: -- cgit v1.2.3