forked from NRZCode/ia32-64
171 lines
7.3 KiB
HTML
171 lines
7.3 KiB
HTML
<!DOCTYPE html>
|
||
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" xmlns:x86="http://www.felixcloutier.com/x86"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="style.css"></link><title>RSTORSSP
|
||
— Restore Saved Shadow Stack Pointer</title></head><body><header><nav><ul><li><a href='index.html'>Index</a></li><li>December 2023</li></ul></nav></header><h1>RSTORSSP
|
||
— Restore Saved Shadow Stack Pointer</h1>
|
||
|
||
<table>
|
||
<tr>
|
||
<th>Opcode/Instruction</th>
|
||
<th>Op/En</th>
|
||
<th>64/32 bit Mode Support</th>
|
||
<th>CPUID Feature Flag</th>
|
||
<th>Description</th></tr>
|
||
<tr>
|
||
<td>F3 0F 01 /5 (mod!=11, /5, memory only) RSTORSSP m64</td>
|
||
<td>M</td>
|
||
<td>V/V</td>
|
||
<td>CET_SS</td>
|
||
<td>Restore SSP.</td></tr></table>
|
||
<h2 id="instruction-operand-encoding">Instruction Operand Encoding<a class="anchor" href="#instruction-operand-encoding">
|
||
¶
|
||
</a></h2>
|
||
<table>
|
||
<tr>
|
||
<th>Op/En</th>
|
||
<th>Operand 1</th>
|
||
<th>Operand 2</th>
|
||
<th>Operand 3</th>
|
||
<th>Operand 4</th></tr>
|
||
<tr>
|
||
<td>M</td>
|
||
<td>ModRM:r/m (r, w)</td>
|
||
<td>N/A</td>
|
||
<td>N/A</td>
|
||
<td>N/A</td></tr></table>
|
||
<h2 id="description">Description<a class="anchor" href="#description">
|
||
¶
|
||
</a></h2>
|
||
<p>Restores SSP from the shadow-stack-restore token pointed to by m64. If the SSP restore was successful then the instruction replaces the shadow-stack-restore token with a previous-ssp token. The instruction sets the CF flag to indicate whether the SSP address recorded in the shadow-stack-restore token that was processed was 4 byte aligned, i.e., whether an alignment hole was created when the restore-shadow-stack token was pushed on this shadow stack.</p>
|
||
<p>Following RSTORSSP if a restore-shadow-stack token needs to be saved on the previous shadow stack, use the SAVEPREVSSP instruction.</p>
|
||
<p>If pushing a restore-shadow-stack token on the previous shadow stack is not required, the previous-ssp token can be popped using the INCSSPQ instruction. If the CF flag was set to indicate presence of an alignment hole, an additional INCSSPD instruction is needed to advance the SSP past the alignment hole.</p>
|
||
<h2 id="operation">Operation<a class="anchor" href="#operation">
|
||
¶
|
||
</a></h2>
|
||
<pre>IF CPL = 3
|
||
IF (CR4.CET & IA32_U_CET.SH_STK_EN) = 0
|
||
THEN #UD; FI;
|
||
ELSE
|
||
IF (CR4.CET & IA32_S_CET.SH_STK_EN) = 0
|
||
THEN #UD; FI;
|
||
FI;
|
||
SSP_LA = Linear_Address(mem operand)
|
||
IF SSP_LA not aligned to 8 bytes
|
||
THEN #GP(0); FI;
|
||
previous_ssp_token = SSP | (IA32_EFER.LMA AND CS.L) | 0x02
|
||
Start Atomic Execution
|
||
restore_ssp_token = Locked shadow_stack_load 8 bytes from SSP_LA
|
||
fault = 0
|
||
IF ((restore_ssp_token & 0x03) != (IA32_EFER.LMA & CS.L))
|
||
THEN fault = 1; FI; (* If L flag in token does not match IA32_EFER.LMA & CS.L or bit 1 is not 0 *)
|
||
IF ((IA32_EFER.LMA AND CS.L) = 0 AND restore_ssp_token[63:32] != 0)
|
||
THEN fault = 1; FI; (* If compatibility/legacy mode and SSP to be restored not below 4G *)
|
||
TMP = restore_ssp_token & ~0x01
|
||
TMP = (TMP - 8)
|
||
TMP = TMP & ~0x07
|
||
IF TMP != SSP_LA
|
||
THEN fault = 1; FI; (* If address in token does not match the requested top of stack *)
|
||
TMP = (fault == 0) ? previous_ssp_token : restore_ssp_token
|
||
shadow_stack_store 8 bytes of TMP to SSP_LA and release lock
|
||
End Atomic Execution
|
||
IF fault == 1
|
||
THEN #CP(RSTORSSP); FI;
|
||
SSP = SSP_LA
|
||
// Set the CF if the SSP in the restore token was 4 byte aligned, i.e., there is an alignment hole
|
||
RFLAGS.CF = (restore_ssp_token & 0x04) ? 1 : 0;
|
||
RFLAGS.ZF,PF,AF,OF,SF := 0;
|
||
</pre>
|
||
<h2 id="flags-affected">Flags Affected<a class="anchor" href="#flags-affected">
|
||
¶
|
||
</a></h2>
|
||
<p>CF is set to indicate if the shadow stack pointer in the restore token was 4 byte aligned, else it is cleared. ZF, PF, AF, OF, and SF are cleared.</p>
|
||
<h2 id="c-c++-compiler-intrinsic-equivalent">C/C++ Compiler Intrinsic Equivalent<a class="anchor" href="#c-c++-compiler-intrinsic-equivalent">
|
||
¶
|
||
</a></h2>
|
||
<pre>RSTORSSP void _rstorssp(void *);
|
||
</pre>
|
||
<h2 class="exceptions" id="protected-mode-exceptions">Protected Mode Exceptions<a class="anchor" href="#protected-mode-exceptions">
|
||
¶
|
||
</a></h2>
|
||
<table>
|
||
<tr>
|
||
<td rowspan="4">#UD</td>
|
||
<td>If the LOCK prefix is used.</td></tr>
|
||
<tr>
|
||
<td>If CR4.CET = 0.</td></tr>
|
||
<tr>
|
||
<td>IF CPL = 3 and IA32_U_CET.SH_STK_EN = 0.</td></tr>
|
||
<tr>
|
||
<td>IF CPL < 3 and IA32_S_CET.SH_STK_EN = 0.</td></tr>
|
||
<tr>
|
||
<td rowspan="4">#GP(0)</td>
|
||
<td>If linear address of memory operand not 8 byte aligned.</td></tr>
|
||
<tr>
|
||
<td>If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.</td></tr>
|
||
<tr>
|
||
<td>If destination is located in a non-writeable segment.</td></tr>
|
||
<tr>
|
||
<td>If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment selector.</td></tr>
|
||
<tr>
|
||
<td>#SS(0)</td>
|
||
<td>If a memory operand effective address is outside the SS segment limit.</td></tr>
|
||
<tr>
|
||
<td rowspan="3">#CP(rstorssp)</td>
|
||
<td>If L bit in token does not match (IA32_EFER.LMA & CS.L).</td></tr>
|
||
<tr>
|
||
<td>If address in token does not match linear address of memory operand.</td></tr>
|
||
<tr>
|
||
<td>If in 32-bit or compatibility mode and the address in token is not below 4G.</td></tr>
|
||
<tr>
|
||
<td>#PF(fault-code)</td>
|
||
<td>If a page fault occurs.</td></tr></table>
|
||
<h2 class="exceptions" id="real-address-mode-exceptions">Real-Address Mode Exceptions<a class="anchor" href="#real-address-mode-exceptions">
|
||
¶
|
||
</a></h2>
|
||
<table>
|
||
<tr>
|
||
<td>#UD</td>
|
||
<td>The RSTORSSP instruction is not recognized in real-address mode.</td></tr></table>
|
||
<h2 class="exceptions" id="virtual-8086-mode-exceptions">Virtual-8086 Mode Exceptions<a class="anchor" href="#virtual-8086-mode-exceptions">
|
||
¶
|
||
</a></h2>
|
||
<table>
|
||
<tr>
|
||
<td>#UD</td>
|
||
<td>The RSTORSSP instruction is not recognized in virtual-8086 mode.</td></tr></table>
|
||
<h2 class="exceptions" id="compatibility-mode-exceptions">Compatibility Mode Exceptions<a class="anchor" href="#compatibility-mode-exceptions">
|
||
¶
|
||
</a></h2>
|
||
<p>Same as protected mode exceptions.</p>
|
||
<h2 class="exceptions" id="64-bit-mode-exceptions">64-Bit Mode Exceptions<a class="anchor" href="#64-bit-mode-exceptions">
|
||
¶
|
||
</a></h2>
|
||
<table>
|
||
<tr>
|
||
<td rowspan="4">#UD</td>
|
||
<td>If the LOCK prefix is used.</td></tr>
|
||
<tr>
|
||
<td>If CR4.CET = 0.</td></tr>
|
||
<tr>
|
||
<td>If CPL = 3 and IA32_U_CET.SH_STK_EN = 0.</td></tr>
|
||
<tr>
|
||
<td>If CPL < 3 and IA32_S_CET.SH_STK_EN = 0.</td></tr>
|
||
<tr>
|
||
<td rowspan="2">#GP(0)</td>
|
||
<td>If linear address of memory operand not 8 byte aligned.</td></tr>
|
||
<tr>
|
||
<td>If a memory address is in a non-canonical form.</td></tr>
|
||
<tr>
|
||
<td>#SS(0)</td>
|
||
<td>If a memory address referencing the SS segment is in a non-canonical form.</td></tr>
|
||
<tr>
|
||
<td rowspan="2">#CP(rstorssp)</td>
|
||
<td>If L bit in token does not match (IA32_EFER.LMA & CS.L).</td></tr>
|
||
<tr>
|
||
<td>If address in token does not match linear address of memory operand.</td></tr>
|
||
<tr>
|
||
<td>#PF(fault-code)</td>
|
||
<td>If a page fault occurs.</td></tr></table><footer><p>
|
||
This UNOFFICIAL, mechanically-separated, non-verified reference is provided for convenience, but it may be
|
||
inc<span style="opacity: 0.2">omp</span>lete or b<sub>r</sub>oke<sub>n</sub> in various obvious or non-obvious
|
||
ways. Refer to <a href="https://software.intel.com/en-us/download/intel-64-and-ia-32-architectures-sdm-combined-volumes-1-2a-2b-2c-2d-3a-3b-3c-3d-and-4">Intel® 64 and IA-32 Architectures Software Developer’s Manual</a> for anything serious.
|
||
</p></footer></body></html>
|