2005年5月,Intel 找上 Yahoo,要求对方下令撤回一篇即将发表的安全论文。让大厂公关扑空的是,论文作者 Colin Percival 当时只是个刚从牛津毕业、住在加拿大父母地下室的无业青年,并非如许多 FreeBSD 开发者那样受雇于 Yahoo。正是这份无业游民的自由,保住了现代 CPU 侧信道攻击的开山之作,也逼着整个芯片行业第一次正视硬件资源共享的物理代价。

Percival 最近撰文回顾了这段往事,把研究者的这种坚持称为学者的职责。剥开道德叙事的外衣,这件事真正耐人寻味的,是一场持续了二十年的架构博弈。当芯片厂商为了纸面跑分把多个线程塞进同一个物理核心时,安全与性能的死结就已经系上了。

父母地下室里的半年拉锯战

故事的起点在 2004年11月16日。Percival 向牛津大学提交博士论文时,满脑子想的却是 Intel 在 2002年引入的超线程(Hyper-Threading,即同步多线程 SMT)技术。当时安全圈有个心照不宣的段子,美国国家安全局(NSA)虽然开始公开谈论加密防守,但唯独对侧信道攻击讳莫如深,这种沉默本身就构成了泄露 NSA 重视程度的侧信道。

不到一个月,Percival 在 2004年12月中旬写出了概念验证代码(PoC)。他在一台搭载 2.8 GHz Pentium 4 处理器、运行 FreeBSD 5.2.1 和 OpenSSL 0.9.7c 的机器上,通过观测同一物理核心上相邻线程的缓存失效时间,成功窃取并还原了 RSA 1024-bit 私钥。这个漏洞后来被编号为 CVE-2005-0109。

拿到实锤后,他没有直接把代码扔到网上博取名声,而是按下了人生暂停键。在 2005年2月至3月间,他私下联系了包括 Intel 在内的各大厂商,给足时间准备补丁,直到 2005年5月13日才在 BSDCan 大会上公开发表那篇著名的《Cache Missing for Fun and Profit》,FreeBSD、NetBSD、Red Hat、SCO 和 Ubuntu 也在同一时间发布了安全公告。

CVE-2005-0109 协同披露与微架构侧信道演进时间线 2002 Intel 引入 超线程 HT 2004.12 完成 PoC 还原 1024位密钥 2005.05.13 顶住施压公开 BSDCan 发论文 2016 CacheBleed L1 缓存分行竞争 2018 PortSmash 执行端口竞争

这种先私下通知、等补丁就绪再公开的做法,就是今天开源界熟知的协同披露。但 Percival 的经历揭开了温情面纱下的残酷真相。这套机制之所以能走通,是因为他单身、没孩子、住父母家免房租,且身处拥有公共医保的加拿大,不用为了买胰岛素去给美国雇主打工看脸色。如果他的饭碗捏在大厂手里,这篇论文大概率会在法务和公关的联手施压下胎死腹中。

堵不住的微架构物理漏斗

为什么 Intel 当年那么紧张一篇学术论文?因为 Percival 捅破的不是某个软件版本的低级 Bug,而是现代 CPU 性能神话的底层逻辑。

超线程技术的核心算盘,是让两个逻辑线程共享同一个物理核心的缓存和执行单元,以此填补指令流水线的空隙。逻辑上看,操作系统把两个线程隔离开了;物理上看,它们同处一室,谁先用洗手间、谁占了走廊,另一方只要掐表算时间就能猜个八九不离十。

这种物理状态共享带来的隐患,在此后十几年里顺着硬件结构一路向下蔓延:

  • 2005年的最初攻击利用的是 CPU 缓存状态,逼得密码学界推广常量时间编程(Constant-time programming),确保内存访问模式不随密钥数值变化。
  • 到了 2016年,研究人员发现 CacheBleed 攻击,把目标瞄准了更底层的 L1 缓存分行(Bank)竞争,即便代码做好了缓存行对齐也难以幸免。
  • 2018年出现的 PortSmash 更进一步,直接绕过缓存,利用超线程架构下的执行端口(Execution Port)竞争来窃取信息。

只要两个线程还在争夺同一块硅片上的物理通道,修补就永远是打地鼠。面对 PortSmash 这类新型攻击,厂商和学界形成了鲜明的立场分裂。Intel 依然倾向于推荐软件层面的修补,要求开发者写出极其严苛的常量时间代码,以此保住超线程带来的性能卖点;而学术界和极端重视安全的操作系统维护者则认为,唯有通过内核核心调度(Core Scheduling)强制隔离不可信线程,甚至直接关闭 SMT,才能从根源上斩断侧信道。

  • 提醒.对于运行多租户高保障工作负载(High-assurance workloads)的云团队而言,单纯依赖软件补丁无法根除微架构侧信道,必须在内核级启用 Core Scheduling 或在 BIOS 层关闭超线程。

商业算盘与被高估的道德底线

既然关掉超线程就能一劳永逸,为什么二十年过去了,绝大多数云厂商和企业依然默认开着它?答案藏在商业计算的成本账本里。

行业里流传着一种夸张的恐吓,说关掉超线程等于砍掉一半算力。但实际上,根据 Red Hat 的性能测试,关闭超线程带来的性能损耗在 0-30% 之间,具体取决于工作负载类型。对于计算密集且流水线本就饱满的任务,关掉它几乎不掉速;但在高并发、频繁等待内存的云端场景里,这最高三成的性能折损,直接对应着真金白银的服务器采购成本和利润率。

微架构侧信道防御策略的工程代价对比 软件修补与核心调度(厂商偏好) 核心手段:常量时间编程 / Core Scheduling 性能保留:维持 SMT 吞吐优势 现实局限:难防新型端口竞争,极其考验代码 适用场景:通用商业负载、成本敏感型云主机 彻底关闭超线程 SMT(学界底线) 核心手段:物理核心独占,切断微架构共享 性能代价:Red Hat 实测损耗 0-30%(非 50%) 安全收益:从物理根源免疫同核跨线程窃密 适用场景:高保障密钥管理、跨租户强隔离环境

这就是我不太买账单纯歌颂学者个人道德的原因。司马迁在《史记》里写过一句大实话,天下熙熙,皆为利来。科技产业同样如此。当架构师的绩效绑定在跑分提升上,当云厂商的毛利建立在超卖物理核心上,整个商业机器的激励方向都是把硬件榨干,而不是留出安全冗余。

协同披露若无免于报复的制度兜底,不过是要求学者用饭碗替大厂的架构债买单。

Percival 在文章后半段引用德国哲学家费希特《论学者的使命》,区分了创造新知识的研究者(Researcher)与把知识传递给需要之人的学者(Scholar)。他还举了另一个例子,2009年他发现 Amazon EC2 防火墙默认破坏了路径 MTU 发现机制,私下报告三年无果后,他在 2012年11月直接发博客教用户自己动手修,结果 Amazon 转头就把 Bug 改了。

你看,哪怕是温和的工程问题,大厂的本能反应也是拖延,直到公开曝光威胁到声誉或客户留存。在安全漏洞上,行业后来把负责任的披露(Responsible disclosure)改名叫协同披露(Coordinated disclosure),恰恰是因为大厂总想把责任两个字变成封口令。如果厂商利用半年的修补期去发律师函、找雇主施压,那么所谓协同,就成了单方面保护厂商股价的缓冲垫。

二十年前,我们靠一个住在父母地下室、不惧解雇的年轻人,才看清了 Pentium 4 缓存里的暗门。今天,芯片微架构的复杂度早已翻了数倍,AI 与云计算又把算力饥渴推到了极致。如果发现底层缺陷的代价依然是研究者的职业安全,那么下一个潜伏在硅片深处的幽灵,恐怕就没人敢替我们敲响警钟了。