Simplex:利用英特尔MPX实现安全存储
立即解锁
发布时间: 2025-08-31 01:25:07 阅读量: 7 订阅数: 15 AIGC 

# Simplex:利用英特尔 MPX 实现安全存储
## 1. 背景与现状
在信息安全领域,保护敏感数据不被攻击者获取是至关重要的。以往,为了向攻击者隐藏信息,主要有以下三种选择:
1. **内核或特权模式页面存储**:将信息存储在内核或只能在特权硬件模式下访问的页面中。只要操作系统未被破坏,这种方法是安全的。但缺点是每次查询或更新都需要额外的上下文切换,严重影响性能。
2. **程序地址空间隐藏区域存储**:把信息存储在程序地址空间的隐藏区域。这种方式性能较好,但依赖概率性隐藏措施。如果攻击者了解隐藏信息的类型,或者能够承受搜索过程中的崩溃和重启,这种方法就可能失效。
3. **预留寄存器存储**:从编译器的分配池中预留寄存器,专门用于存储敏感数据。一旦选定寄存器,防御者可以通过形式化验证确保没有其他代码访问这些寄存器,从而保证安全性。然而,可用寄存器数量有限,可能会与其他防御机制或动态链接代码产生冲突。
## 2. Simplex 编译相关
### 2.1 手动修改的局限性
在评估过程中,手动将全局指针对象及其引用/解引用语句替换为使用边界寄存器的必要代码,这种方式缺乏可扩展性。以 SPEC CPU2017 基准测试为例:
| 基准测试 | 代码行数(KLOC) | 修改次数 |
| ---- | ---- | ---- |
| 519.lbm | 1 | 22 |
| 531.deepsjeng | 10 | 173 |
| 502.gcc | 1300 | - |
| 526.blender | 1600 | - |
可以看到,对于较小的代码库,手动修改就需要耗费大量的开发时间和精力。如果代码规模和修改复杂度进一步增加,手动实现大型基准测试将变得不可行。
### 2.2 基于 Clang 注解系统的编译方案
为了解决手动修改的问题,设计了一个使用 Clang 注解系统的方案,但尚未实现。该方案的流程如下:
1. **开发者注解**:开发者在变量声明处应用必要的注解。
2. **编译器映射**:编译器识别注解,根据变量大小将其映射到一个边界寄存器。如果没有可用的寄存器空间,将抛出编译错误。
3. **函数调用替换**:编译器将对这些变量的引用替换为适当的 Simplex 函数调用。如果变量是左值,将替换为调用其中一个修改器函数;如果是右值,则替换为调用其中一个访问器函数。
### 2.3 开发者注解与自动发现的权衡
开发者注解能够精确捕捉软件设计中与安全相关的重要信息,但开发者容易出错。因此,推荐三种操作模式,以平衡安全性和性能:
- **白名单模式**:允许开发者将安全敏感数据列入白名单,由编译器将其存储在 MPX 边界寄存器中。这是最保守、性能友好但容易出错的选项。
- **自动推断模式**:编译器采用启发式方法自动分析和识别安全敏感信息,并相应地分配 MPX 边界寄存器来管理这些敏感数据。例如,识别有安全敏感文档记录的 API 函数,并进行反向切片以确定感兴趣的数据。这是最激进的选项,更侧重于安全性而非性能。
- **黑名单模式**:作为中间选项,允许开发者定义不应存储在 MPX 寄存器中的数据项。虽然黑名单和白名单一样容易出现人为错误,但与白名单中的错误相比,它对安全性的不利影响可能较小。
## 3. MPX 上下文行为
### 3.1 进程创建时的上下文继承
在进程创建时,子进程会继承与父进程相同的 MPX 上下文,因为 MPX 上下文本身是更大的 CPU 上下文的一部分。
### 3.2 重复初始化的影响
Simplex 提供了初始化和结束其最小 MPX 上下文的方法。如果程序员或攻击者多次调用这些方法(无论是意外还是恶意),每次 MPX 上下文初始化时,边界寄存器的下限将被设置为系统最大无符号值,上限将被设置为 0。在 MPX 的设计用例中,这会确保在边界寄存器设置为某个分配
0
0
复制全文
相关推荐









