All moved under tests/kernel/mem_protect to reduce clutter. Many more tests are coming for 1.10 and 1.11. Signed-off-by: Andrew Boie <andrew.p.boie@intel.com>
136 lines
3.0 KiB
C
136 lines
3.0 KiB
C
/*
|
|
* Copyright (c) 2012-2014 Wind River Systems, Inc.
|
|
* Copyright (c) 2016 Intel Corporation
|
|
*
|
|
* SPDX-License-Identifier: Apache-2.0
|
|
*/
|
|
|
|
|
|
/**
|
|
* @brief test Stack Protector feature using canary
|
|
*
|
|
* This is the test program to test stack protection using canary.
|
|
*
|
|
* The main thread starts a second thread, which generates a stack check
|
|
* failure.
|
|
* By design, the second thread will not complete its execution and
|
|
* will not set ret to TC_FAIL.
|
|
*/
|
|
|
|
#include <tc_util.h>
|
|
|
|
#include <zephyr.h>
|
|
|
|
|
|
#define STACKSIZE 2048
|
|
#define PRIORITY 5
|
|
|
|
static int count;
|
|
static int ret = TC_PASS;
|
|
|
|
void check_input(const char *name, const char *input);
|
|
|
|
/**
|
|
*
|
|
* print_loop
|
|
*
|
|
* This function calls check_input 6 times with the input name and a short
|
|
* string, which is printed properly by check_input.
|
|
*
|
|
* @param name caller identification string
|
|
*
|
|
* @return N/A
|
|
*/
|
|
|
|
void print_loop(const char *name)
|
|
{
|
|
while (count < 6) {
|
|
/* A short input string to check_input. It will pass. */
|
|
check_input(name, "Stack ok");
|
|
count++;
|
|
}
|
|
}
|
|
|
|
/**
|
|
*
|
|
* check_input
|
|
*
|
|
* This function copies the input string to a buffer of 16 characters and
|
|
* prints the name and buffer as a string. If the input string is longer
|
|
* than the buffer, an error condition is detected.
|
|
*
|
|
* When stack protection feature is enabled (see prj.conf file), the
|
|
* system error handler is invoked and reports a "Stack Check Fail" error.
|
|
* When stack protection feature is not enabled, the system crashes with
|
|
* error like: Trying to execute code outside RAM or ROM.
|
|
*
|
|
* @return N/A
|
|
*/
|
|
|
|
void check_input(const char *name, const char *input)
|
|
{
|
|
/* Stack will overflow when input is more than 16 characters */
|
|
char buf[16];
|
|
|
|
strcpy(buf, input);
|
|
TC_PRINT("%s: %s\n", name, buf);
|
|
}
|
|
|
|
/**
|
|
*
|
|
* This thread passes a long string to check_input function. It terminates due
|
|
* to stack overflow and reports "Stack Check Fail" when stack protection
|
|
* feature is enabled. Hence it will not execute the print_loop function
|
|
* and will not set ret to TC_FAIL.
|
|
*
|
|
* @return N/A
|
|
*/
|
|
void alternate_thread(void)
|
|
{
|
|
TC_PRINT("Starts %s\n", __func__);
|
|
check_input(__func__,
|
|
"Input string is too long and stack overflowed!\n");
|
|
/*
|
|
* Expect this thread to terminate due to stack check fail and will not
|
|
* execute pass here.
|
|
*/
|
|
print_loop(__func__);
|
|
|
|
ret = TC_FAIL;
|
|
}
|
|
|
|
|
|
|
|
K_THREAD_STACK_DEFINE(alt_thread_stack_area, STACKSIZE);
|
|
static struct k_thread alt_thread_data;
|
|
|
|
/**
|
|
*
|
|
* This is the entry point to the test stack protection feature.
|
|
* It starts the thread that tests stack protection, then prints out
|
|
* a few messages before terminating.
|
|
*
|
|
* @return N/A
|
|
*/
|
|
|
|
void main(void)
|
|
{
|
|
TC_START("Test Stack Protection Canary\n");
|
|
TC_PRINT("Starts %s\n", __func__);
|
|
|
|
/* Start thread */
|
|
k_thread_create(&alt_thread_data, alt_thread_stack_area, STACKSIZE,
|
|
(k_thread_entry_t)alternate_thread, NULL, NULL, NULL,
|
|
K_PRIO_PREEMPT(PRIORITY), 0, K_NO_WAIT);
|
|
|
|
if (ret == TC_FAIL) {
|
|
goto errorExit;
|
|
}
|
|
|
|
print_loop(__func__);
|
|
|
|
errorExit:
|
|
TC_END_RESULT(ret);
|
|
TC_END_REPORT(ret);
|
|
}
|