@@ -112,69 +112,69 @@ pub enum ShadowStackInit {
112112 Exception ,
113113}
114114
115+ struct ShadowStackInitializer < ' a > {
116+ page : & ' a PageRef ,
117+ top_of_stack : VirtAddr ,
118+ stack_ptr : usize ,
119+ }
120+
121+ impl < ' a > ShadowStackInitializer < ' a > {
122+ fn new ( page : & ' a PageRef , top_of_stack : VirtAddr ) -> Self {
123+ Self {
124+ page,
125+ top_of_stack,
126+ stack_ptr : PAGE_SIZE ,
127+ }
128+ }
129+
130+ fn push ( & mut self , value : usize ) {
131+ let buf = value. to_ne_bytes ( ) ;
132+ self . stack_ptr -= buf. len ( ) ;
133+ self . page . write ( self . stack_ptr , & buf) ;
134+ }
135+
136+ fn push_token ( & mut self , offset : usize , mask : usize ) -> VirtAddr {
137+ let token_offset = PAGE_SIZE - self . stack_ptr + size_of :: < usize > ( ) ;
138+ let token_addr = self . top_of_stack - token_offset;
139+ let token = ( token_addr + offset) . bits ( ) | mask;
140+ self . push ( token) ;
141+ token_addr
142+ }
143+ }
144+
115145pub fn init_shadow_stack (
116146 page : & PageRef ,
117147 top_of_sstack : VirtAddr ,
118148 init : ShadowStackInit ,
119149) -> ( Option < VirtAddr > , VirtAddr ) {
120150 // Initialize the shadow stack.
121- let mut chunk = [ 0 ; 32 ] ;
122- let ( base_token_addr , ssp , len ) = match init {
151+ let mut shadow_stack = ShadowStackInitializer :: new ( page , top_of_sstack ) ;
152+ match init {
123153 ShadowStackInit :: Normal {
124154 entry_return,
125155 exit_return,
126156 iret_frame,
127157 } => {
128- let base_token_addr = top_of_sstack - 8 ;
129- let ( token_bytes, rip_bytes) = chunk. split_at_mut ( 8 ) ;
158+ let base_token_addr = match iret_frame {
159+ true => Some ( shadow_stack. push_token ( 0 , BUSY ) ) ,
160+ false => Some ( top_of_sstack - 8 ) ,
161+ } ;
130162
131- let len: usize = if iret_frame { 32 } else { 24 } ;
163+ shadow_stack. push ( exit_return) ;
164+ shadow_stack. push ( entry_return) ;
132165
133- // Create a shadow stack restore token.
134- let token_addr = top_of_sstack - len;
135- let token = ( token_addr + 8 ) . bits ( ) + MODE_64BIT ;
136- token_bytes. copy_from_slice ( & token. to_ne_bytes ( ) ) ;
166+ let token_addr = shadow_stack. push_token ( size_of :: < usize > ( ) , MODE_64BIT ) ;
137167
138- let ( entry_bytes, base_bytes) = rip_bytes. split_at_mut ( 8 ) ;
139- entry_bytes. copy_from_slice ( & entry_return. to_ne_bytes ( ) ) ;
140-
141- let ( exit_bytes, bottom_bytes) = base_bytes. split_at_mut ( 8 ) ;
142- exit_bytes. copy_from_slice ( & exit_return. to_ne_bytes ( ) ) ;
143-
144- if iret_frame {
145- // If iret_frame is true, then this thread will be used as a
146- // user task stack. In that case, place a busy token at the
147- // base of the shadow stack.
148- let base_token = base_token_addr. bits ( ) + BUSY ;
149- bottom_bytes. copy_from_slice ( & base_token. to_ne_bytes ( ) ) ;
150- }
151-
152- ( Some ( base_token_addr) , token_addr, len)
168+ ( base_token_addr, token_addr)
153169 }
154170 ShadowStackInit :: ContextSwitch => {
155- let ( _, token_bytes) = chunk. split_at_mut ( 24 ) ;
156-
157- // Create a shadow stack restore token.
158- let token_addr = top_of_sstack - 8 ;
159- let token = ( token_addr + 8 ) . bits ( ) + MODE_64BIT ;
160- token_bytes. copy_from_slice ( & token. to_ne_bytes ( ) ) ;
161-
162- ( None , token_addr, 32 )
171+ let token_addr = shadow_stack. push_token ( size_of :: < usize > ( ) , MODE_64BIT ) ;
172+ ( None , token_addr)
163173 }
164174 ShadowStackInit :: Exception => {
165- let ( _, token_bytes) = chunk. split_at_mut ( 24 ) ;
166-
167- // Create a supervisor shadow stack token.
168- let token_addr = top_of_sstack - 8 ;
169- let token = token_addr. bits ( ) ;
170- token_bytes. copy_from_slice ( & token. to_ne_bytes ( ) ) ;
171-
172- ( None , token_addr, 32 )
175+ let token_addr = shadow_stack. push_token ( 0 , 0 ) ;
176+ ( None , token_addr)
173177 }
174- ShadowStackInit :: Init => ( None , top_of_sstack - 8 , 24 ) ,
175- } ;
176-
177- page. write ( PAGE_SIZE - len, & chunk[ ..len] ) ;
178-
179- ( base_token_addr, ssp)
178+ ShadowStackInit :: Init => ( None , top_of_sstack - 8 ) ,
179+ }
180180}
0 commit comments