Stack protection in IAR Embedded Workbench
In software, a stack buffer overflow occurs when a program writes to a memory address on the program’s call stack outside of the intended data structure, which is usually a fixed-length buffer. The result is, almost always, corruption of nearby data, and it can even change which function to return to. If it is deliberate, it is often called stack smashing. One method to guard against stack buffer overflow is to use stack canaries, named for their analogy to the use of canaries in coal mines. Stack protection is available mainly for all recent releases of IAR Embedded Workbench.
The implementation of stack protection in IAR Embedded Workbench for Arm uses a heuristic to determine whether a function needs stack protection or not. If any defined local variable has the array type or a structure type that contains a member of array type, the function will need stack protection. In addition, if the address of any local variable is propagated outside of a function, such a function will also need stack protection.
If a function needs stack protection, the local variables are sorted to let the variables with array type to be placed as high as possible in the function stack block. After those variables, a canary element is placed. The canary is initialized at function entrance. The initialization value is taken from the global variable __stack_chk_guard. At function exit, the code verifies that the canary element still contains the initialization value. If not, the function __stack_chk_fail is called.
Use the option under Project>Options>C/C++ Compiler>Code>Stack protection to enable stack protection for the functions that are considered to need it.
Optionally, it's also possible to use the Project>Options>C/C++ Compiler>Extra Options page to specify the --stack_protection command line to enable stack protection.
Stack protection in your application
To use stack protection, you must define these objects in your application:
- extern uint32_t __stack_chk_guard
The global variable __stack_chk_guard must be initialized prior to first use. If the initialization value is randomized, it will be more secure.
- __interwork __nounwind __noreturn void __stack_chk_fail(void)
The purpose of the function __stack_chk_fail is to notify about the problem and then terminate the application. Note that the return address from this function will point into the function that failed.
The file stack_protection.c in the directory arm\src\lib\runtime can be used as a template for both __stack_chk_guard and __stack_chk_fail.