Intel SGX -- The Life Cycle of an SGX Enclave

发布时间:2024年01月03日

前言

本文来自 Intel SGX Explained

一、The Life Cycle of an SGX Enclave

一个Enclave的生命周期与资源管理密切相关,特别是与EPC页面的分配相关。因此,只有系统软件才能执行在不同生命周期状态之间转换的指令。系统软件被期望将下面描述的SGX指令作为Enclave加载和拆除服务来提供。

接下来描述了飞地生命周期中的主要步骤,SGX飞地生命周期管理说明和状态转换图如下所示:
在这里插入图片描述

1.1 Creation

创建Enclave时,系统软件使用ECREATE指令将一个空闲的EPC页面转换为新Enclave的SECS(Secure Enclave Control Structure,安全Enclave控制结构)。
在这里插入图片描述
ECREATE指令使用系统软件拥有的非EPC页面中的信息初始化新创建的SECS。这个页面指定了SDM中定义的所有SECS字段的值,例如BASEADDR和SIZE。使用一种体系结构级别的布局,确保这些值在未来的实现中得到保留。

在ECREATE指令执行之前,系统软件需要准备一个非EPC页面,其中包含了要初始化SECS的所有字段的值。这些字段包括Enclave的基地址(BASEADDR)、大小(SIZE)、属性(ATTRIBUTES)等。

实际上,初始的SGX实现很可能与体系结构的SECS布局非常接近,但未来的实现可以自由地偏离这个布局,只要它们能够使用体系结构布局来初始化SECS即可。软件无法访问包含SECS的EPC页面,因此不能依赖于SECS的内部布局。这是一种更强的封装性,类似于虚拟机控制结构(VMCS)中使用的封装性。

ECREATE指令对用于初始化SECS的信息进行验证,如果信息无效,将导致页面错误(#PF)或通用保护错误(#GP)。例如,如果SIZE字段不是2的幂次方,ECREATE指令将导致#GP错误。这种验证机制,结合SECS对软件不可访问的特性,简化了其他SGX指令的实现,这些指令可以假设SECS内部的信息是有效的。

最后,ECREATE指令将Enclave的INIT属性(在Enclave的SECS中的ATTRIBUTES字段的子字段)初始化为false值。在INIT属性设置为true之前,Enclave的代码无法执行。INIT属性的设置发生在初始化阶段。

1.2 Loading

ECREATE指令将新创建的SECS标记为未初始化状态。在Enclave的SECS处于此状态时,系统软件可以使用EADD指令将初始代码和数据加载到Enclave中。EADD指令用于创建TCS页面和普通页面。
在这里插入图片描述
EADD指令从一个Page Information(PAGEINFO)结构中读取输入数据,该结构的示例在下图中展示。该结构的内容仅用于与SGX实现之间的信息交流,因此它完全是体系结构相关的,并在SDM(Software Developer’s Manual)中有详细的文档说明。
在这里插入图片描述
PAGINFO结构将输入数据提供给诸如EADD之类的SGX指令。

PAGINFO结构的布局如下(PAGINFO是一种体系结构数据结构,用作EPC管理指令的参数。它需要32字节对齐。):
在这里插入图片描述
当前,PAGEINFO结构包含以下内容:将被分配的EPC页面的虚拟地址(LINADDR),要复制到新分配的EPC页面中的非EPC页面的虚拟地址(SRCPGE),解析为将拥有该页面的Enclave的SECS的虚拟地址(SECS),以及与新分配的EPC页面相关联的EPCM条目的一些字段的值(SECINFO)。

具体而言,这些字段的含义如下:
(1)LINADDR:该字段指定将被分配的EPC页面的虚拟地址。EPC(Enclave Page Cache)页面是受保护的内存页面,用于存储Enclave的代码和数据。
(2)SRCPGE:该字段指定要复制到新分配的EPC页面中的非EPC页面的虚拟地址。这个非EPC页面可以包含Enclave所需的代码或数据。
(3)SECS:该字段是一个虚拟地址,解析为将拥有新分配页面的Enclave的SECS(Secure Enclave Control Structure)。SECS是Enclave的一个关键数据结构,用于管理Enclave的状态和安全属性。
(4)SECINFO:该字段包含了与新分配的EPC页面相关联的EPCM(Enclave Page Cache Map)条目的一些字段的值。EPCM是一个数据结构,用于跟踪和管理EPC页面的状态和属性。

这些字段提供了给SGX指令(如EADD)所需的输入数据,以完成相应的操作。通过指定将被分配的EPC页面的虚拟地址、要复制的非EPC页面的虚拟地址、将拥有页面的Enclave的SECS的虚拟地址,以及新分配的EPC页面的相关字段值,SGX实施可以正确地分配和管理EPC页面,并将所需的内容从非EPC页面复制到新分配的EPC页面中。

在PAGEINFO结构中,SECINFO字段实际上是一个虚拟内存地址,指向一个安全信息(SECINFO)结构,其中部分内容也在上图中进行了说明。SECINFO结构包含了新分配的EPC页面的访问权限(R、W、X)和EPCM页面类型(PT_REG或PT_TCS)。与PAGEINFO类似,SECINFO结构仅用于向SGX实现传递数据,因此其内容完全是按照体系结构定义的。然而,该结构的大部分64字节都保留供将来使用。

PAGEINFO和SECINFO结构都是由调用EADD指令的系统软件准备的,因此它们必须包含在非EPC页面中。这两个结构必须按照它们的大小进行对齐。PAGEINFO结构长度为32字节,因此每个PAGEINFO实例必须按32字节对齐,而SECINFO结构长度为64字节,因此每个SECINFO实例必须按64字节对齐。对齐要求可以简化SGX实施,减少需要处理的特殊情况数量。

在修改新分配的EPC页面或其EPCM条目之前,EADD指令会对其输入进行验证。最重要的是,如果尝试将页面添加到SECS处于初始化状态的Enclave中,将导致#GP异常。此外,如果尝试添加已经分配的EPC页面(其EPCM条目中的VALID字段为1),将导致#PF异常。EADD还确保页面的虚拟地址位于Enclave的ELRANGE范围内,并且SECINFO中的所有保留字段都设置为零。

在加载Enclave时,系统软件还会使用EEXTEND指令,该指令更新在软件认证过程中使用的Enclave measurement(测量值)。
在这里插入图片描述

1.3 Initialization

在将初始代码和数据页面加载到Enclave之后,系统软件必须使用Launch Enclave (LE)操作来获取一个EINIT令牌结构,通过一个文档不充分描述的过程。然后,该令牌被提供给EINIT指令,该指令将Enclave的SECS标记为已初始化。

LE是由Intel提供的特权Enclave,是使用非Intel方编写的Enclave的先决条件。LE是一个SGX Enclave,因此必须使用本节中描述的过程创建、加载和初始化。然而,LE是使用一个特殊的Intel密钥进行加密签名,该密钥被硬编码到SGX实现中,这导致EINIT在初始化LE时不检查有效的EINIT令牌结构。

当EINIT成功完成时,它将Enclave的INIT属性设置为true。这为Ring 3应用程序软件执行Enclave的代码打开了通道,使用了在第2节中描述的SGX指令。另一方面,一旦INIT被设置为true,就不能再对该Enclave调用EADD指令,因此系统软件必须在执行EINIT指令之前加载构成Enclave初始状态的所有页面。

Enclave的INIT属性用于表示Enclave是否已成功初始化和准备好执行。一旦INIT属性被设置为true,Enclave被认为是可执行的,并且Ring 3应用程序可以通过SGX指令与Enclave进行交互。

然而,一旦Enclave的INIT属性被设置为true,就不能再使用EADD指令向Enclave添加新的页面。因此,在执行EINIT指令之前,系统软件必须确保将构成Enclave初始状态的所有页面加载到Enclave中,以确保Enclave在初始化完成后能够正确执行所需的操作。

这种限制确保了Enclave的完整性和安全性。通过要求在初始化之前加载所有页面,可以防止在Enclave初始化后动态修改其初始状态。这有助于保护Enclave的安全性和可信度。

1.4 Teardown

在Enclave完成其设计用于执行的计算后,系统软件执行EREMOVE指令来释放Enclave使用的EPC页面。

EREMOVE指令通过将页面的EPCM(Enclave Page Cache Map)条目的VALID字段设置为0(零),将EPC页面标记为可用。在释放页面之前,EREMOVE确保没有任何逻辑处理器正在执行属于要被移除的Enclave的代码。

在这里插入图片描述
当包含Enclave的SECS(Secure Enclave Control Structure)的EPC页面被释放时,Enclave将完全被销毁。EREMOVE指令在SECS页面被其他EPCM条目的ENCLAVESECS字段引用时,拒绝释放SECS页面,因此只有在所有Enclave页面被释放后,才能释放Enclave的SECS页面。

二、The Life Cycle of an SGX Thread

在上面的第1.3 Enclave Initialization 和第1.4 Teardown之间的时间段内,任何将Enclave的EPC页面映射到其虚拟地址空间的应用程序进程都可以执行Enclave的代码。

一旦Enclave被初始化并且其EPC页面被分配和映射到应用程序进程的虚拟地址空间,该进程就可以执行Enclave中的代码。这意味着应用程序可以调用Enclave中定义的函数、执行Enclave中的指令和访问Enclave中的数据。

当逻辑处理器执行Enclave内部的代码时,被称为处于"enclave mode"(Enclave模式),它所执行的代码可以访问当前执行的Enclave所属的常规EPC页面(PT_REG)。当逻辑处理器处于Enclave模式之外时,它会将任何内存访问反弹回处理器保留内存范围(PRM),其中包括EPC。

当逻辑处理器处于Enclave模式之外时,它无法直接访问EPC页面。这是为了确保对EPC页面的访问受到严格的限制和控制,防止非授权的访问或篡改。当逻辑处理器尝试访问EPC页面时,它会被重定向到处理器保留内存范围(PRM),其中包括EPC。这样可以防止非授权的进程或代码访问Enclave的敏感数据或破坏Enclave的安全性。

每个执行Enclave代码的逻辑处理器都使用一个线程控制结构(TCS,§ 5.2.4)。当一个TCS被逻辑处理器使用时,它被认为是忙碌的,并且不能被其他逻辑处理器使用。下图说明了主机进程用于执行Enclave代码的指令以及它们与目标TCS之间的交互:
在这里插入图片描述
SGX线程控制结构(TCS)生命周期的各个阶段,该结构具有两个状态保存区(SSA)。

假设没有硬件异常发生,Enclave的主机进程使用EENTER指令来执行Enclave代码。当Enclave代码完成其任务后,它使用EEXIT指令将执行控制权返回给调用Enclave的主机进程。

如果逻辑处理器在Enclave模式下发生硬件异常,系统会使用异步Enclave退出(AEX),在调用系统软件的异常处理程序之前将处理器从Enclave模式中退出。在调用系统软件的异常处理程序后,Enclave的主机进程可以使用ERESUME指令重新进入Enclave并恢复之前的计算任务。

一旦系统软件的异常处理程序完成处理并确定Enclave可以继续执行,Enclave的主机进程可以使用ERESUME指令。该指令允许主机进程重新进入Enclave,并恢复之前由硬件异常中断的计算任务。ERESUME指令携带了必要的参数和状态信息,以便从异常发生的地方继续执行,无需重新初始化Enclave或重新执行之前的操作。

在这里插入图片描述

2.1 Synchronous Enclave Entry

在高层次上,EENTER指令执行了一个受控的跳转进入Enclave代码,并进行了SGX安全保证所需的处理器配置。
在这里插入图片描述
EENTER指令是SGX中的一个关键指令,用于将执行控制从主机进程转移到Enclave代码中的入口点。该指令在执行跳转之前会执行一系列的处理器配置和安全检查,以确保Enclave的安全性和隔离性。

EENTER指令,如下图所示,只能由在Ring 3上运行的非特权应用软件执行,如果由系统软件执行,会导致未定义指令(#UD)故障。
在这里插入图片描述
上图是EENTER中逻辑子集的数据流图。

EENTER指令将逻辑处理器切换到Enclave模式,但不执行特权级别切换。因此,Enclave代码始终在Ring 3上执行,具有与调用它的应用代码相同的特权级别。这使得基础设施所有者可以允许用户提供的软件创建和使用Enclave,同时确保操作系统内核和虚拟化监控程序仍然可以保护基础设施免受有缺陷或恶意软件的影响。

EENTER指令以一个TCS的虚拟地址作为输入,并要求TCS可用(非忙碌状态),并且在TCS中至少有一个状态保存区(SSA)可用。后者的检查是通过确保TCS中当前SSA索引(CSSA)字段小于SSA数量(NSSA)字段来实现的。CSSA所指示的SSA被称为当前SSA,在执行Enclave代码时,如果发生硬件异常,将使用当前SSA。

EENTER指令将逻辑处理器转换为Enclave模式,并将指令指针(RIP)设置为所接收TCS中的入口点偏移(OENTRY)字段指示的值。EENTER指令被一个不可信的调用方用于在受保护的环境中执行代码,因此与用于调用系统软件的SYSCALL指令具有相同的安全考虑。将RIP设置为OENTRY指示的值,确保了Enclave代码只会在定义良好的点上被调用,并防止恶意的主机应用程序绕过Enclave作者可能执行的任何安全检查。

EENTER指令还会设置XCR0寄存器,该寄存器用于控制使用的扩展架构特性,将其设置为XFRM(Enclave属性)字段的值。通过确保根据Enclave作者的意图设置XCR0寄存器,可以防止恶意操作系统通过启用Enclave无法处理的架构特性来绕过Enclave的安全性。

此外,EENTER指令会使用TCS中指定的值加载段寄存器FS和GS的基址。这些段的选择子和类型被硬编码为适用于Ring 3数据段的安全值。SGX设计的这个方面使得实现每个线程的线程本地存储(TLS)变得简单。对于64位的Enclave来说,这是一项便利功能,而不是一项安全措施,因为Enclave代码可以使用WRFSBASE和WRGSBASE指令安全地加载新的FS和GS基址。

EENTER指令的实现会备份修改的寄存器的旧值,以便在Enclave完成计算后可以恢复它们。与SYSCALL指令类似,EENTER指令将紧随其后的指令的地址保存在RCX寄存器中。

根据SDM(Software Developer’s Manual)的说明,XCR0、FS和GS寄存器的旧值被保存在专门用于SGX实现的新寄存器中。然而,考虑到这些值只会在Enclave退出时使用,我们可以预期这些寄存器的值将被保存在DRAM中,即TCS中的保留区域。

为了确保Enclave的执行状态在退出后可以正确地恢复,SGX实现会将修改前的XCR0、FS和GS寄存器的值保存在专门的寄存器中。这些寄存器的内容最终会被存储在Enclave的TCS(Thread Control Structure)中,TCS是一个在内存中分配给Enclave的数据结构,用于管理Enclave的状态信息。

与SYSCALL指令类似,EENTER指令不会修改堆栈指针寄存器(RSP)。为了避免任何安全漏洞,Enclave代码应该将RSP设置为指向完全包含在EPC(Enclave Page Cache)页面中的堆栈区域。多线程Enclave可以通过设置每个线程的TLS(Thread Local Storage)区域来实现每个线程的堆栈区域,并通过将RSP设置为通过读取FS或GS段所指向的TLS区域获取的值来进行设置。

当EENTER进入Enclave模式时,它会暂停一些处理器的调试功能,例如硬件断点和精确事件基础采样(PEBS)。从概念上讲,附加在主机进程上的调试器将把Enclave的执行视为一个单一的处理器指令。

2.2 Synchronous Enclave Exit

EEXIT指令只能在逻辑处理器处于Enclave模式下执行,如果在其他情况下执行,将导致(#UD)异常。简而言之,该指令将处理器返回到Enclave模式之外的Ring 3,并恢复由EENTER保存的寄存器,这些寄存器已在前面描述过。

当处理器处于Enclave模式下执行EEXIT指令时,它会将处理器从Enclave模式切换回Ring 3模式,这是一种较低特权级别的操作模式。通过执行EEXIT指令,处理器离开Enclave并返回到主机环境。

在执行EEXIT指令之前,EENTER指令保存了一些寄存器的旧值,包括被修改的寄存器和紧随EENTER指令的下一条指令的地址。在执行EEXIT指令时,这些保存的寄存器值将被恢复,以确保退出Enclave后能够正确还原之前的执行状态。

在这里插入图片描述
和SYSRET不同,EEXIT在退出Enclave模式后将RIP设置为从RBX读取的值。这与EENTER的行为不一致,因为EENTER将RIP的值保存到RCX中。

这种不一致性不是SDM(软件开发者手册)中的错误,而是SGX(软件保护扩展)架构设计的一部分。

Enclave代码必须注意这种差异。当准备使用EEXIT退出Enclave时,Enclave代码应确保期望的返回地址存储在RBX寄存器中。在退出时,RBX中的值将用于设置Enclave模式之外的RIP。

另一方面,在使用EENTER进入Enclave时,Enclave代码应将期望的入口点地址提供给RCX寄存器。SGX实现将保存RCX的值作为Enclave的入口点,并在Enclave退出时使用保存的RCX值来恢复RIP。

Enclave开发人员必须注意这种不一致性,并正确处理相应的寄存器(EEXIT使用RBX,EENTER使用RCX),以确保在Enclave模式和主机环境之间进行转换时实现预期的控制流程。

SDM明确指出,EEXIT不会修改大多数寄存器,因此Enclave的作者必须确保在将控制权返回给主机进程之前清除存储在处理器寄存器中的任何机密信息。此外,如果Enclave软件不将堆栈指针RSP和堆栈帧基指针RBP恢复为调用EENTER时的值,它很可能会导致其调用者出现故障。

Enclave代码可能会导致其调用者产生故障,这可能是不太幸运的。无论好坏,这与应用程序调用动态加载模块的情况完全匹配。更具体地说,模块的代码也负责保留与堆栈相关的寄存器,而有错误的模块可能会跳转到主机进程的任意应用程序代码位置。

本节描述的是64位Enclave的EENTER行为。由于32位Intel架构中仍存在全面的分段模型,32位Enclave的EENTER实现要复杂得多,并引入了额外的特殊情况。正如介绍中所述,我们对这种遗留的特性不感兴趣。

2.3 Asynchronous Enclave Exit (AEX)

如果在逻辑处理器执行飞地代码时发生硬件异常,如 fault 或 interrupt ,则处理器在调用系统软件的异常处理程序之前执行异步飞地退出(AEX),如图所示:
在这里插入图片描述
上图表明了如果在飞地执行过程中发生了硬件异常,同步执行路径会被中止,而将会发生一个异步飞地退出(Asynchronous Enclave Exit,AEX)。

异步飞地退出(AEX)会保存飞地代码的执行上下文(execution context),恢复由 EENTER 保存的状态,并设置处理器寄存器,以便系统软件的硬件异常处理程序返回到飞地所在的主进程的异步退出处理程序。

退出处理程序被期望使用 ERESUME 指令来恢复被硬件异常中断的飞地计算。这意味着在处理完硬件异常后,退出处理程序会使用 ERESUME 指令重新启动飞地的计算,使其从中断的地方继续执行。

ERESUME 指令如下所示:
在这里插入图片描述
The ENCLU[ERESUME]指令用于恢复因异常或中断而中断的飞地的执行,使用之前存储在SSA(State Save Area)中的机器状态。

当飞地的执行被异常或中断打断时,处理器会将当前的机器状态保存到SSA中。这个保存的状态包括处理器寄存器的值、程序计数器、标志位等。当执行ENCLU[ERESUME]指令时,处理器会从SSA中恢复之前保存的机器状态,并继续执行飞地代码。

通过使用ENCLU[ERESUME]指令,飞地能够在中断发生之前的状态下继续执行,而无需重新初始化或重新启动。这对于保持飞地的内部状态和数据完整性非常重要,同时提供了更高的执行效率。

除了在第2.1节中描述的行为之外,EENTER指令还会将一些信息写入当前的SSA(State Save Area),这些信息只在发生AEX时使用。如图66所示,EENTER指令将栈指针寄存器RSP和栈帧基址寄存器RBP存储到当前SSA的U_RSP和U_RBP字段中。此外,EENTER指令还将RCX寄存器中的值存储到当前SSA的Asynchronous Exit handler Pointer (AEP)字段中。

当在飞地模式下发生硬件异常时,SGX实现会执行一系列步骤,将逻辑处理器从飞地模式中退出,并调用系统软件中的硬件异常处理程序。在概念上,SGX实现首先执行AEX将逻辑处理器从飞地模式中退出,然后使用标准的Intel架构行为来处理硬件异常。实际的Intel处理器可能会将AEX实现与异常处理实现交错进行。然而,为了简单起见,本文将AEX描述为在执行任何异常处理步骤之前单独执行的过程。

在Intel架构中,如果发生了硬件异常,系统软件的异常处理程序可以读取和修改应用程序代码的执行上下文。当系统软件被应用软件所信任时,这是可以接受的。然而,在SGX的安全威胁模型下,系统软件不被飞地所信任。因此,AEX步骤通过将所有寄存器重置为预定义的值,擦除了执行状态中可能存在的任何机密信息。

在重置飞地的执行状态之前,它会被备份到当前的SSA中。具体来说,AEX会将通用寄存器(GPRs)备份到SSA中的GPRSGX区域,并使用在飞地的SECS中的XFRM字段中指定的请求特征位图(RFBM)执行XSAVE指令。由于每个SSA完全存储在为飞地分配的EPC页面中,系统软件无法读取或篡改备份的执行状态。当一个SSA接收到飞地的执行状态时,通过递增当前TCS中的CSSA字段,将其标记为已使用。

在清除执行上下文之后,AEX过程会将RSP和RBP设置为当前SSA中由EENTER保存的值,并将RIP设置为当前SSA的AEP字段中的值。这样,当系统软件的硬件异常处理程序完成时,处理器将在飞地的宿主进程中执行异步退出处理程序的代码。SGX的设计使得在包含EENTER指令的程序中设置异步处理程序代码作为异常处理程序变得容易,因为RSP和RBP寄存器的值将与执行EENTER指令时的值相同。

通过将RSP和RBP恢复为EENTER保存的值,AEX确保了在异步退出处理程序执行时,栈的状态与进入飞地时的状态一致。这样,异步退出处理程序可以正确地访问和操作栈上的数据,而不会引入错误或冲突。
通过将RIP设置为当前SSA的AEP字段中的值,AEX确保了在硬件异常处理程序完成后,处理器会跳转到异步退出处理程序的代码,从而实现对异常的正确处理和恢复。

总之,AEX过程通过恢复RSP、RBP和RIP的值,确保了在异步退出处理程序中能够正确地执行代码,并在处理器返回到飞地的宿主进程后恢复飞地的执行。这种设计使得在包含EENTER指令的程序中设置异步处理程序代码作为异常处理程序变得简单和方便。

在将逻辑处理器从飞地模式中退出的过程中,AEX执行的许多操作与EEXIT相匹配。段寄存器FS和GS被恢复为EENTER保存的值,并且所有由EENTER禁用的调试功能被恢复到它们之前的状态。

AEX过程的目标是将逻辑处理器从飞地模式中转换回常规执行模式。为了实现这一目标,AEX需要执行与EEXIT相似的操作。其中一些操作包括恢复段寄存器FS和GS的值,这些值是在进入飞地时由EENTER保存的。此外,AEX还需要将被EENTER禁用的调试功能恢复到之前的状态。

2.4 Recovering from an Asynchronous Exit

当在飞地模式下发生硬件异常时,处理器会在调用系统软件设置的异常处理程序之前执行AEX。AEX设置执行上下文的方式是,当系统软件完成异常处理后,将返回到飞地的宿主进程中的异步退出处理程序。异步异常处理程序通常会执行ERESUME指令,该指令使逻辑处理器回到飞地模式,并继续被硬件异常中断的计算过程。

AEX的目的是在处理硬件异常之前保存飞地的执行状态,并确保在异常处理完成后能够正确地恢复执行。通过设置执行上下文,在异步退出处理程序中执行ERESUME指令后,逻辑处理器将返回到飞地模式,并继续中断的计算过程,从上次中断的地方继续执行。

ERESUME与EENTER共享其大部分功能。如下图所示:
在这里插入图片描述
上图说明了如果在飞地执行过程中发生硬件异常,同步执行路径会被中断,而会发生异步飞地退出(AEX)。

EENTER和ERESUME接收相同的输入,即指向TCS(Thread Control Structure,线程控制结构)的指针,这在第2.1节中有描述,以及AEP(Asynchronous Enclave Pointer,异步飞地指针),这在第2.3节中有描述。最常见的应用程序设计将每个EENTER实例与一个异步退出处理程序配对,该处理程序使用完全相同的参数调用ERESUME。

在SGX中,EENTER用于将逻辑处理器从非飞地模式切换到飞地模式,并开始执行飞地中的指令。EENTER需要一个TCS指针来指定线程控制结构,该结构包含了飞地执行所需的状态信息和数据。此外,EENTER还需要一个AEP,它是一个指向飞地中的入口点函数的指针,该函数定义了飞地的初始执行代码。

在飞地执行期间,如果需要进行异步退出操作,通常会使用异步退出处理程序。该处理程序与每个EENTER实例配对,并使用相同的TCS指针和AEP参数调用ERESUME。ERESUME的作用是将逻辑处理器从非飞地模式切换回飞地模式,并继续中断的执行过程。通过使用相同的参数,ERESUME可以确保在异步退出处理程序中正确恢复到之前的飞地执行状态,从而实现无缝的中断处理和恢复。

ERESUME和EENTER之间的主要区别在于,前者使用由AEX(第2.3节)填充的安全存储区(SSA),而后者使用一个空的SSA。因此,如果提供的TCS中的CSSA字段为0(零),ERESUME会导致#GP故障,而如果CSSA大于或等于NSSA,EENTER会失败。

当ERESUME成功时,它会将TCS中的CSSA字段减小,并将SSA中备份的执行上下文恢复到由CSSA字段指向的位置。具体来说,ERESUME实现会将GPRs(通用寄存器)从SSA中的GPRSGX字段恢复,并执行XRSTOR(扩展寄存器恢复)指令,以加载飞地使用的扩展体系结构功能相关的执行状态。

ERESUME与EENTER(第2.1节)共享以下行为。这两个指令都会写入当前SSA中的U_RSP(用户栈指针)、U_RBP(用户基址指针)和AEP(异步飞地指针)字段。两个指令在备份XCR0寄存器和FS、GS段寄存器方面遵循相同的过程,并且根据当前TCS和其飞地的SECS设置它们的值。最后,这两个指令都会禁用逻辑处理器的相同子集的调试功能。

ERESUME在处理中处理了一个有趣的边缘情况,即在执行XRSTOR之前将XCR0设置为XFRM飞地属性。因此,如果SSA中的请求特征位图(RFBM)不是XFRM的子集,ERESUME将失败。这很重要,因为虽然AEX始终将XFRM值用作RFBM,但在调用ERESUME之前,在另一个线程上执行的飞地代码可以自由地修改SSA内容。

在ERESUME的实现中,正确的操作顺序可以防止恶意应用程序使用飞地来修改与未在XFRM中声明的扩展体系结构功能相关联的寄存器。这将破坏系统软件提供线程级别执行上下文隔离的能力。

文章来源:https://blog.csdn.net/weixin_45030965/article/details/135248486
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。