Reliable Update allows writing in application area?

cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

Reliable Update allows writing in application area?

957 Views
brunoalbrecht
Contributor III

Hello all,

I've been playing around with the Bootloader and I found something that could be called a bug, or a possible weird feature.

When you turn Relible Update on, the idea is basically to program your application in a backup address (BL_BACKUP_APP_START, let's call it B) and then the bootloader will check if it is correct and moves it to the application address (BL_APP_VECTOR_TABLE_ADDRESS, let's call it A). The application only runs from the address A. If the application in B is not right (CRC not valid), then the bootloader does nothing and you'll still have your application in address A.

This is very nice, but it means you should program your application in B. If you program it in any other location, the bootloader won't find it, thus won't update the application in A.

But what if I try to program my application directly in A? Shouldn't the bootloader protect this area?

Right now, if you program your application directly in A, no Reliable Update will be performed, thus if the the program is somehow corrupted during the transfer, it might disable your board.

Cheers,

Bruno

Labels (1)
0 Kudos
4 Replies

622 Views
brunoalbrecht
Contributor III

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

0 Kudos

622 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Bruno,

Thank you for the sharing.

best regards,

Hui

0 Kudos

622 Views
Hui_Ma
NXP TechSupport
NXP TechSupport

Hi Bruno,

So far, the Kinetis bootloader V2.0.0 does support the reliable update.

Please check the KBOOT V2.0.0 reference manual chapter 12 for the detailed info:

pastedImage_1.png

pastedImage_2.png

The configuration macros defined in bootloader_config.h are used to enable the reliable update feature.

Wish it helps.


Have a great day,
Ma Hui

-----------------------------------------------------------------------------------------------------------------------
Note: If this post answers your question, please click the Correct Answer button. Thank you!
-----------------------------------------------------------------------------------------------------------------------

0 Kudos

622 Views
brunoalbrecht
Contributor III

Sorry Hui_Ma, but I think you either didn't understand my post or didn't read it entirely. 

I understand how the Booloader works and how the Reliable Update works and how it can be configured. My point is: even with the reliable update turned on, it is still possible to overwrite the application area by writing directly to it, which, in my opinion should not be allowed. If you're trying to update your application in reliable way, you shouldn't be able to write over your old application! You should only be able to write on the backup location and then the bootloader would decide whether the application is valid or not to finally, if it is valid, move to the application space.

Anyway, I'll be working on that on the next few days and I'll post a solution.

Cheers,

Bruno

0 Kudos