Exercises related to Robust Design Patterns - Part 2
Stack
Leveraging stack Overflow
Exercice 1
In an interesting article of Arstechnica - How security flaws work: The buffer overflow the following is stated:
The problem of buffer flows is more serious: they often lead to code execution. This happens because those overflowed buffers won’t just overwrite data. They can also overwrite the other important thing kept on the stack—those return addresses. The return address controls which instructions the processor will execute when it’s finished with the current function; it’s meant to be some location within the calling function, but if it gets overwritten in a buffer overflow, it could point anywhere. If attackers can control the buffer overflow, they can control the return address; if they can control the return address, they can choose what code the processor executes next.
In the same article, the Morris Worm ( The buffer overflow - Blame C ) is explained. Have a go at this and explain:
- what was the main attack vector used?
- what leveraging means was part of the attack?
- what is the intrinsic challenge with buffer handling?
Overflow checking
Exercice 2
- The following code is what ARM Keil uses for checking whether a stack overflow
has occurred. Can you explain what it does?
/// Check current running Thread Stack. /// \param[in] thread running thread. /// \return true - success, false - failure. bool_t osRtxThreadStackCheck (const os_thread_t *thread) { if ((thread->sp <= (uint32_t)thread->stack_mem) || (*((uint32_t *)thread->stack_mem) != osRtxStackMagicWord)) { return FALSE; } return TRUE; }
- What happens when a stack overflow is detected? Does the system have the possibility of intervening? Hint: check out Configure RTX v5
Exercice 3
You have now set stack sizes for your applications - without too much thoughts about sizes. While a Dynamic Stack Analysis (with the help of watermarking) may help you figuring out how much stack your own tasks require, the main stack (MSP) is trickier. Read Keil’s Application Note 316, Analysis of Stack Usage (page 5 onwards) carefully and respond to the questions below:
- What is the primary difference between Static and Dynamic Stack Analysis?
- What is that one may miss while using Static Stack Analysis?
- What is the risk (in the result interpretation) of Dynamic Stack Analysis?
Memory
Memory Pools
Memory fragmentation is a challenge as we saw during the lecture. Luckily, ARM Keil does have a response to it in the form of Memory Pools.
Exercice 4
Read the Theory of Operations about Memory Pools and provide an answer to following questions:
- What is the prerequisite to make Memory Pools work?
- What are the 3 types of Memory Management Systems available in ARM Keil?
- What is the advantage of Object-specific Memory Pools?
- What should one pay attention to in case of Statically allocated memory objects?
ARM Keil Objects and User Defined Structures
As stated in the previous exercice, ARM Keil supports Memory Pools for different object types. Obviously, this can be used for ARM Keil objects, while the same be done for structures defined by a developer.
Exercice 5
The document Memory Pool Management provides details about its way of working. Very interesting is the usage example that gives a concrete example how to use it. Study it carefully and respond the following questions:
- Can the different functions be called from an ISR?
- What is necessary so that your structure is served by a Memory Pool?
- Can I use this for sharing data among threads?