← 文章 / 科技资讯
Hacker News 5小时前 · 2026-09-11 12:11:18 · 4 阅读

Deathray:不可信网站让 Mac 死机的简单方法

一个不可信网站让 Mac 死机的简单方法

不可信网站上的一个 WebGPU shader 就能让 Mac 的图形系统卡死,桌面界面无法使用,直到强制重启为止。受害者只需要点击一个链接。这个问题在 MacOS 上跨浏览器可复现,但在其他操作系统上不行。

试试 Deathray!

下面的按钮会让你的 Mac 死机,也可能会拖慢其他操作系统

在我测试过的其他操作系统上,它只会导致标签页卡死、系统变卡,关掉标签页就恢复正常了。但你的情况可能不同!只有愿意接受电脑死机风险时才点击上面的按钮。

影响范围

我在 MacOS 的 Chrome、Firefox 和 Safari 上都复现了 deathray,但在其他操作系统上无法复现。我只在运行 Tahoe 的 M 系列 MacBook 上测试过;如果你发现其他 Mac 也受影响,欢迎告诉我!

工作原理

deathray 用到了一项相对较新的 Web 技术:WebGPU。WebGPU 提供内置的浏览器 API,网站可以通过它向设备 GPU 提交 shader 运行。它旨在取代 WebGL,已在大多数操作系统的所有主流浏览器中得到支持。

整个 deathray 只需一个小文件就能实现。你可以在这里查看源代码。文件的大部分是脚手架代码,关键部分是 WebGPU shader。

Compute Shader

      
@group(0) @binding(0) var<storage, read_write> data : array<vec4f>;

@compute @workgroup_size(1) fn compute() {
  // no i++, loop spins endlessly
  for(var i = 0u; i < 1;) {
    data[i+1] = data[i];
  }
}
      
    

Render Shaders

      
@group(0) @binding(0) var<storage, read> data : array<vec4f>;

@vertex fn vert(@builtin(vertex_index) vertexIdx : u32)
              -> @builtin(position) vec4f {
  // attempts to read from same buffer the compute shader writes to
  let datum = data[vertexIdx];
  return datum;
}

@fragment fn frag(@builtin(position) pos : vec4f)
               -> @location(0) vec4f {
  return pos;
}
      
    

compute shader 中有一个无限忙循环,不断把同一个向量反复复制到缓冲区里。而 vertex shader 依赖的正是 compute shader 正在操作的同一块数据缓冲区。由于 compute shader 一直在忙于循环,vertex shader 就无法继续执行。

这个问题会波及到其他需要 GPU 的进程,尤其是 WindowServer。由于 WebGPU 任务堆积,WindowServer 也随之无响应。具体表现不一定相同:有时还能动鼠标,有时完全卡死;有时出现彩色转圈等待图标,有时屏幕局部会刷出粉红色的花屏。我不太确定是什么导致了这些不同的表现。

有意思的是,此时电脑其他部分完全正常,你甚至能正常 SSH 连进去。但系统里有个 Watchdog 在监控 WindowServer,一旦它长时间无响应,就会触发 kernel panic,电脑自动重启。如果你已经被 deathray 命中且等不及,可以长按电源键强制关机重启,不必等 Watchdog 动手。只希望你的浏览器重启后不会自动恢复那个该死的标签页 :)

先例

苹果其实不是第一次遇到这类问题。2023 年,Imperva 的 Ron Masas 制作了一个类似的恶意 shader,名为 ShadyShader,利用的是 WebGL。ShadyShader 同样用失控的循环来霸占 GPU——构造了巨大的嵌套循环,但严格来说并不是无限循环。

苹果随后发布了 CVE-2023-40441,CVSS 评分为 6.5(中危)。作为缓解措施,苹果增强了输入校验,以便更好地检测失控循环。

不过在 WebGPU 中,这套输入校验似乎没那么严格——deathray 里的无限循环几乎一眼就能看出来。但归根结底,检测无限循环是一场必输的博弈,halting problem 绕不过去。需要更完善的机制来抢占无响应的 shader,尤其是当这些 shader 在运行不可信代码时。我测试过 deathray 的其他操作系统,都能正确处理这一点。

我猜苹果在修复这类问题时所面临的困难,部分原因在于 M 系列芯片的架构。操作系统内核无法直接抢占 GPU,实际由一个名为 ASC 的协处理器来完成 GPU 处理,内核通过它与之通信。所有 GPU 抢占逻辑都写在 ASC 的固件里。Asahi Lina 有一篇关于 M 系列 GPU 的精彩文章,更详细地剖析了这一架构。

deathray 是怎么被发现的?

我以最老派的方式发现了这个问题:纯属意外!当时我在 Recurse Center 学习 WebGPU,不小心写了个死循环。电脑直接卡死让我吃了一惊,我本能地试了试"是不是每次都会这样"——果然。我不可能是第一个撞上这个坑的人。

漏洞披露

我在 2026 年 7 月 27 日将问题报告给了 Apple Security。Apple 很快复现了问题并表示会修复,还给出了修复时间表,但标注为机密,所以我这里就不写了。

然而 2026 年 8 月 26 日,Apple 突然改口,称"未发现该报告存在任何安全影响",也未"导致产品发生任何变更"。他们说该报告将转交另一个团队进行"潜在增强评估"。在我看来,这意味着修复优先级会非常低,甚至可能根本不会被处理。考虑到 ShadyShader 被标记为 6.5 分的中危问题,这个态度确实让人困惑。

话虽如此,"什么才算安全问题"确实值得讨论。我聊过的安全研究员大多认同 Apple 的立场。用 Apple 的话说,"结果是崩溃、卡死或可恢复的数据丢失,我们不认为这属于安全问题。"从技术层面讲,我觉得他们说的也没错。

但我聊过的非安全领域的人,大多对这种定性和 Apple 不优先修复的态度感到意外。我觉得普通用户对浏览器有相当强的信任感——也许是过于天真的信念:点一个链接最多只是让电脑慢一点,关掉标签页就恢复了。deathray 这种东西以非常直观的方式打破了这种信任,我认为大多数用户会把它视为安全问题。

我期望看到的

deathray 的严重程度当然远不及沙箱逃逸、RCE 或数据泄露。但它上手门槛极低(只需要让人点一个链接),所以搞起事来会相当烦人。如果被恶意使用,我觉得它就像一个更恶毒的 Rickroll,希望 Apple 能尽快修复。(Apple 拜托,修复方案别是默认禁用 WebGPU 啊!我已经爱上 WebGPU 了 💚)

不过在 Apple 修复之前,希望大家能拿它玩点无害的花样。我很想看到这样的 deathray 游戏礼物:游戏输了,你的 Mac 就会死机(前提是用户提前自愿开启)。这算是「游戏中死亡,现实中也会死」的温和版本。

玩得开心,但也请手下留情!

此致,

Auberon López(they/them)

原始来源: Hacker News

评论 (0)