GPU-Fuzz:深度学习框架GPU内存安全检测新突破,发现13个未知漏洞(1/4)
关键词:GPU-Fuzz、深度学习框架、内存错误、模糊测试、约束求解
GPU内存错误是威胁深度学习框架可靠性与安全性的关键隐患。越界访问、静默数据损坏等问题会引发系统崩溃与安全风险。然而,现有深度学习模糊测试工具以网络结构生成为核心,聚焦编译器算术错误检测,未系统性探索算子参数空间,难以挖掘底层CUDA内核的内存漏洞。

针对这一技术盲区,本文提出GPU-Fuzz模糊测试工具。 该方法将深度学习算子的语义规则与内存约束建模为形式化约束公式,依托Z3 SMT求解器生成测试用例,并采用迭代约束引导搜索策略高效探查参数边界条件,通过跨框架执行与NVIDIA Compute Sanitizer工具实现内存错误的精准检测。
实验结果显示:
* GPU-Fuzz在PyTorch、TensorFlow、PaddlePaddle三大主流框架中发现了13个此前未知的漏洞,包含7项内存访问违规、5个静默内存损坏问题。
* 与主流工具NNSmith对比,在4小时的测试中,GPU-Fuzz的测试用例生成量提升近3倍,成功挖掘26±5个高危内存错误,而NNSmith未发现任何内存安全问题。

图注:GPU-Fuzz发现漏洞汇总。该表统计了GPU-Fuzz在三大框架中发现的13个未知漏洞,包含7个内存访问违规、5个静默内存损坏漏洞。转置卷积算子漏洞高发,根因多为网格维度计算错误与边界检查缺陷。漏洞覆盖静默损坏、GPU异常、CPU断言三类模式。GPU-Fuzz可有效发现主流深度学习框架的底层CUDA内核内存安全漏洞,验证了工具的检测能力。
GPU-Fuzz实现了从网络模型测试到算子参数空间测试的范式转变,填补了深度学习框架GPU内存安全测试的空白,为提升AI系统底层可靠性与安全性提供了全新技术方案。
本文目录
- 一、引言
- 二、背景与动机
- 2.1 GPU架构
- 2.2 深度学习算子
- 2.3 动机
- 三、系统设计
- 3.1 算子建模
- 3.2 基于约束的测试用例生成
- 3.3 跨框架执行
- 四、实现
- 五、评估
- 5.1 实验设置
- 5.2 漏洞发现效果
- 5.3 对比研究
- 5.4 案例研究
- 六、讨论
- 七、相关工作
- 八、负责任的披露
- 九、结论
一、引言
如今,GPU已成为PyTorch、TensorFlow等深度学习框架中不可或缺的组成部分。然而,GPU计算的正确性却常受到内存损坏问题的威胁,这类隐蔽的漏洞源于底层的CUDA内核。越界访问、内存地址未对齐等内存错误,不仅会导致系统崩溃,还会引发静默数据损坏(内存数据被错误修改但无任何崩溃或报错提示,隐蔽性极强),对人工智能应用的可靠性和安全性构成重大威胁。
但定位这类与内存相关的漏洞仍是一项极具挑战性的工作。 现有的深度学习系统模糊测试工具主要通过生成不同结构的多样化神经网络,来检测深度学习编译器中的算术计算错误。这种方法虽对编译器测试有效,却因未对算子参数空间进行系统性探查,无法有效发现内存错误。
本文的核心见解是:要发现GPU内存错误,需将测试重点从网络结构转移到算子参数和内存布局上。 张量形状、数据类型、步长及其他参数的特定组合,决定了CUDA内核中的内存访问模式。因此,一款有效的模糊测试工具必须能对这些复杂的访问模式进行推理,并生成可系统性探查参数空间的输入用例。
为此,我们设计并实现了GPU-Fuzz这一新型模糊测试工具,其专门用于定位这类与内存相关的漏洞。与NNSmith等现有深度学习模糊测试工具不同,GPU-Fuzz聚焦于算子层级的测试。它将深度学习算子复杂的语义规则和内存相关规则转化为形式化约束,再通过求解这些约束生成多样化输入用例,探查与内存相关的边界条件。这种基于约束引导的测试方法,能让GPU-Fuzz对底层CUDA内核进行有效的内存安全性压力测试。
本文的主要贡献如下:
1. 提出一种全新的模糊测试方法,通过系统性探查算子参数空间来针对GPU内存错误开展测试,该研究维度与现有深度学习模糊测试工具形成互补。
2. 设计并实现GPU-Fuzz系统,该系统利用约束求解技术自动生成测试用例,探查底层CUDA内核中与内存相关的边界条件。
3. 在PyTorch、TensorFlow、飞桨等主流深度学习框架中,通过GPU-Fuzz发现了13个此前未被发现的漏洞,验证了该工具的有效性。
二、背景与动机
2.1 GPU架构
现代GPU是基于流多处理器(SMs)构建的大规模并行计算设备,每个流多处理器可同时执行数百个线程。这种并行计算能力由复杂的内存层级结构支撑,但要利用该硬件实现高性能计算,开发人员需手动管理数据的存储位置和传输过程。这一手动操作的复杂性,使得CUDA内核极易出现越界访问、竞态条件等内存错误。

如图1所示,这类内存错误可被利用,从而破坏内核的完整性并篡改程序的控制流。 与这类攻击密切相关的内存空间主要包括:
- 全局内存:供所有线程共享的大容量内存空间,通常用于存储内核的可执行指令和全局变量。已有研究表明,GPU 不支持写执行分离(W⊕X)权限机制[10]。因此,全局内存中的越界写入漏洞可能被攻击者利用来修改存储在该空间中的内核指令,从而从根本上改变程序的预期执行逻辑。
- 本地内存:每个线程独有的私有内存空间,用于存储函数参数、局部变量以及返回地址等控制流数据。栈缓冲区溢出是一种常见的内存错误,会覆盖保存的返回地址。这一漏洞是面向返回的编程(ROP,一种通过拼接程序中现有代码片段来实施攻击的手段)攻击的基础[10],攻击者可借此劫持线程的控制流,将执行逻辑转向恶意代码。
这些漏洞的存在,凸显了建立可靠机制以检测和缓解 CUDA 内核中内存损坏问题的必要性。
2.2 深度学习算子
PyTorch[22]、TensorFlow[1]等深度学习框架,均基于一套丰富的基础计算单元构建,这类计算单元被称为算子。卷积、池化、矩阵乘法、激活函数[3]等算子,是构建神经网络的基本模块。
用户可通过简洁的高层 Python 接口调用这些算子,但其底层实现却极为复杂:每个算子都由一个或多个高度优化的底层程序(即内核[3])支撑,这些内核将在 GPU 上执行。
如图 2 所示,高层的 Python 算子调用会被转化为底层的 CUDA 内核执行,而实现过程中的细微漏洞,都可能引发各类内存错误。

算子的参数空间极为庞大,这是其底层实现复杂的核心原因。以卷积算子[6]为例,除输入张量本身外,该算子还受内核尺寸、步长、填充、膨胀率、通道分组等众多参数约束。这些参数并非相互独立,而是受一套复杂的语义和数学约束规则限制,这些规则决定了参数的有效组合方式,并定义了输出张量的属性。为实现最优性能,框架开发人员会使用 CUDA C++手动实现这些内核,同时采用共享内存分块、复杂的指针运算等高级技术最大化数据吞吐量[9]。这种以性能为导向的手动优化,往往会舍弃更安全的高层抽象方法,使得内核代码成为隐蔽内存错误的高发区——这类错误仅会在特定且通常较为罕见的参数配置下被触发[12]。
2.3 动机
GPU 内存漏洞是人工智能系统可靠性和安全性面临的严重且隐蔽的威胁[20]。在医学影像[24]、自动驾驶[14]等关键任务型应用中,这类漏洞可能引发灾难性故障;同时,它也可能被利用实施安全攻击[21,23]。
当前主流的深度学习模糊测试工具聚焦于编译器栈,通过生成有效的神经网络来发现漏洞[15,16]。但这种方法并不适合检测 GPU 内核中的底层内存错误——这类错误通常并非由网络架构引发,而是由算子参数的特定组合(尤其是边界值组合,如张量形状、步长)触发。这就导致了一个根本性的测试盲区:NNSmith[15]等现有工具并未对单个算子复杂的参数空间进行系统性探查,而这正是 GPU 内存漏洞的隐藏位置。
这一发现表明,深度学习模糊测试需要向算子层级模糊测试转型。为此,我们提出 GPU-Fuzz 系统,该系统通过探查算子参数空间,发现底层 CUDA 内核中的内存漏洞。
三、系统设计
本节详细介绍 GPU-Fuzz 的架构。如图 3 所示,该系统包含三个核心阶段:算子建模、基于约束的测试用例生成、跨框架执行。

3.1 算子建模
GPU-Fuzz 通过一个抽象层对 GPU 算子进行建模,捕获算子的参数空间和形状关联关系。每个算子类别(如卷积、池化)都由一个统一模型表示,该模型定义了输入/输出形状的接口以及参数约束规则。
如图 4 所示,GPU-Fuzz 将算子语义编码为一组含符号变量的约束公式。

以图中的卷积算子为例,其核心约束公式[6]为:
$$
O = frac{I + 2P – D(K-1) -1}{S} + 1
$$
其中,$I$ 和 $O$ 分别表示输入和输出尺寸,$P$ 为填充值,$D$ 为膨胀率,$K$ 为内核尺寸,$S$ 为步长。只有当输入满足该约束公式时,算子才能被正确实例化并执行。除该核心约束外,还存在各类附加约束(如 $K > 0$)以保证算子的语义正确性。这种约束建模方法,能让我们为深度学习算子有效生成合法的测试用例。
为保证建模的正确性,我们从每个算子的官方文档中手动提取约束公式。两位作者独立完成各算子约束公式的提取工作,再交叉验证结果,整个过程耗时约一个月。这两位作者均为深度学习领域的专家,对各算子的语义有深入理解,这在很大程度上保证了 GPU-Fuzz 的正确性。本研究共为 13 类算子提取了 45 条约束规则。
3.2 基于约束的测试用例生成
约束求解
当算子完成约束建模后,GPU-Fuzz 会利用 Z3 的 SMT 求解器[5]为所有符号变量寻找满足约束的赋值。

如图 5 所示,要为卷积算子生成测试用例,求解器需为 $I$、$O$、$P$、$D$、$K$ 和 $S$ 找到满足图中约束集的具体数值。以图 5 为例,一组可行的解为 $I=224$、$O=112$、$P=1$、$D=1$、$K=3$、$S=2$。
尽管 Z3[5]等 SMT 求解器能有效为给定约束找到一组解,但其设计初衷并非系统性探查整个参数空间。具体而言,Z3[5]这类求解器往往会为符号变量返回单一的边界解(如对于约束 $K > 0$,返回 $K=1$),这对于全面的模糊测试而言是远远不够的。为解决这一问题,NNSmith[15]等现有研究通过为原始约束添加周期性扰动(如 $K neq 1$),迫使 Z3[5]返回多组解。而 GPU-Fuzz 则采用一种全新的约束引导搜索策略,实现对参数空间的系统性探查。
参数空间探查
为实现对参数空间的系统性探查,GPU-Fuzz 采用迭代式的约束引导搜索策略,如图 6 所示。

该过程从求解器找到的初始解 $S_0$(如 $S=2, K=3$)开始,在每次迭代中,系统随机选择一个参数维度添加约束。
例如,系统可能先选择步长($S$),添加排除其当前值的约束,引导求解器找到新解 $S_1$;在下一步中,系统可随机选择内核尺寸($K$),在现有约束基础上累加新约束(如 $S neq 2$ 且 $K neq 3$),迫使求解器向未探查的区域搜索,进而得到另一组解 $S_2$。
值得注意的是,为同时提升求解器的效率和解的多样性,我们提出在约束中不仅加入直接值排除(如 $K neq 3$),还融入基于哈希的约束(如 $hash(K) mod N neq m$)。该哈希函数通过一系列位混合操作对输入值进行转换,使其具备离散性;具体而言,该函数通过交替执行右移、异或和乘法操作,确保输入值的微小变化都会产生不同的哈希值,有效避免恒等映射和分布不均的问题。基于哈希的约束与直接值排除形成互补,能防止求解器探查相似的参数区域,大幅提升解的多样性。
这种增量式搜索策略,确保 GPU-Fuzz 能持续、高效地生成多样化的测试用例。
3.3 跨框架执行
当生成一组有效的算子参数后,GPU-Fuzz 会将其作为测试用例,在 PyTorch[22]、飞桨[17]、TensorFlow[1]等多个深度学习框架中执行,以检测 GPU 内存错误。
如图 7 所示,该过程会将求解器生成的、与框架无关的抽象参数,转化为带特定 API 调用的具体参数。

例如,通用参数outch会在 PyTorch 中映射为out_channels,在 TensorFlow 中映射为filters。为检测内存错误和内核执行故障,每次执行都会由 NVIDIA 的 compute-sanitizer 工具[19]封装监控,这一方法能大幅提升内存错误的检测效率。
四、实现
本节详细介绍第 3 节所述系统设计的具体实现。GPU-Fuzz 基于 Python 开发,代码总量为 2628 行。
为实现第 3 节提出的算子建模和基于约束的测试用例生成功能,我们开发了一个专用库,该库中将每个算子表示为独立的类。本研究为 13 类算子应用了该建模方法(如表 1 所示),这些算子均为深度学习模型中的常用算子,且其内存访问模式复杂、易出现错误。

我们实现了第 3.3 节所述的参数转换过程,将生成的参数值转化为各框架专属的 API 调用。当 compute-sanitizer 在执行过程中检测到错误时,系统会自动归档执行日志,确保错误可复现。
五、评估
本节对 GPU-Fuzz 的有效性和效率进行评估,旨在解答以下研究问题:
- RQ1:GPU-Fuzz 在发现主流深度学习框架中的实际漏洞方面效果如何?
- RQ2:在测试用例生成和漏洞发现方面,尤其是针对 GPU 内存错误的检测,GPU-Fuzz 与当前主流的深度学习模糊测试工具相比表现如何?
5.1 实验设置
所有实验均在一台配置如表 2 所示的服务器上完成。

- 我们为 PyTorch、TensorFlow、飞桨三个目标框架分别搭建了独立的 Conda 环境,以管理各自的专属依赖;
- 所有测试均使用相同的核心硬件、操作系统和 NVIDIA 驱动。
5.2 漏洞发现效果
在评估过程中,GPU-Fuzz 在三个深度学习框架中共发现 13 个此前未被发现的漏洞,表 3 对这些发现进行了汇总。

这些漏洞涵盖多种故障模式,从底层内存损坏到 API 层级的异常均有涉及;其中我们识别出 7 类不同的内存访问违规问题(如越界访问、未对齐写入),且有 5 类为静默内存损坏——这类错误不会触发任何 API 层级的崩溃,仅能通过 compute-sanitizer 等专用工具检测。
漏洞模式
我们的研究发现,所有漏洞可归为三类不同的故障模式,且各模式呈现出明显的规律:
- 静默内存损坏:最关键的漏洞类别,该类错误会引发越界或未对齐的内存访问,但不会触发任何 API 层级的错误提示。这类漏洞的隐蔽性极强,是最危险的内存错误,仅能通过底层内存调试工具检测。
- GPU 层级异常:第二类漏洞,无效的参数或配置会导致 CUDA、cuDNN 或 CUBLAS 库返回错误,该错误通常会被框架捕获并上报。
- CPU 端断言失败:最后一类漏洞,在 CPU 端计算内核参数时会出现整数溢出等问题,直接阻止 GPU 内核的启动。
所有框架中漏洞的一个常见根本原因是网格维度计算错误或边界检查逻辑缺陷,其中转置卷积算子是漏洞的高发区。
5.3 对比研究
为从数量上验证 GPU-Fuzz 的有效性,我们将其与当前主流的深度学习模糊测试工具 NNSmith 进行对比实验。在同一硬件上,我们针对 PyTorch 框架分别对两款工具进行 5 次独立的 4 小时模糊测试,且两款工具均运行在相同的 Conda 环境中。

表 4 汇总了对比实验结果:
- NNSmith 平均生成 个测试用例,发现 个漏洞,且其发现的漏洞大多为数值不匹配问题,并非内存安全问题;
- 而 GPU-Fuzz 平均生成 个测试用例,排除内存不足错误后共发现 个实际漏洞,其中包含 个严重的内存错误和 个配置错误。这些内存错误属于严重的安全漏洞,可能导致数据损坏、信息泄露或系统崩溃。
核心发现
我们的分析得出两个关键结论:
- 第一,GPU-Fuzz 生成的测试用例数量约为 NNSmith 的 3 倍,证明了基于约束引导的参数模糊测试在系统性探查算子参数空间方面的高效性;
- 第二,GPU-Fuzz 发现了 个具有安全风险的内存错误,而 NNSmith 发现的漏洞主要为数值精度问题,通常不会威胁内存安全。
这一结果表明,GPU-Fuzz 填补了现有深度学习模糊测试工具在 GPU 内存安全测试方面的盲区。两款工具的测试方法形成互补:NNSmith 擅长发现编译器相关漏洞和数值不一致问题,而 GPU-Fuzz 则填补了算子参数层级 GPU 内存安全测试的空白。
5.4 案例研究
为验证 GPU-Fuzz 的实际实用性,我们以 PyTorch 的二维转置卷积(ConvTranspose2d)算子中发现的一个内存损坏漏洞为例,给出最简可验证性证明(PoC),如图 8 所示。

触发该漏洞的关键在于 GPU-Fuzz 自动生成的参数组合,尤其是超大的步长值与输入维度的组合。尽管这些参数值符合 PyTorch API 的语义规则,但属于手动测试中极难覆盖的边缘场景。
如图 8 所示,该漏洞的根本原因是 C++主机端代码中的整数溢出:
- 在计算 CUDA 内核的总元素数时,64 位整数值被强制转换为 32 位整数,导致数值被截断;
- 该溢出后的数值随后被用于计算 CUDA 网格维度,生成的网格尺寸过小,无法覆盖所有必要的内存操作。
当 col2im_kernel 内核执行时,线程计算出的 64 位索引会超出实际分配的缓冲区大小,最终引发内存越界写入。

如图 9 所示,compute-sanitizer 检测到有 CUDA 线程试图向越界地址写入数据,且该地址位于最近的有效内存分配区域之前。这类静默内存损坏是严重的漏洞,它不会引发显式的 Python 程序崩溃,却可能导致计算结果错误或程序行为不可预测。
这一案例证明,GPU-Fuzz 能够通过探查非平凡的参数空间,系统性地发现成熟深度学习框架中隐藏的严重漏洞。
六、讨论
尽管实验结果验证了 GPU-Fuzz 的有效性,但我们也认识到该工具存在一些局限性,同时也明确了未来的研究方向:
- 手动建模的工作量:GPU-Fuzz 的性能依赖于其约束库的完整性。当前我们的约束库仅支持 13 类算子,而深度学习框架中存在数百类算子,扩展算子覆盖范围需要手动进行约束建模(每类算子约需 100-150 行代码)。未来的研究可探索从框架文档中半自动提取约束规则的方法,以提升工具的可扩展性。
- 测试判定器的局限性:我们主要使用的测试判定器 compute-sanitizer 擅长发现内存错误,但无法检测静默的数值正确性问题或性能退化问题。将模糊测试与可信的 CPU 实现进行差分测试,是实现更全面测试判定器的可行方向。
七、相关工作
近年来,深度学习系统的模糊测试研究受到持续关注。为检测复杂的现代深度学习编译器栈中的漏洞,一种有效的方法是生成合法的神经网络模型。
NNSmith、TVMFuzz、HirGen 等研究开创了这一方向,证明了该方法在发现编译器相关漏洞(如图层优化问题、中间表示转换错误)方面的有效性。在此基础上,其他研究开始针对深度学习栈的不同组件开展测试:
- 例如 LEMON 通过生成模型变体检测不同库实现之间的不一致性,从而对深度学习库进行测试;
- Orion 等近期研究则基于历史漏洞模式生成测试输入,专门针对 API 层级开展测试。
尽管这些方法均有成效,但它们主要在较高的抽象层级执行测试,并未被设计用于系统性探查执行算子的 GPU 内核中的底层内存访问模式。
而针对 GPU 内核的测试本身也形成了独立的研究方向:
- GPUVerify 采用形式化方法,通过检测数据竞争和屏障分歧验证内核的正确性;
- DeepSmith 通过从头生成随机的 CUDA 程序,对 CUDA 编译器本身进行压力测试。
相比之下,GPU-Fuzz 与上述研究均存在差异:它既不像 NNSmith 那样生成完整的神经网络模型,也不像 DeepSmith 那样生成完整的 CUDA 程序,而是聚焦于现有深度学习算子的参数空间模糊测试,以发现内核层级的漏洞。
八、负责任的披露
我们已通过向 PyTorch、TensorFlow 和飞桨的官方代码仓库提交详细的漏洞报告,负责任地披露了所发现的全部 13 个漏洞。截至本文撰写时,多个漏洞已获得开发团队的确认。我们将继续与各框架的维护者密切合作,共同致力于提升深度学习生态系统的安全性与鲁棒性。
九、结论
本文提出了 GPU-Fuzz,一种基于约束引导的模糊测试工具,专门用于检测深度学习算子中的 GPU 内存安全错误。通过将测试焦点从网络模型转移到算子参数空间,GPU-Fuzz 能够有效探查可能触发底层内存错误的边界条件。在 PyTorch、TensorFlow 和飞桨等主流深度学习框架上的实验表明,该工具成功发现了 13 个此前未知的漏洞,其中大部分为静默内存错误。
本研究证明,保障现代人工智能系统的安全可采用模型层级模糊测试与算子参数空间模糊测试相结合的互补策略。我们希望通过开源 GPU-Fuzz 工具并分享相关研究发现,为提升这些基础技术的可靠性与安全性做出贡献。
参考文献

关注“鲸栖”小程序,掌握最新AI资讯
本文来自网络搜集,不代表鲸林向海立场,如有侵权,联系删除。转载请注明出处:http://www.itsolotime.com/archives/29336

