Ok, so I found a solution for now.
Since the memory driver can't be changed very easily, because the reliable update should still be able to erase and write the main application area, I added some logic to the command and sbloader layers. The patches (git) for both files (bl_command.c and sbloader.c) are attached.
This change will prevent the user from:
* Write or Erase a region before the backup address;
* Write or Erase a region that will overlap the main application area (if the Backup Application Address is lower than the Main Application Address).
I should warn, though, that the "Erase all" command is still available and will still erase both the backup and the main appllication areas, but if someone needs the extra protection, a similar approach could be used.
bl_command.c
diff --git a/NXP_Kinetis_Bootloader_2_0_0/src/bootloader/src/bl_command.c b/NXP_Kinetis_Bootloader_2_0_0/src/bootloader/src/bl_command.c
index ac35e17..73173a0 100644
--- a/NXP_Kinetis_Bootloader_2_0_0/src/bootloader/src/bl_command.c
+++ b/NXP_Kinetis_Bootloader_2_0_0/src/bootloader/src/bl_command.c
@@ -491,8 +491,22 @@
#ifdef BOOTLOADER_HOST
host_flash_erase_region(command->startAddress, command->byteCount);
#else
- status = g_bootloaderContext.memoryInterface->erase(command->startAddress, command->byteCount);
-#endif
+/* The user shouldn't be able to erase the application region, if the reliable update is active */
+#if BL_FEATURE_RELIABLE_UPDATE
+ /* If the backup application is saved after the application */
+ if ((command->startAddress < BL_BACKUP_APP_START) || //the user is trying to erase a sector before the region it was supposed to
+ ((BL_BACKUP_APP_START < BL_APP_VECTOR_TABLE_ADDRESS) && (command->startAddress >= BL_APP_VECTOR_TABLE_ADDRESS)) || //the user is trying to erase the application area
+ ((BL_BACKUP_APP_START < BL_APP_VECTOR_TABLE_ADDRESS) && ((command->startAddress + command->byteCount) >= BL_APP_VECTOR_TABLE_ADDRESS))) //the user is trying to erase a region that will overlap the application area
+ {
+ send_generic_response(kStatusMemoryRangeInvalid, command->commandPacket.commandTag);
+ return;
+ }
+ else
+#endif //BL_FEATURE_RELIABLE_UPDATE
+ {
+ status = g_bootloaderContext.memoryInterface->erase(command->startAddress, command->byteCount);
+ }
+#endif //BOOTLOADER_HOST
send_generic_response(status, command->commandPacket.commandTag);
}
@@ -704,7 +718,22 @@
#endif // !BL_FEATURE_MIN_PROFILE
{
// Consumer is memory interface.
- status = g_bootloaderContext.memoryInterface->write(dataAddress, packetLength, packet);
+
+ /* The user shouldn't be able to write in the application region, if the reliable update is active */
+ #if BL_FEATURE_RELIABLE_UPDATE
+ /* If the backup application is saved after the application */
+ if ((dataAddress < BL_BACKUP_APP_START) || //the user is trying to write before the region it was supposed to
+ ((BL_BACKUP_APP_START < BL_APP_VECTOR_TABLE_ADDRESS) && (dataAddress >= BL_APP_VECTOR_TABLE_ADDRESS)) || //the user is trying to write in the application area
+ ((BL_BACKUP_APP_START < BL_APP_VECTOR_TABLE_ADDRESS) && ((dataAddress + packetLength) >= BL_APP_VECTOR_TABLE_ADDRESS))) //the user is trying to write a package that will overlap the application area
+ {
+ status = kStatusMemoryRangeInvalid;
+ }
+ else
+ #endif //BL_FEATURE_RELIABLE_UPDATE
+ {
+ status = g_bootloaderContext.memoryInterface->write(dataAddress, packetLength, packet);
+ }
+
dataAddress += packetLength;
}
sbloader.c
diff --git a/NXP_Kinetis_Bootloader_2_0_0/src/sbloader/src/sbloader.c b/NXP_Kinetis_Bootloader_2_0_0/src/sbloader/src/sbloader.c
index 90c0f12..755c6dc 100644
--- a/NXP_Kinetis_Bootloader_2_0_0/src/sbloader/src/sbloader.c
+++ b/NXP_Kinetis_Bootloader_2_0_0/src/sbloader/src/sbloader.c
@@ -467,8 +467,21 @@
}
#endif
- status_t status =
- g_bootloaderContext.memoryInterface->write(context->bootCmd.address, context->bootCmd.count, context->src);
+ status_t status;
+ /* The user shouldn't be able to erase the application region, if the reliable update is active */
+#if BL_FEATURE_RELIABLE_UPDATE
+ /* If the backup application is saved after the application */
+ if ((context->bootCmd.address < BL_BACKUP_APP_START) || //the user is trying to write in a sector before the region it was supposed to
+ ((BL_BACKUP_APP_START < BL_APP_VECTOR_TABLE_ADDRESS) && (context->bootCmd.address >= BL_APP_VECTOR_TABLE_ADDRESS)) || //the user is trying to write in the application area
+ ((BL_BACKUP_APP_START < BL_APP_VECTOR_TABLE_ADDRESS) && ((context->bootCmd.address + context->bootCmd.count) >= BL_APP_VECTOR_TABLE_ADDRESS))) //the user is trying to write a packet that will overlap the application area
+ {
+ status = kStatusMemoryRangeInvalid;
+ }
+ else
+#endif //BL_FEATURE_RELIABLE_UPDATE
+ {
+ status = g_bootloaderContext.memoryInterface->write(context->bootCmd.address, context->bootCmd.count, context->src);
+ }
if (status != kStatus_Success)
{
@@ -538,8 +551,23 @@
// update the crc running value
crc32_update(&context->crc32, context->src, sizeof(chunk_t));
- status_t status =
- g_bootloaderContext.memoryInterface->write(context->bootCmd.address, sizeof(chunk_t), context->src);
+ status_t status;
+
+ /* The user shouldn't be able to erase the application region, if the reliable update is active */
+#if BL_FEATURE_RELIABLE_UPDATE
+ /* If the backup application is saved after the application */
+ if ((context->bootCmd.address < BL_BACKUP_APP_START) || //the user is trying to write in a sector before the region it was supposed to
+ ((BL_BACKUP_APP_START < BL_APP_VECTOR_TABLE_ADDRESS) && (context->bootCmd.address >= BL_APP_VECTOR_TABLE_ADDRESS)) || //the user is trying to write in the application area
+ ((BL_BACKUP_APP_START < BL_APP_VECTOR_TABLE_ADDRESS) && ((context->bootCmd.address + sizeof(chunk_t)) >= BL_APP_VECTOR_TABLE_ADDRESS))) //the user is trying to write a packet that will overlap the application area
+ {
+ status = kStatusMemoryRangeInvalid;
+ }
+ else
+#endif //BL_FEATURE_RELIABLE_UPDATE
+ {
+ status = g_bootloaderContext.memoryInterface->write(context->bootCmd.address, sizeof(chunk_t), context->src);
+ }
+
if (status != kStatus_Success)
{
return status;
@@ -851,7 +879,20 @@
}
else
{
- status = g_bootloaderContext.memoryInterface->erase(context->bootCmd.address, context->bootCmd.count);
+ /* The user shouldn't be able to erase the application region, if the reliable update is active */
+ #if BL_FEATURE_RELIABLE_UPDATE
+ /* If the backup application is saved after the application */
+ if ((context->bootCmd.address < BL_BACKUP_APP_START) || //the user is trying to erase a sector before the region it was supposed to
+ ((BL_BACKUP_APP_START < BL_APP_VECTOR_TABLE_ADDRESS) && (context->bootCmd.address >= BL_APP_VECTOR_TABLE_ADDRESS)) || //the user is trying to erase the application area
+ ((BL_BACKUP_APP_START < BL_APP_VECTOR_TABLE_ADDRESS) && ((context->bootCmd.address + context->bootCmd.count) >= BL_APP_VECTOR_TABLE_ADDRESS))) //the user is trying to erase a region that will overlap the application area
+ {
+ status = kStatusMemoryRangeInvalid;
+ }
+ else
+ #endif //BL_FEATURE_RELIABLE_UPDATE
+ {
+ status = g_bootloaderContext.memoryInterface->erase(context->bootCmd.address, context->bootCmd.count);
+ }
}
return status;
Hopefully it is usefull for someone else.
Cheers
Bruno