IvySyn

IvySyn: Automated Vulnerability Discovery in Deep Learning Frameworks 论文分享

Neophytos Christou, undefined., et al, “IvySyn: Automated Vulnerability Discovery in Deep Learning Frameworks,” in 32nd USENIX Security Symposium (USENIX Security 23), 2023, pp. 2383–2400.

pdf链接:usenix.org/system/files/usenixsecurity23-christou.pdf

IvySyn:自动发现深度学习框架中的漏洞

IvySyn是第一个用于发现深度学习框架中的内存错误漏洞的全自动框架,它会自动合成高级语言(如Python)中的代码片段

背景

人工智能应用越来越广泛,深度学习(DL)一直走在人工智能技术的前沿。深度学习框架通常为模型开发人员提供一套丰富的高级应用程序接口,开发者可以通过这些接口执行特定的DL操作,但是这些操作的重要部分(内核)是用C/C++等内存不安全语言实现的。因此DL框架底层实现存在漏洞,这些漏洞可能导致功能不正确、数值错误、性能下降、内存耗尽和CPU/GPU/TPU锁定,以及致命的的运行时和内存安全错误。

现存的深度学习框架漏洞发现方法局限

过去了方法试图通过直接在高级应用程序接口上使用模糊处理来回答类似问题,但是是半自动或非自动的,需要领域专家注释来指定有效的参数-值组合,或者需要开发人员手动编写辅助代码。

提出问题
  1. 在本地DL内核中,是否有低级应用程序接口的违规输入会引发内存错误?
  2. 是否有任何高级应用程序接口可以将上述违规输入传播到低级内核代码中?

贡献

  1. 利用原生API的静态类型性质,这使本文能够在低级内核代码上执行基于类型感知突变的模糊
  2. 给定低级API的一组违规输入,本文利用从低级到高级API的固有DL框架映射,并合成代码片段,在低级、原生代码上触发内存错误,并将输入传递给高级API
  3. 设计并实现IvySyn,IvySyn框架中实现了本文自下而上的方法,它不需要域专家注释或手动编写的驱动程序代码

相关知识

内核:DL框架的核心功能由原生C/C++代码提供,实现标准操作,如张量操作、数学、讨论和梯度计算、池化和其他DL特定操作。此类操作的实际本机实现称为内核。在C/C++等语言中实现核心操作不仅提供了更好的性能,还允许框架开发人员为不同的硬件设备(例如CPU、GPU和TPU)提供多个优 化版本。内核被建议避免使用(或取决于)共享状态,每个调用都是自包含的,以便易于并行。这是IvySyn构建的一个重要属性,可以无缝添加其内核模糊钩子。

绑定:即使DL框架提供低级内核API,模型开发人员通常通过Python等高级语言执行特定于DL的操作。因此,为了通过开发人员可访问的API公开这些操作的子集,DL框架生成高级绑定。这些绑定将喂给Python API的输入参数转换为相应的C/C++参数,并透明地调用适当的内核,抽象出有关底层外函数接口的实现细节。IvySyn基于DL框架映射(绑定⇄内核)和低级崩溃输入,以无缝合成代码片段,包括各自的高级API。尽管这些绑定不一定打算由de-velopers使用,但它们仍然被公开曝光,并且可以从Python中调用,使攻击者能够直接访问本机内核实现中可利用的漏洞。

高级API和DL模型:高级语言绑定(如上述)由其他特定于语言的高级API(例如,在Python中实现)进一步包装。在调用相应操作之前,后者可能会在原始绑定上添加一些抽象,例如参数的预处理或额外的健全性检查;或者可能只是包装器,向框架模块添加文档和统一导出操作。最终,围绕内核操作绑定的高级API是模型开发人员打算使用的API。我们称这些开发人员可访问和记录的API为高级API。通常,在为各种任务构建DL模型时,会使用多个此类高级API,例如自动驾驶汽车的图像分类[36],恶意软件检测和人脸识别。测试深度学习框架。DL框架在其底层实现中存在错误,经验表明,此类错误可能会导致内存安全错误、致命的运行时错误、不正确或不一致的功能性、数值错误、性能下降、内存消耗和CPU/GPU/TPU锁定。原生、C/C++、DL框架部分(例如内核)中的错误特别令人感兴趣,因为它们可能会导致致命的运行时错误和内存错误,并可能被攻击者滥用。

内存错误

IvySyn旨在发现触发以下内容的崩溃输入:

(a)内存安全错误,如(任意)内存损坏和内存泄露漏洞

(b)致命的运行时错误——(a)和(b)在模糊/运行时期间表现为崩溃(即带有SIGABRT、SIGFPE和SIGSEGV异常的异常进程终止)。

方法概述

目标:发现安全漏洞

IvySyn利用基于突变的模糊测试和类型感知测试,实现发现本地DL内核中可能引发内存错误的违规输入。IvySyn会自动合成适当的代码片段,从高级应用程序接口触发相应的错误。

每一个可以触发内存错误的输入(代码片段)被称为“漏洞证明”(PoV),因为它正面内核代码中存在漏洞,可能导致内存损坏或泄露(违反完整性/保密性),甚至停止整个DL框架的运行(违反可用性)。攻击者可以通过API触发漏洞。

IvySyn框架

框架的设计遵循三个设计原则

  1. 开发人员关于拓展DL框架的指令:便于识别本机API并为其添加适当的模糊钩子
  2. 挂钩没有共享状态的内核,使用开发人员测试来强制执行和模糊它们
  3. 利用高层和底层API之间固有的DL框架来合成PoV

下图是IvySyn的整体架构

image

IvySyn的仪器从各自的DL代码库中提取本机内核实现,以构建和注入模糊包装器。IvySyn的Watchdog调用开发人员测试套件的切入点;一旦ex-ecution的流到达目标内核,IvySyn的仪器将使用类型感知突变引导强制执行的基于突变的模糊会话。IvySyn的合成器使用模糊过程中发现的低级崩溃输入来生成PoV,这反过来又会触发来自公开可用API的低级内存错误。

要测试本机代码,IvySyn首先需要提取与DL框架内核对应的函数,然后在它们周围创建并注入适当的模糊包装器。

Creating and Injecting Wrappers: 给定一组目标ker- nels,IvySyn创建并注入模糊包装器如下:首先,它将原始内核函数重命名,例如func(),改为do_func();然后,它用包装代码替换原始函数的主体,初始化IvySyn模糊会话。

DL框架通常由多层结构组成,不会公开低级API(即内核)供直接使用。 图1的左侧,内核旨在被高级API暗示使用,高级API⇝绑定⇝内核。 因此,在没有适当的调用上下文(即在调用堆栈上活跃的特定功能链和一组正确初始化的全局变量)的情况下,直接模糊内核API将导致不正确的功能。

为了引导强制执行的模糊会话,IvySyn创建了一个看门狗进程,该进程运行开发人员提供的单元测试的入口点(例如,在TensorFlow的情况下,tf-tests/*.py)。 在仪器期间,原始内核函数定义与IvySyn包装代码插入。 因此,一旦开发人员测试的执行到达仪器内核,它将启动一个“强制执行”的模糊会话。 这种方法可以无缝工作,因为强制执行的内核以适当的调用上下文调用,内核通常通过设计避免共享状态。 (与共享状态交互的内核目前被IvySyn忽略) 崩溃报告生成。 每个突变的投入组合都会被分配一个唯一的索引号(UIN)。 IvySyn将与当前突变输入组合对应的UIN记录到日志文件中,该日志文件以模糊的函数命名。 一旦发生崩溃,此日志文件将包含上次尝试输入组合的UIN,这是导致内存错误的UIN。 IvySyn利用这种形成来重新初始化模糊器,获取违规输入,并将崩溃报告拼接在一起,如Listing1所示。

image

总结

本位设计并实现了IvySyn,IvySyn首先识别DL内核代码实现,并添加模糊钩子,以便对类型感知突变执行基于突变的模糊。 接下来,给定一组崩溃的内核,它合成了传播违规输入的高级代码片段,这些代码片段会使本机内核崩溃,认为是高级API。此类代码片段可以作为漏洞的证明,并可以帮助开发人员复制、分析并最终修复各自的错误。