tests: kernel: fatal: check stack overflow
For all arches except ARC, enable stack sentinel and test that some common stack violations trigger exceptions. For ARC, use the hardware stack checking feature. Additional testcase.ini blocks may be added to do stack bounds checking for MMU/MPU-based stack protection schemes. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
This commit is contained in:
parent
5dcb279df8
commit
636f609d66
4 changed files with 99 additions and 5 deletions
1
tests/kernel/fatal/prj-arc.conf
Normal file
1
tests/kernel/fatal/prj-arc.conf
Normal file
|
@ -0,0 +1 @@
|
|||
CONFIG_ARC_STACK_CHECKING=y
|
|
@ -1,2 +1,2 @@
|
|||
CONFIG_MAIN_THREAD_PRIORITY=7
|
||||
CONFIG_STACK_SENTINEL=y
|
||||
|
||||
|
|
|
@ -9,10 +9,19 @@
|
|||
#include <kernel_structs.h>
|
||||
#include <irq_offload.h>
|
||||
|
||||
#define STACKSIZE 1024
|
||||
#define STACKSIZE 2048
|
||||
#define MAIN_PRIORITY 7
|
||||
#define PRIORITY 5
|
||||
|
||||
static char __noinit __stack alt_stack[STACKSIZE];
|
||||
|
||||
#ifdef CONFIG_STACK_SENTINEL
|
||||
#define OVERFLOW_STACKSIZE 1024
|
||||
static char *overflow_stack = alt_stack + (STACKSIZE - OVERFLOW_STACKSIZE);
|
||||
#else
|
||||
#define OVERFLOW_STACKSIZE STACKSIZE
|
||||
#endif
|
||||
|
||||
static struct k_thread alt_thread;
|
||||
volatile int rv;
|
||||
|
||||
|
@ -39,8 +48,44 @@ void alt_thread1(void)
|
|||
|
||||
void alt_thread2(void)
|
||||
{
|
||||
int key;
|
||||
|
||||
key = irq_lock();
|
||||
k_oops();
|
||||
rv = TC_FAIL;
|
||||
irq_unlock(key);
|
||||
}
|
||||
|
||||
|
||||
void blow_up_stack(void)
|
||||
{
|
||||
char buf[OVERFLOW_STACKSIZE];
|
||||
printk("posting %zu bytes of junk to stack...\n", sizeof(buf));
|
||||
memset(buf, 0xbb, sizeof(buf));
|
||||
}
|
||||
|
||||
void stack_thread1(void)
|
||||
{
|
||||
/* Test that stack overflow check due to timer interrupt works */
|
||||
blow_up_stack();
|
||||
printk("busy waiting...\n");
|
||||
k_busy_wait(1024 * 1024);
|
||||
printk("should never see this\n");
|
||||
rv = TC_FAIL;
|
||||
}
|
||||
|
||||
|
||||
void stack_thread2(void)
|
||||
{
|
||||
int key = irq_lock();
|
||||
|
||||
/* Test that stack overflow check due to swap works */
|
||||
blow_up_stack();
|
||||
printk("swapping...\n");
|
||||
_Swap(irq_lock());
|
||||
printk("should never see this\n");
|
||||
rv = TC_FAIL;
|
||||
irq_unlock(key);
|
||||
}
|
||||
|
||||
|
||||
|
@ -50,8 +95,10 @@ void main(void)
|
|||
|
||||
TC_START("test_fatal");
|
||||
|
||||
k_thread_priority_set(_current, K_PRIO_PREEMPT(MAIN_PRIORITY));
|
||||
|
||||
printk("test alt thread 1: generic CPU exception\n");
|
||||
k_thread_create(&alt_thread, alt_stack, STACKSIZE,
|
||||
k_thread_create(&alt_thread, alt_stack, sizeof(alt_stack),
|
||||
(k_thread_entry_t)alt_thread1,
|
||||
NULL, NULL, NULL, K_PRIO_PREEMPT(PRIORITY), 0,
|
||||
K_NO_WAIT);
|
||||
|
@ -63,7 +110,7 @@ void main(void)
|
|||
}
|
||||
|
||||
printk("test alt thread 2: initiate kernel oops\n");
|
||||
k_thread_create(&alt_thread, alt_stack, STACKSIZE,
|
||||
k_thread_create(&alt_thread, alt_stack, sizeof(alt_stack),
|
||||
(k_thread_entry_t)alt_thread2,
|
||||
NULL, NULL, NULL, K_PRIO_PREEMPT(PRIORITY), 0,
|
||||
K_NO_WAIT);
|
||||
|
@ -74,6 +121,43 @@ void main(void)
|
|||
printk("PASS\n");
|
||||
}
|
||||
|
||||
printk("test stack overflow - timer irq\n");
|
||||
#ifdef CONFIG_STACK_SENTINEL
|
||||
/* When testing stack sentinel feature, the overflow stack is a
|
||||
* smaller section of alt_stack near the end.
|
||||
* In this way when it gets overflowed by blow_up_stack() we don't
|
||||
* corrupt anything else and prevent the test case from completing.
|
||||
*/
|
||||
k_thread_create(&alt_thread, overflow_stack, OVERFLOW_STACKSIZE,
|
||||
#else
|
||||
k_thread_create(&alt_thread, alt_stack, sizeof(alt_stack),
|
||||
#endif
|
||||
(k_thread_entry_t)stack_thread1,
|
||||
NULL, NULL, NULL, K_PRIO_PREEMPT(PRIORITY), 0,
|
||||
K_NO_WAIT);
|
||||
if (rv == TC_FAIL) {
|
||||
printk("thread was not aborted\n");
|
||||
goto out;
|
||||
} else {
|
||||
printk("PASS\n");
|
||||
}
|
||||
|
||||
printk("test stack overflow - swap\n");
|
||||
#ifdef CONFIG_STACK_SENTINEL
|
||||
k_thread_create(&alt_thread, overflow_stack, OVERFLOW_STACKSIZE,
|
||||
#else
|
||||
k_thread_create(&alt_thread, alt_stack, sizeof(alt_stack),
|
||||
#endif
|
||||
(k_thread_entry_t)stack_thread2,
|
||||
NULL, NULL, NULL, K_PRIO_PREEMPT(PRIORITY), 0,
|
||||
K_NO_WAIT);
|
||||
if (rv == TC_FAIL) {
|
||||
printk("thread was not aborted\n");
|
||||
goto out;
|
||||
} else {
|
||||
printk("PASS\n");
|
||||
}
|
||||
|
||||
out:
|
||||
TC_END_RESULT(rv);
|
||||
TC_END_REPORT(rv);
|
||||
|
|
|
@ -1,2 +1,11 @@
|
|||
[test]
|
||||
# Uses CONFIG_STACK_SENTINEL
|
||||
[stack-sentinel]
|
||||
tags = core ignore_faults
|
||||
arch_exclude = arc
|
||||
|
||||
# Uses CONFIG_ARC_STACK_CHECKING
|
||||
[arc-stack-checking]
|
||||
tags = core ignore_faults
|
||||
extra_args = CONF_FILE=prj-arc.conf
|
||||
arch_whitelist = arc
|
||||
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue