1.2 CPU安全包含什么

标题的问题其实是最重要的问题。做安全,最容易回答的是一个具体的问题应该如何去做,而最难回答的问题,就是做到了哪些才能说明系统是安全的。尤其安全还是一个容易背锅的岗位,因此很多从业者也不追求搞清楚这个问题,反正相关的罗列上去,仿佛回到了考阅读理解多写字总能压上得分点的时代。正好ChatGPT很火,我们来看看他怎么说:

Info

提问: 做一个安全的CPU需要考虑哪些方面?

ChatGPT: 做一个安全的CPU需要考虑以下方面:

  1. 物理安全:确保CPU的物理安全,防止未经授权的人员接触或修改CPU。
  2. 逻辑安全:确保CPU的逻辑安全,防止未经授权的人员通过软件或硬件手段攻击CPU。
  3. 数据安全:确保CPU内部数据的安全,防止未经授权的人员获取或篡改CPU内部数据。
  4. 通信安全:确保CPU与其他设备之间的通信安全,防止未经授权的人员窃听或篡改通信数据。
  5. 软件安全:确保CPU的软件安全,防止未经授权的人员通过软件手段攻击CPU。
  6. 硬件安全:确保CPU的硬件安全,防止未经授权的人员通过硬件手段攻击CPU。
  7. 安全升级:确保CPU的安全升级,及时修复已知的安全漏洞,提高CPU的安全性能。

综上所述,做一个安全的CPU需要考虑多方面的因素,需要综合考虑物理安全、逻辑安全、数据安全、通信安全、软件安全、硬件安全以及安全升级等方面。

你看ChatGPT也是摊大饼,说明他的输入中确实没有太多这个视角的讨论。(太好了,我的工作暂时还没有被ChatGPT革命。

不过CPU需要的安全逻辑其实还是有非常多共性的,我们这里简单的从理论上讲CPU涉及到的安全知识作出大致分类,然后按照不同分类下的逻辑来逐个解释。至于真实的CPU设计如何做好安全——那可能是付费内容了。

计算域

在描述CPU安全的范围前,我们先定义一个新的概念:计算域。它指一个软件计算环境,包括软件可使用的所有资源,计算能力等。这个概念其实一般情况下表示一个软件/硬件的上下文中。但是,上下文这个概念在不同的场景下有着不同的含义,例如,在进程切换,异常处理等时候,我们会用“保存上下文”这样的表述来指当前的寄存器值的集合。我们避免混淆,在本系列中直接新定义一个概念。

CPU本质上是个冯诺依曼机——这是一句废话,但是其实就如前一小节所述的每一个层次,其实也都是一个冯诺依曼机。甚至有些软件还会不依赖于硬件自己构造一些新的计算层次。例如解释执行的语言中,语言的解释器其实也是一个冯诺依曼机,而解释器读入的脚本就是其输入代码。讨论安全,一个重要的前提就是,安全问题是否是跨越这个层次的,这就是我们新定义的计算域

跨计算域安全和计算域内安全

为什么我们要引入这个抽象概念呢?因为CPU相关的安全问题,第一层切分就是一个安全问题是否涉及到不同的计算域。通俗的说,他是一个“提权问题”,还是一个“软件安全问题”。(你看,这种叫法就很模糊)

所谓跨计算域安全就是指攻击者和受害者分别处在不同的计算域中。这个计算域可以是软件上下文不同,例如一个JavaScript的虚拟机中的不同脚本;也可以是硬件上下文中,例如,一个用户态程序攻击内核。因为不同的计算域之间必然有资源隔离手段:可能是CPU权限不同,页表不同,可能是页权限,也可能仅仅是寄存器状态不同。无论是什么手段,跨计算域安全的攻击目的,就是超越当前计算域权限,获得其他计算域的能力,因此经常被称为“提权”。简单来说跨计算域安全的重点在于计算资源的权限管理与隔离技术

那么,假设一个计算域内,只使用了它自己权限内的权限,那还有安全问题么?其实还是有的,因为程序必须按照程序员所期望的方式工作,如果攻击者可以控制程序的执行方式,使其运行方式不同于编写者所预期,那就是计算域内安全问题了(例如,一个简单的计算输入算式结果的程序,可以在特殊的输入下远程下恶意程序并运行。这在安全机制较少的计算机上,稍加学习就可以做到)。为什么会出现这种问题呢?因为软件程序本身的设计不可能遍历所有的输入保证其工作正确,也很难使用形式化证明的方式来确认其安全。许多计算都是靠着精巧但不一定严谨的设计“恰好”运行的,所谓“能跑就行”(其实多数时候也是为了更高的性能,我们会在后文介绍这些权衡 todo: link )。这些不严谨的设计,在攻击者的钻研和利用后,就可以被攻击者控制了。这种安全问题中最常见的就是内存安全,即内存数据的更新和读取没有按照软件开发者本意进行,而可能被攻击者违规读取、写入并加以利用的安全问题

Comment

安全界就是如此,一个“内存安全”的定义甚至在中文互联网上找不到一个明确的定义。例如百度百科这篇博客都语焉不详。我理解编写者甚至“不敢”下一个定义,生怕遗漏什么概念被人喷不懂安全,结果就是罗列一些相关概念并加一个“等”字作为免责声明。这是不利于我们进步的。在本系列中我会非常大胆的开始一系列名词定义,也欢迎讨论。

用前面的比喻来讲,对于厨房的管理员来讲,他管理的计算域就是每一个使用他管理厨房的客户。每个客户只应该使用管理员预期他可以使用的食材和厨具。如果某个客户使用了只有管理员才可以使用的厨具或者仓库,那么他就是一个“提权”,也就是跨计算域攻击。如果一个客户用厨房开了饭馆,迎接的客人点了一些奇奇怪怪的菜品,使得他没法服务其他客人,那么在管理员看来,这是你自己范围内的问题,是一个计算域内攻击。计算域内的问题我更喜欢另一个比喻。我们在那个章节再来展开。

Warning

这里再补充一句,其实这两个概念也并非泾渭分明的。因为某些提权攻击,其实是利用了受害者侧的计算域内的攻击。但是这种分类最大的好处是让读者可以清晰地区分出不同方向安全的逻辑,不至于经常混为一谈。这里先埋下一个伏笔:请读者思考一个问题:什么是代码,什么是数据?在我们介绍完计算域内安全后,我们再来回顾这个问题的答案。

可信执行环境和机密计算

todo:

侧信道和故障注入安全

侧信道安全和故障注入安全的逻辑是独立于前面两者的,前面两者仍然是在架构层定义范围内(这里简单的理解为软件可见的内容即可,在这一部分我们再详细解释)。而侧信道和故障注入安全已经深入到了CPU的微架构设计甚至物理设计,因此他打破了非常多人为设计的安全假设,问题十分棘手。尤其2017年后面出现的Spectre和Meltdown攻击真的是困(zao)扰(fu)了广大的计算系统安全的研究者。因此我们把它单独列为一个部分。

用前面的比喻来讲,侧信道攻击是指一个想窃取某个饭馆秘密配方的攻击者,没有偷偷潜入后厨去查看制作过程。而是通过一些做饭时产生的外部影响来推测配方,例如蹲在进货口记录食材的购买,查看烟囱来记录炒菜的时间,去下水道和垃圾箱看食材处理的残渣。结合自己对后厨构造的认知,来逆推出秘密配方。如果是故障注入攻击,那么可能他会在进货口偷偷混入一些腐坏的食材,通过品尝那些菜品味道变化来猜测这些食材用到了那些菜品上。

特定领域安全

这一部分其实是免责的“其他”部分:)。因为多数的,有迹可循的安全设计其实都会涵盖在前面三个领域了。但是实际工程中,还有茫茫多的设计并不能直接分类到前面所述的领域。他们一般有以下由来:

  • 为了对抗攻击者常用工具而特化的防御手段
  • 为了特定领域内的安全需求定制
  • 和其他安全设计相互配合使用

本系列结构

因此,本系列也就按照以下几个部分行文:

  • 计算系统安全通用知识
  • 计算域间安全
  • 计算域内安全
  • 侧信道和故障输入安全
  • 特定领域安全