1 /*
2  * Copyright (c) 2018 Intel Corporation
3  *
4  * SPDX-License-Identifier: Apache-2.0
5  */
6 
7 #include <ztest.h>
8 #include <zephyr.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 
alternate_thread(void)17 void alternate_thread(void)
18 {
19 	int i;
20 	void *sp_val;
21 
22 	/* If the stack isn't being randomized then sp_val will never change */
23 	sp_val = &i;
24 
25 #if VERBOSE
26 	printk("stack pointer: %p last: %p\n", sp_val, last_sp);
27 #endif
28 
29 	if (last_sp != (void *)0xFFFFFFFF && sp_val != last_sp) {
30 		changed++;
31 	}
32 	last_sp = sp_val;
33 }
34 
35 
36 K_THREAD_STACK_DEFINE(alt_thread_stack_area, STACKSIZE);
37 static struct k_thread alt_thread_data;
38 
39 /**
40  * @brief Test stack pointer randomization
41  *
42  * @ingroup kernel_memprotect_tests
43  *
44  */
test_stack_pt_randomization(void)45 void test_stack_pt_randomization(void)
46 {
47 	int i, sp_changed;
48 	int old_prio = k_thread_priority_get(k_current_get());
49 
50 	/* Set preemptable priority */
51 	k_thread_priority_set(k_current_get(), K_PRIO_PREEMPT(1));
52 
53 	printk("Test Stack pointer randomization\n");
54 
55 	/* Start thread */
56 	for (i = 0; i < THREAD_COUNT; i++) {
57 		k_thread_create(&alt_thread_data, alt_thread_stack_area,
58 				STACKSIZE, (k_thread_entry_t)alternate_thread,
59 				NULL, NULL, NULL, K_HIGHEST_THREAD_PRIO, 0,
60 				K_NO_WAIT);
61 	}
62 
63 
64 	printk("stack pointer changed %d times out of %d tests\n",
65 	       changed, THREAD_COUNT);
66 
67 	sp_changed = changed;
68 	zassert_not_equal(sp_changed, 0, "Stack pointer is not randomized");
69 
70 	/* Restore priority */
71 	k_thread_priority_set(k_current_get(), old_prio);
72 }
73 
test_main(void)74 void test_main(void)
75 {
76 	ztest_test_suite(stack_pointer_randomness,
77 			ztest_1cpu_unit_test(test_stack_pt_randomization));
78 	ztest_run_test_suite(stack_pointer_randomness);
79 }
80