-
Notifications
You must be signed in to change notification settings - Fork 7.3k
mpu stack guard: fix stack alignement #500
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
mpu stack guard: fix stack alignement #500
Conversation
6e262be
to
233d892
Compare
@@ -65,6 +66,5 @@ void main(void) | |||
printk("Canary Initial Value = 0x%x\n", buf.canary); | |||
|
|||
/* spawn stack_guard_thread */ | |||
k_thread_spawn(buf.stack, STACKSIZE, stack_guard_thread, NULL, NULL, | |||
NULL, PRIORITY, 0, K_NO_WAIT); | |||
k_thread_create(&buf.thread, buf.stack, STACKSIZE, stack_guard_thread, NULL,NULL, NULL, PRIORITY, 0, K_NO_WAIT); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This was recently fixed in #478, but the arm branch hasn't been rebased yet to pick it up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if you rebase, we should pickup the fix now in the arm branch
@@ -1,5 +1,4 @@ | |||
CONFIG_STDOUT_CONSOLE=y | |||
CONFIG_MPU_STACK_GUARD=y | |||
CONFIG_SYS_LOG=y | |||
CONFIG_SYS_LOG_DEFAULT_LEVEL=4 | |||
CONFIG_SYS_LOG_OVERRIDE_LEVEL=4 | |||
CONFIG_MULTITHREADING=y |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You don't need to enable multithreading explicitly, it's enabled by default
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agree
printk("Canary = 0x%08x\tTest not passed.\n", buf.canary); | ||
|
||
if (buf[num].canary != STACK_GUARD_CANARY) { | ||
printk("Canary = 0x%08x\tTest not passed.\n", buf[num].canary); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I tried running this on frdm_k64f without stack guarding enabled and I don't hit this condition anymore.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your point is reproduced on nucleo_f401re.
If I moved struct k_thread thread before canary, the message test not passed occurs on nucleo_f401re (because canary gets corrupted before kthread structure get corrupted by stack overflow)
In this case , log is as follow:
STACK_ALIGN 4
MPU STACK GUARD Test
MPU STACK GUARD Test
MPU STACK GUARD Test
MPU STACK GUARD Test
Canary Initial Value = 0xf0cacc1a threads 0x20000b9c
Canary = 0xfffffff5 Test not passed.
***** MPU FAULT *****
Executing thread ID (thread): 0x20000b9c
Faulting instruction address: 0x80025b0
Data Access Violation
Address: 0x8000edb
Fatal fault in thread 0x20000b9c! Aborting.
***** HARD FAULT *****
Fault escalation (see below)
***** MPU FAULT *****
Executing thread ID (thread): 0x20000b9c
Faulting instruction address: 0x8001db6
Data Access Violation
Address: 0x8000edb
Fatal fault in ISR! Spinning...
On the other hand , the log present in README.rst is not describing a mpu guard working usecase: the instruction causing the initial MPU FAULT is at address 0x0, it should be a valid address showing that the MPU caught the instruction that has overflowed the stack.
=>i ll will update README.rst in next PR update
I've updated the arm branch to be in sync with master to pull in the fix @MaureenHelm mentioned. |
233d892
to
13d8c7c
Compare
Comment taken into account and patch rebased. |
Faulting instruction address: 0x8001db6 | ||
Data Access Violation | ||
Address: 0x8000edb | ||
Fatal fault in ISR! Spinning... | ||
|
||
With the MPU enabled and the stack guard feature present: |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
might change "present" to "enabled" to parallel the previous heading
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
one wording suggestion, but otherwise OK.
You should consider implementing ARM versions of the stack definition macros, K_THREAD_STACK_DEFINE, etc. You can then reserve an additional 32-bytes at the beginning of the stack buffers for the guard area so that the effective stack size is the same as the user requested. |
Signed-off-by: Kumar Gala <[email protected]>
We define a variable to pickup a default for the bossa binary, however we weren't using it. Lets do so now. Signed-off-by: Kumar Gala <[email protected]>
If we have more than one board of a given type we need to be able to specify the board_id to select which specific board that the pyocd command should target. Introduce an environment variable PYOCD_BOARD_ID to we can set that will get passed to the pyocd command that needs it. Here's an example: $ make -C samples/hello_world/ BOARD=frdm_k64f flash PYOCD_BOARD_ID=1234 Signed-off-by: Kumar Gala <[email protected]>
As there are multiple ways to flash or debug (pyOCD or openOCD) allow the user to override the default. Signed-off-by: Kumar Gala <[email protected]>
Allow to use an external debug adapter such as J-Link or ULINK connected to a 20-pin JTAG header to flash the image. SWD is the actual protocol used by the debug interface. Signed-off-by: Piotr Mienkowski <[email protected]>
As other stm32 series support MPU, move common file in a file tree useable by socs from other series JIRA: ZEP-2220 Signed-off-by: Michel Jaouen <[email protected]>
Since all l4 socs support MPU, add MPU capability in KConfig.series JIRA: ZEP-2220 Signed-off-by: Michel Jaouen <[email protected]>
Signed-off-by: Michel Jaouen <[email protected]>
Signed-off-by: Michel Jaouen <[email protected]>
Since not all socs from f3 series (i.e stm32f334x8 no MPU) have MPU capability, add capability only for MPU capable socs in Kconfig.soc JIRA: ZEP-2220 Signed-off-by: Michel Jaouen <[email protected]>
Add configuration and memory definitions to support STM32F103x8 Medium-density performance line SoC with 64 KB Flash. Merge multiple files into single Kconfig.defconfig.stm32f103xx Signed-off-by: Siddharth Chandrasekaran <[email protected]>
Following test changes, log info have changes and previous log info with stack guard present shows an mpu error not caused by a stack overflow caught by mpu stack guard feature. Signed-off-by: Michel Jaouen <[email protected]>
9cec2ca
to
1a620de
Compare
Are the changes fine for everybody? |
@MaureenHelm you good? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your point is reproduced on nucleo_f401re.
If I moved struct k_thread thread before canary, the message test not passed occurs on nucleo_f401re (because canary gets corrupted before kthread structure get corrupted by stack overflow)
Thanks, this fixes the frdm_k64f as well.
printk("MPU STACK GUARD Test\n"); | ||
printk("Canary Initial Value = 0x%x\n", buf.canary); | ||
/* create stack_guard_thread */ | ||
k_thread_create(&buf[i].thread, buf[i].stack, STACKSIZE, |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think you need to use K_THREAD_STACK_SIZEOF instead of STACKSIZE
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
yeah. That adjusts for the alignment adjustment. Otherwise you might get unlucky and bad things will happen. Good catch.
int i; | ||
bool failed; | ||
|
||
printk("STACK_ALIGN %x\n", STACK_ALIGN); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Please prepend the value with 0x
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
agreed
f95c1d6
to
4c01e1a
Compare
@@ -42,9 +42,98 @@ extern "C" { | |||
#include <arch/arm/cortex_m/sys_io.h> | |||
#include <arch/arm/cortex_m/nmi.h> | |||
#endif | |||
#if defined(CONFIG_MPU_STACK_GUARD) | |||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry for the late comment, but I found out that we need this regardless of whether or not the STACK_GUARD is set. The reason being that we need these in place to place the stacks in a specific place. Instead of noinit, we can set the location to a specific region during link.
How about just putting the STACK_SIZE in the #if def and set it to 32 or 4 based on the STACK_GUARD being set. The rest would always be defined.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Stacks can really live anywhere that isn't in application memory space.
For stacks that are not defined as struct members, on x86 I put them in a special '.stacks' section which ends up in the kernel's "noinit".
0f36cad
to
1bc2fdc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The definition of the various K_THREAD_STACK_xxxx macros looks correct to me for the guard-type stack protection.
0723c92
to
38db4ed
Compare
I reworked these patches and pushed to a new pull request. #987 |
Merged #987, we can close this now. |
-1- The mpu stack guard feature requires that stack base is 32 bytes aligned.
(ARM DUI0553.pdf : Cortex M4 generic User guide mentions this constraint)
-2- Mpu stack guard test does not use kthread_spawn api, because it is not
useable with mpu stack guard: this api allocates the kthread structure at
stack base address, and mpu stack guard does not allow any access
in the 32 bytes after stack base address.
-3- Mpu stack guard test has been modified to be able to detect above issue.