1 /*
2 * Copyright (c) 2018 Intel Corporation
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zephyr/kernel.h>
9
10 #define STACKSIZE 2048
11 #define THREAD_COUNT 64
12 #define VERBOSE 0
13
14 void *last_sp = (void *)0xFFFFFFFF;
15 volatile unsigned int changed;
16
17 /*
18 * The `alternate_thread` function deliberately makes use of a dangling pointer
19 * in order to test stack randomisation.
20 */
21 #if defined(__GNUC__)
22 #pragma GCC diagnostic push
23 #pragma GCC diagnostic ignored "-Wpragmas"
24 #pragma GCC diagnostic ignored "-Wdangling-pointer"
25 #endif
26
alternate_thread(void)27 void alternate_thread(void)
28 {
29 int i;
30 void *sp_val;
31
32 /* If the stack isn't being randomized then sp_val will never change */
33 sp_val = &i;
34
35 #if VERBOSE
36 printk("stack pointer: %p last: %p\n", sp_val, last_sp);
37 #endif
38
39 if (last_sp != (void *)0xFFFFFFFF && sp_val != last_sp) {
40 changed++;
41 }
42 last_sp = sp_val;
43 }
44
45 #if defined(__GNUC__)
46 #pragma GCC diagnostic pop
47 #endif
48
49 K_THREAD_STACK_DEFINE(alt_thread_stack_area, STACKSIZE);
50 static struct k_thread alt_thread_data;
51
52 /**
53 * @brief Test stack pointer randomization
54 *
55 * @ingroup kernel_memprotect_tests
56 *
57 */
ZTEST(stack_pointer_randomness,test_stack_pt_randomization)58 ZTEST(stack_pointer_randomness, test_stack_pt_randomization)
59 {
60 int i, sp_changed;
61 int old_prio = k_thread_priority_get(k_current_get());
62
63 /* Set preemptable priority */
64 k_thread_priority_set(k_current_get(), K_PRIO_PREEMPT(1));
65
66 printk("Test Stack pointer randomization\n");
67
68 /* Start thread */
69 for (i = 0; i < THREAD_COUNT; i++) {
70 k_thread_create(&alt_thread_data, alt_thread_stack_area,
71 STACKSIZE, (k_thread_entry_t)alternate_thread,
72 NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, 0,
73 K_NO_WAIT);
74 k_sleep(K_MSEC(10));
75 }
76
77
78 printk("stack pointer changed %d times out of %d tests\n",
79 changed, THREAD_COUNT);
80
81 sp_changed = changed;
82 zassert_not_equal(sp_changed, 0, "Stack pointer is not randomized");
83
84 /* Restore priority */
85 k_thread_priority_set(k_current_get(), old_prio);
86 }
87
88 ZTEST_SUITE(stack_pointer_randomness, NULL, NULL,
89 ztest_simple_1cpu_before, ztest_simple_1cpu_after, NULL);
90