2021-02-06 09:06 AM
I have developed a dynamic loader that works in an STM32 (cortex-m4) microcontroller. Basically, the base firmware is in charge of writing new dynamic code into flash, and executing it. It works as expected. but I am trying to make the execution of the dynamic code as safe as possible. At the moment I am not thinking about malicious code from an attacker as this relates more to the security of the system.
I am more concerned that for some reason, someone who has loadedDynamic Code did not test it extensively and might create a hard fault. Is it possible to implement a monitor that detects if the hard fault handler was caused during executing of the dynamic code (e.g. setting a flag when executing the code) and re-write the dynamic code in flash so next time the MCU is rebooted the code is not executed again.
Would this approach be viable or has someone had any experience on scenarios where the base firmware must be able to recover from hard faults caused by external unknown bugs (in this case from loading dynamic code).
2021-02-07 02:45 AM
That's possible in many ways. A crude but simple way would be resetting the whole MCU. You can store a reset reason in SRAM and evaluate it after the reset and then take appropriate actions. If you can restrict the "dynamic code" to user mode, you may create a run-time monitor in privileged mode. You may also use a memory protection unit/firewall if present in your MCU. The whole story ends-up with a fully fledged operating system...
2021-02-07 02:49 AM
When you load and start any code, your base better named bootloader dont have chance to do any correction when code started is bad.
Only Two real protection exist , first is use independent watchdog and require it use in dynamic code.
Second use an RTOS as base and dynamic code must be based as new thread app part.
2021-02-08 08:00 AM
Thanks for the info. I read more about the Cortex-M4 and I see that I can use the CONTROL register for the purpose of using privileged mode. My idea is the following:
1)Set MPU, so the external binary code that will be executed does not access certain regions of the MCU.
2)Enable MPU and set Thread mode to unprivileged mode.
3)Finish Execution, call the Supervisor Call Handler, and set privilege mode again.
Do you think this approach can work or is there something else I am missing? The idea for the Project is not to implement a full OS. I only require to execute code on run-time (e.g. additional functions that the MCU can have, sort of like plugins) and be sure that the device can gracefully recover if the plugins dont work due to bugs for example.
2021-02-08 08:08 AM
You can return from a Hard Fault..
Here you'd have to be able to unpack the processor state, and walk back up the instructions from the fault. This is a non-trival task and would require a clear understanding of the core's behaviour and instruction forms.
You could also walk back up the stack, but again this is not easy.
Perhaps you could implement a try/catch method allowing you to define a recovery point and stack depth so you could properly back-out of the failure?