5
5
*/
6
6
7
7
#include <zephyr/ztest.h>
8
- #include <zephyr/arch/exception .h>
8
+ #include <zephyr/irq_offload .h>
9
9
10
- #define IV_CTRL_PROTECTION_EXCEPTION 21
10
+ #include <zephyr/kernel/thread_stack.h>
11
11
12
- #define CTRL_PROTECTION_ERRORCODE_ENDBRANCH 3
12
+ #include "common.h"
13
13
14
- extern int should_work (int a );
15
- extern int should_not_work (int a );
14
+ #define SHADOW_STACK_SIZE 1024
15
+
16
+ #ifdef CONFIG_HW_SHADOW_STACK
17
+ void thread_a_entry (void * p1 , void * p2 , void * p3 );
18
+ K_SEM_DEFINE (thread_a_sem , 0 , 1 );
19
+ K_THREAD_DEFINE (thread_a , STACKSIZE , thread_a_entry , NULL , NULL , NULL ,
20
+ THREAD_PRIORITY , 0 , -1 );
21
+
22
+ void thread_b_entry (void * p1 , void * p2 , void * p3 );
23
+ K_SEM_DEFINE (thread_b_sem , 0 , 1 );
24
+ K_SEM_DEFINE (thread_b_irq_sem , 0 , 1 );
25
+ K_THREAD_DEFINE (thread_b , STACKSIZE , thread_b_entry , NULL , NULL , NULL ,
26
+ THREAD_PRIORITY , 0 , -1 );
27
+
28
+ static bool is_shstk_enabled (void )
29
+ {
30
+ long cur ;
31
+
32
+ cur = z_x86_msr_read (X86_S_CET_MSR );
33
+ return (cur & X86_S_CET_MSR_SHSTK_EN ) == X86_S_CET_MSR_SHSTK_EN ;
34
+ }
35
+
36
+ void thread_c_entry (void * p1 , void * p2 , void * p3 )
37
+ {
38
+ zassert_true (is_shstk_enabled (), "shadow stack not enabled on static thread" );
39
+ }
40
+
41
+ K_THREAD_DEFINE (thread_c , STACKSIZE , thread_c_entry , NULL , NULL , NULL ,
42
+ THREAD_PRIORITY , 0 , 0 );
43
+
44
+ void __attribute__((optimize ("O0" ))) foo (void )
45
+ {
46
+ printk ("foo called\n" );
47
+ }
48
+
49
+ void __attribute__((optimize ("O0" ))) fail (void )
50
+ {
51
+ long a [] = {0 };
52
+
53
+ printk ("should fail after this\n" );
54
+
55
+ * (a + 2 ) = (long )foo ;
56
+ }
57
+
58
+ struct k_work work ;
59
+
60
+ void work_handler (struct k_work * wrk )
61
+ {
62
+ printk ("work handler\n" );
63
+
64
+ zassert_true (is_shstk_enabled (), "shadow stack not enabled" );
65
+ }
66
+
67
+ ZTEST (cet , test_shstk_work_q )
68
+ {
69
+ k_work_init (& work , work_handler );
70
+ k_work_submit (& work );
71
+ }
16
72
17
- static bool expect_fault ;
18
- static int expect_code ;
19
-
20
- void k_sys_fatal_error_handler (unsigned int reason , const struct arch_esf * pEsf )
21
- {
22
- if (expect_fault ) {
23
- #ifdef CONFIG_X86_64
24
- zassert_equal (pEsf -> vector , IV_CTRL_PROTECTION_EXCEPTION ,
25
- "unexpected exception" );
26
- zassert_equal (pEsf -> code , expect_code , "unexpected error code" );
27
- #else
28
- zassert_equal (z_x86_exception_vector , IV_CTRL_PROTECTION_EXCEPTION ,
29
- "unexpected exception" );
30
- zassert_equal (pEsf -> errorCode , expect_code , "unexpected error code" );
31
- #endif
32
- printk ("fatal error expected as part of test case\n" );
33
- expect_fault = false;
73
+ void intr_handler (const void * p )
74
+ {
75
+ printk ("interrupt handler\n" );
76
+
77
+ if (p != NULL ) {
78
+ /* Test one nested level. It should just work. */
79
+ printk ("trying interrupt handler\n" );
80
+ irq_offload (intr_handler , NULL );
81
+
82
+ k_sem_give ((struct k_sem * )p );
34
83
} else {
35
- printk ("fatal error was unexpected, aborting\n" );
36
- TC_END_REPORT (TC_FAIL );
37
- k_fatal_halt (reason );
84
+ printk ("interrupt handler nested\n" );
38
85
}
39
86
}
40
87
88
+ void thread_b_entry (void * p1 , void * p2 , void * p3 )
89
+ {
90
+ k_sem_take (& thread_b_sem , K_FOREVER );
91
+
92
+ irq_offload (intr_handler , & thread_b_irq_sem );
93
+
94
+ k_sem_take (& thread_b_irq_sem , K_FOREVER );
95
+ }
96
+
97
+ ZTEST (cet , test_shstk_irq )
98
+ {
99
+ k_thread_start (thread_b );
100
+
101
+ k_sem_give (& thread_b_sem );
102
+
103
+ k_thread_join (thread_b , K_FOREVER );
104
+ }
105
+
106
+ void thread_a_entry (void * p1 , void * p2 , void * p3 )
107
+ {
108
+ k_sem_take (& thread_a_sem , K_FOREVER );
109
+
110
+ fail ();
111
+
112
+ zassert_unreachable ("should not reach here" );
113
+ }
114
+
115
+ ZTEST (cet , test_shstk )
116
+ {
117
+ k_thread_start (thread_a );
118
+
119
+ expect_fault = true;
120
+ expect_code = CTRL_PROTECTION_ERRORCODE_NEAR_RET ;
121
+ expect_reason = IV_CTRL_PROTECTION_EXCEPTION ;
122
+ k_sem_give (& thread_a_sem );
123
+
124
+ k_sem_take (error_handler_sem , K_FOREVER );
125
+ k_thread_abort (thread_a );
126
+ }
127
+ #endif /* CONFIG_HW_SHADOW_STACK */
128
+
129
+ #ifdef CONFIG_X86_CET_IBT
130
+ extern int should_work (int a );
131
+ extern int should_not_work (int a );
132
+
41
133
/* Round trip to trick optimisations and ensure the calls are indirect */
42
134
int do_call (int (* func )(int ), int a )
43
135
{
@@ -50,8 +142,10 @@ ZTEST(cet, test_ibt)
50
142
51
143
expect_fault = true;
52
144
expect_code = CTRL_PROTECTION_ERRORCODE_ENDBRANCH ;
145
+ expect_reason = IV_CTRL_PROTECTION_EXCEPTION ;
53
146
do_call (should_not_work , 1 );
54
147
zassert_unreachable ("should_not_work did not fault" );
55
148
}
149
+ #endif /* CONFIG_X86_CET_IBT */
56
150
57
151
ZTEST_SUITE (cet , NULL , NULL , NULL , NULL , NULL );
0 commit comments