| /* |
| * Copyright (c) 2018 Intel Corporation |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #include <zephyr/ztest.h> |
| #include <zephyr/kernel.h> |
| |
| #define STACKSIZE 2048 |
| #define THREAD_COUNT 64 |
| #define VERBOSE 0 |
| |
| void *last_sp = (void *)0xFFFFFFFF; |
| volatile unsigned int changed; |
| |
| /* |
| * The `alternate_thread` function deliberately makes use of a dangling pointer |
| * in order to test stack randomisation. |
| */ |
| #if defined(__GNUC__) |
| #pragma GCC diagnostic push |
| #pragma GCC diagnostic ignored "-Wpragmas" |
| #pragma GCC diagnostic ignored "-Wdangling-pointer" |
| #endif |
| |
| void alternate_thread(void) |
| { |
| int i; |
| void *sp_val; |
| |
| /* If the stack isn't being randomized then sp_val will never change */ |
| sp_val = &i; |
| |
| #if VERBOSE |
| printk("stack pointer: %p last: %p\n", sp_val, last_sp); |
| #endif |
| |
| if (last_sp != (void *)0xFFFFFFFF && sp_val != last_sp) { |
| changed++; |
| } |
| last_sp = sp_val; |
| } |
| |
| #if defined(__GNUC__) |
| #pragma GCC diagnostic pop |
| #endif |
| |
| K_THREAD_STACK_DEFINE(alt_thread_stack_area, STACKSIZE); |
| static struct k_thread alt_thread_data; |
| |
| /** |
| * @brief Test stack pointer randomization |
| * |
| * @ingroup kernel_memprotect_tests |
| * |
| */ |
| ZTEST(stack_pointer_randomness, test_stack_pt_randomization) |
| { |
| int i, sp_changed; |
| int old_prio = k_thread_priority_get(k_current_get()); |
| |
| /* Set preemptable priority */ |
| k_thread_priority_set(k_current_get(), K_PRIO_PREEMPT(1)); |
| |
| printk("Test Stack pointer randomization\n"); |
| |
| /* Start thread */ |
| for (i = 0; i < THREAD_COUNT; i++) { |
| k_thread_create(&alt_thread_data, alt_thread_stack_area, |
| STACKSIZE, (k_thread_entry_t)alternate_thread, |
| NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, 0, |
| K_NO_WAIT); |
| } |
| |
| |
| printk("stack pointer changed %d times out of %d tests\n", |
| changed, THREAD_COUNT); |
| |
| sp_changed = changed; |
| zassert_not_equal(sp_changed, 0, "Stack pointer is not randomized"); |
| |
| /* Restore priority */ |
| k_thread_priority_set(k_current_get(), old_prio); |
| } |
| |
| ZTEST_SUITE(stack_pointer_randomness, NULL, NULL, |
| ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL); |