Loading...
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 | /* * Copyright (c) 2012-2014 Wind River Systems, Inc. * Copyright (c) 2016 Intel Corporation * * SPDX-License-Identifier: Apache-2.0 */ #include <zephyr.h> #include <ztest.h> #define STACKSIZE (2048 + CONFIG_TEST_EXTRA_STACKSIZE) ZTEST_BMEM static int count; ZTEST_BMEM static int ret = TC_PASS; void k_sys_fatal_error_handler(unsigned int reason, const z_arch_esf_t *esf) { if (reason != K_ERR_STACK_CHK_FAIL) { printk("wrong error type\n"); k_fatal_halt(reason); } } 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; /** * @brief test Stack Protector feature using canary * * @details 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. * 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. * * @ingroup kernel_memprotect_tests */ void test_stackprot(void) { zassert_true(ret == TC_PASS, NULL); print_loop(__func__); } void test_create_alt_thread(void) { /* Start thread */ k_thread_create(&alt_thread_data, alt_thread_stack_area, STACKSIZE, (k_thread_entry_t)alternate_thread, NULL, NULL, NULL, K_PRIO_COOP(1), K_USER, K_NO_WAIT); } void test_main(void) { ztest_test_suite(stackprot, ztest_unit_test(test_create_alt_thread), ztest_user_unit_test(test_stackprot)); ztest_run_test_suite(stackprot); } |