四行着色器代码拖垮窗口渲染核心
2026 年 9 月 10 日,开发者 Auberon López 发表文章,披露了一个名为 Deathray 的设备冻结问题。在 Recurse Center 学习 WebGPU 技术时,他意外写出了一个体积极小的死循环脚本,在浏览器中运行后,直接让他的 M 系列 MacBook 失去响应。这次事故把浏览器沙箱的一句隐含承诺摊到了台面上——用户潜意识里相信,仅仅点击一个链接不该搞坏自己的电脑。
这份被称为 Deathray 的攻击载荷非常简单,核心仅仅是两段几十个字符的 WebGPU 着色器代码。触发条件低到了极点,受害者只需要在浏览器里点开一个含有该脚本的网页链接。在计算着色器里,代码包含一句 for(var i = 0u; i < 1;) { data[i+1] = data[i]; },作者的注释写得非常直白,这里刻意没有推进计数器,循环会在同一块缓冲区上来回复制同一个向量。
紧接着,渲染着色器的顶点阶段被指示去读取这块正在被计算着色器写入的缓冲区。死循环不给资源,顶点阶段就永远等不到。GPU 的处理请求随之堆积。这种阻塞外溢到了其他要用 GPU 的进程,首当其冲的是负责 macOS 图形界面渲染的 WindowServer。系统表现不稳定:有时鼠标还能勉强移动,有时出现彩球,有时屏幕局部冒出紫红色的垃圾数据块。
唯一的确定性是电脑在这个阶段基本无法使用,常规的键盘和鼠标指令全部失效。系统在这个状态下并没有死亡。用户通过 SSH 远程连接,依然能正常登入设备。真正让机器崩掉的,是 macOS 系统内核里死盯着 WindowServer 的看门狗程序,它发现界面进程长时间不响应后,直接触发内核 panic 强制重启。
固件协处理器隔绝了内核抢占
这种单次点击就造成整机强制重启的破坏力,主要局限在苹果的生态内。López 证实该问题在 macOS 上可以稳定复现,Chrome、Firefox 和 Safari 三个主流浏览器全部中招,作者主要在 M 系列 MacBook 上的 Tahoe 环境进行了测试验证。而在其他操作系统上,同样的死循环代码只是让对应的浏览器标签页卡住,或者导致系统整体变慢,用户只要关掉那个标签页,设备就能恢复正常。
其他操作系统在面对失控的渲染指令时,在硬件调用堆栈中守住了隔离边界,而 macOS 将这种应用层面的失控放大成了系统级灾难。López 推测,苹果难以修复这个缺陷,部分原因出在 M 系列芯片底层的特殊架构设计上。他引用了 Asahi Lina 讲解 M 系列 GPU 拆解的文章,指出操作系统的内核其实不能直接干预和抢占 GPU 资源。
在 M 系列芯片的设计里,GPU 的调度处理被移交给了一个叫 ASC 的协处理器。内核只能通过特定接口与 ASC 通信,所有 GPU 抢占逻辑都固化在 ASC 固件里。面对持续涌入的恶意计算流,内核没有底层的强制抢断手段。只要固件层没有识别出这种死锁,内核层只能看着图形资源被抽干,直到看门狗程序把整个系统掀翻。
图:2023 年同类问题 ShadyShader 的官方配图,攻击者用 WebGL 让 M 系列 Mac 单次点击即崩溃。来源:Imperva Threat Research
苹果拒认安全漏洞引发社区争议
苹果对这个问题的处理态度,展现了厂商在漏洞定义权上的绝对控制。时间线显示,López 在 7 月 27 日将该问题报告给了 Apple Security 团队。苹果初期迅速在内部完成了复现,并明确表示打算着手修复,甚至给出了一个带有保密协议的修复时间表。
但到了 8 月 26 日,苹果的态度发生大转弯,明确表示「没有看到任何安全影响」。他们在回复中的判定表述非常直白:「结果是崩溃、挂起或可恢复的数据丢失,我们不认为这是安全问题。」定性一变,这份报告就没有导致苹果产品的任何改动。它被转交给另一个团队,仅作为「潜在的增强考虑」,修复优先级随之跌到最低。
这种判定引发了外界对标准一致性的质疑。2023 年,Imperva 公司的 Ron Masas 报告过一个名为 ShadyShader 的同类漏洞,当时的手法是构造巨大但技术上受限的嵌套循环,利用 WebGL 霸占 GPU,同样能让 M 系列 Mac 崩溃。苹果当时非常严肃地对待了那个问题,分配了 CVE-2023-40441 编号,给出了 CVSS 6.5 的中危评级。同一个厂商,面对相似的攻击手法和相同的系统崩溃结果,仅仅隔了两年,给出的认定结论截然相反。
图:Imperva 对同类 GPU 资源滥用问题的技术分析配图。来源:Imperva Threat Research
静态代码审查绕不过图灵停机问题
面对相似问题的重演,防守策略本身也成了一个争议焦点。在处理此前的 ShadyShader 漏洞时,苹果试图通过在执行前改进输入校验,用代码审查的方式去检测异常的失控循环。López 的判断非常明确,那套输入校验逻辑在功能更强大的 WebGPU 上显得更为脆弱。Deathray 采用的无限循环代码平铺直叙,是一眼就能看出的死胡同,但它依然通过了检验。
依赖代码静态检测去拦截无限循环,本质上面临着图灵停机问题,在计算机科学的理论上这是一场必输的仗。López 认为,面对来自互联网上不特定来源的着色器代码,系统需要的是在执行期间建立强制抢占机制,而不是继续在应用层打补丁加循环检测。作者验证过的其他操作系统,正是因为做对了底层的任务抢占,才避免了整机崩溃的命运。
López 在披露时的自我定位显得相当克制。他明确承认,Deathray 造成的破坏远没有沙箱逃逸、远程代码执行或者数据泄露那么严重,符合安全研究圈子传统的定级直觉。但他同时指出,这个攻击的门槛低到了只需要「骗人点一个链接」的地步,如果被恶意利用,它就像是一个破坏力更恶劣版本的 Rickroll 恶作剧。他也向厂商明确主张,不要为了掩盖架构问题,采用「默认关掉 WebGPU」这种开倒车的修法。
失败循环击碎了用户的心理防线
在 Hacker News 讨论区,这两套评判标准的对立更加明显。一派技术人员倾向于支持苹果的安全判定,认为这是自 2011 年 WebGL 推出以来就存在的老问题。他们认为这种滥用具有自我修正机制,网站如果故意冻结访问者的机器,访客就会再也不去。既然没有真实的数据被窃取,攻击者除了失去受众什么也得不到,这也解释了为什么 15 年来这种攻击手法并没有成气候。
另一派的反驳立足于普通用户的真实体验。恶意广告可以悄悄挂到成千上万个正常网站上,用户死机之后根本无从判断是哪段脚本干的。其次,如果真的要加强管制,该被限制的恰恰是 WebGPU 而不是老旧的 WebGL。
真实的失败循环让这种辩护显得非常苍白。有人在社区描述了实际体验:用户第一次被冻住后,无奈之下长按电源键强制重启;系统重启后,macOS 会自动恢复上一次未正常关闭的全部窗口。机器于是毫无悬念地遭遇第二次冻结,用户只能再次强行切断电源,在开机后努力赶在渲染前关掉恢复的窗口。但只要打开 Safari,历史标签页又会自动加载,再次中招。这个死循环里,普通用户最后只能打电话求助。
Deathray 把浏览器沙箱的一句隐含承诺摊到了台面上。安全圈子和厂商按「能否窃取数据、能否执行任意代码」的框架走,结论是它不算安全问题;而用户的直觉按「我什么都没干,只是点了下鼠标电脑就卡死重启了」走,结论是这毫无疑问算作漏洞。判定的最终解释权死死攥在厂商手里。当整个 web 平台正把越来越多的裸 GPU 控制权交给外部脚本时,操作系统的防线还停留在上个版本。
参考链接:
- The Deathray — A simple way for an untrusted site to freeze a Mac
- Hacker News discussion on Deathray
- Imperva Threat Research on ShadyShader