RPG:一种面向Rust库的模糊测试目标自动生成技术(ICSE‘24)

2023-12-12 09:12

本文主要是介绍RPG:一种面向Rust库的模糊测试目标自动生成技术(ICSE‘24),希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

- 这是我们在ICSE’24的论文RPG: Rust Library Fuzzing with Pool-based Fuzz TargetGeneration and Generic Support [1] 的科普版本。
- 插播一条广告:西安电子科技大学广州研究院 ICTT(GZ) 实验室长期接收硕士、博士、博士后、教师岗位申请,欢迎勤奋、认真,有创新精神的有志青年加入我们研究组!详见:RPG:一种面向Rust库的模糊测试目标自动生成技术(ICSE'24)

一、背景介绍

Rust是一种新兴的系统编程语言,它具有内存安全和高效性的优点。Rust的设计理念是“不信任开发者”,也就是说,它不允许任何可能导致未定义行为的操作。这样,Rust可以避免很多常见的编程错误,比如空指针解引用、缓冲区溢出、内存泄漏等。由于这些优势,Rust不仅受到了很多系统开发者的青睐,也吸引了其他领域的科学家。

Rust库(crate)是Rust语言的基本组成部分,它们是一些可复用的代码模块,可以提供各种功能和特性。Rust库有两种类型:库(library)和二进制(binary)。库可以被其他库或二进制引用,而二进制则是可执行的程序。Rust库可以通过一个叫做Crates.io的在线仓库进行发布和下载,目前已经有超过6万个Rust库可供使用。然而,Rust的库也不是完美的,它们可能存在一些隐藏的错误和漏洞,这些错误和漏洞可能导致程序崩溃或者出现未定义行为。那么,如何有效地检测和发现Rust库中的错误呢?

一种常用的方法是模糊测试(fuzzing),它是一种自动化的软件测试技术,它通过向程序提供随机或者半随机的输入,观察程序的行为是否异常。模糊测试已经被证明是一种非常有效的发现软件错误的方法,它已经在许多领域和项目中得到了广泛的应用。然而,模糊测试也有一些挑战和限制,其中之一就是如何为目标程序编写合适的测试用例(也称为fuzz target)。对于Rust库来说,这个问题尤为突出,因为Rust库通常只提供了一些函数(也称为API),而没有给出具体的使用场景和示例。因此,如果想要对Rust库进行模糊测试,就需要手动编写fuzz target,这是一项非常耗时和繁琐的工作。

为了解决这个问题,一些研究人员提出了一种自动化的模糊测试目标(fuzz target)生成技术,它可以根据Rust库的API信息,自动地生成一些有效和有效的fuzz target,从而实现对Rust库的模糊测试,例如发表在ASE’24的RULF[2]。该文章指出,模糊测试目标是一个可以调用库中的函数(API)的Rust程序,它需要满足以下条件:

  • 语法正确:模糊测试目标必须是一个合法的Rust程序,可以通过编译器的检查。

  • 语义正确:模糊测试目标必须是一个有意义的Rust程序,可以正确地调用库中的函数,不会产生编译时或运行时的错误。

  • 多样性:模糊测试目标应该能够调用库中的不同函数,以及函数之间的不同组合,以触发库中的不同分支和路径。

  • 有效性:模糊测试目标应该能够调用库中的关键函数,特别是那些涉及到不安全(unsafe)代码的函数,以发现库中的潜在错误。

二、本文方法:RPG

RPG是本文提出的一种自动为Rust库生成模糊测试目标的新技术,它的全称是(R)ust (P)ool-based fuzz target (G)eneration。RPG的主要贡献是解决了两个挑战:

  • 如何生成多样性和有效性高的函数序列,以优先考虑不安全代码和函数之间的交互,从而揭示Rust库中的错误。

  • 如何提供对泛型(generic)函数的支持,并验证模糊测试目标的语法和语义正确性,以达到高覆盖率。

Overview

RPG的工作流程如下:

  • Rust库分析:RPG利用静态分析从Rust库中提取函数和数据类型的信息,基于此构建一个API依赖图和一个参数提供器。API依赖图记录了库中可以调用的函数(API)的信息,用于指导函数序列的生成;参数提供器包含了库中定义的数据类型以及一些常用的数据结构类型,用于为泛型函数提供类型候选。

  • 函数序列生成:这一步是RPG的核心,因为一个函数序列直接反映了其对应的模糊测试目标的质量。RPG从一个序列集合开始,该集合考虑了不安全的API,并根据API依赖图和一个API池生成函数序列。API池由当前可用的API组成,其中可能有多个重复。特别地,当处理泛型函数时,RPG从参数提供器中取出数据类型,并保持泛型类型参数的一致性,以确保有效性。

  • 函数序列优化:为了确保模糊测试目标的语法和语义正确性,RPG采用了移动-借用(move-borrow)循环检查和泛型声明检查来移除无效的函数序列。RPG还进行了序列过滤,以获得一个最小的序列集合,覆盖了最多的API及其依赖。最后,剩余的函数序列分别被合成,生成模糊测试目标。

RPG的优势:

  • 优先考虑不安全代码和交互:文章的方案能够有效地检测Rust库中由不安全代码或复杂API序列交互导致的漏洞,而过去的方案主要关注单个API的覆盖,忽略了这些重要的因素。

  • 提供泛型支持和有效性检查:文章的方案能够处理Rust库中广泛使用的泛型函数,通过类型推断和参数提供器为泛型参数提供合适的类型,并保持类型的一致性。文章的方案还能够对API序列进行移动-借用检查和泛型声明检查,以确保API序列的语法和语义有效性,而过去的方案缺乏对泛型的支持或只提供有限的支持,导致生成的目标不完善或无效。

  • 使用基于池的序列生成和过滤:文章的方案能够使用一种基于池的方法,根据API的不安全性和依赖性,生成多样化和深度的API序列,以覆盖更多的API和依赖。文章的方案还能够对API序列进行过滤,以获得一个最小的序列集合,覆盖最多的API和依赖,而过去的方案使用的是基于图的序列生成,不能有效地探索API序列的可能性,也没有对API序列进行过滤,导致生成的目标冗余或低效。

三、技术细节:

3.1 API依赖图的构建

Rust 库函数包含结构、函数签名和所需参数等一系列信息。测试一个 Rust 库通常意味着测试其中所有的 API 函数,因此需要调用所有的 API 函数。然而,大部分 Rust库中的函数需要通过传递参数才能调用。对于需要基础数据类型或常见数据类型作为参数的函数,本文将提供由模糊测试生成的字符来作为传递参数,该字符将由工具生成。对于需要非基础数据类型作为参数的函数,这些参数通常只能通过其它函数的返回值来提供,这就形成了函数之间所谓的依赖关系。

因此,为了使函数调用更加简洁有序,本文通过静态分析方法获取 Rust 库中的 API信息,并构建了敏感 API 依赖关系图,这是受到 RULF 工作的启发而来的。虽然 RULF采用的 API 依赖关系图只包含简单的 API 依赖信息,不能满足本论文所需的序列生成方法。因此,需要通过更多静态分析方法来获取所需信息,以保证序列生成方法的正常运行。

本文使用rustdoc工具从Rust库中提取API的信息,包括名称,输入,输出,是否包含不安全代码,以及泛型类型的约束。文章根据API的输入和输出类型之间的兼容性,构建了一个带标签的API依赖图,表示API之间的依赖关系和依赖种类。

3.2 参数提供器

文章收集了Rust库中定义的数据结构类型,以及一些常用的数据结构类型,作为参数提供器,用于为泛型函数提供类型候选。

当序列生成过程中涉及到泛型类型时,主要问题在于如何选择数据类型作为参数调用目标方法。本文提出了通过参数供给的方法来实现泛型函数的调度。当序列生成过程时涉及到泛型时,若无确定的数据类型,则会通过参数供给器获取。由于泛型类型不仅能由库定义的数据类型提供,还可能由常见的数

据类型提供,而这些类型可能不会在库中特别说明。因此,为了解决此类情况,参数供给器不仅来源于库定义的数据类型,还包括一些预设的数据类型。在接下来的部分中,将作为泛型类型的参数称为泛参。

3.3 基于池的序列生成

目前可用的生成模糊测试目标方法中,RULF通过遍历图的方法,实现了工具自动生成模糊测试目标,方法主要分为两步:使用 Rust 库生成 API

序列,再将所生成的序列构建成适用于模糊测试的模糊测试目标。然而,该工作的方法存在以下问题:(1) API 序列的针对性差,不能有效覆盖存在不安全行为的函数或者只能通过特定执行序列才能触发的漏洞。(2) 因深度受限,无法有效探索要求较高深度的API。虽提出了回溯搜索方法生成长序列,但仍存在 API 缺失的情况。(3) 序列检查方法尚不完善,可能无法通过 Rust 编译器检查。

因此,为更好地生成高质量的模糊测试目标,本文提出了以下改进:1. 需要具有针对性的方法,以生成具有优先错误触发能力的模糊测试目标。2. 在不牺牲速度和质量的前提下,探索更深层次的 API。3. 随着功能的增加,需要全面而精确的语法和语义检查,来确保序列的合法性。

文章提出了一种基于池的方法,根据API依赖图和API池生成多样化的API序列。API池是一个包含多个API的集合,每个API可能有多次出现。文章根据API的不安全性和依赖性,确定每个API的初始数量。文章使用一种启发式算法,从API池中选择API,优先选择数量较多的API。文章还使用了一个探索阈值,当API池中消耗的API的比例超过阈值时,API池会重置,以便生成更长的API序列。

3.4 泛型支持和有效性检查

文章提出了一种调度方法,用于调用泛型函数。文章维护了一个泛型签名和具体类型的哈希映射,以确保API序列中泛型类型参数的一致性。文章使用了一个类型推断引擎,结合参数提供器,根据API依赖和泛型约束,推断泛型参数的具体类型,并将其传递给其他函数。文章还对API序列进行了移动-借用检查和泛型声明检查,以确保API序列的语法和语义有效性。

3.5 返回值回调

文章尝试使用API序列中的API的返回值,作为另一个API的输入,以利用内存相关的漏洞。文章对每个调用的API的返回值进行了反向移动-借用检查,以确定是否可以使用它,然后搜索一个可调用的函数。

四、实验效果

任务和性能:文章在50个流行的Rust库上评估了RPG,使用AFL++作为模糊测试工具。文章使用了以下指标来衡量RPG的性能:

  • API覆盖率:表示生成的模糊测试目标覆盖了多少比例的可达API。文章的结果显示,RPG的API覆盖率为71.8%,显著高于RULF的48.9%。

  • 依赖覆盖率:表示生成的模糊测试目标覆盖了多少比例的API依赖。文章的结果显示,RPG的依赖覆盖率为11.1%,显著高于RULF的3.7%。

  • 目标数量:表示生成的模糊测试目标的数量。文章的结果显示,RPG的目标数量为1,165,低于RULF的1,481,说明RPG生成的目标更精简和高效。

  • 目标有效性:表示生成的模糊测试目标是否能够通过编译和运行。文章的结果显示,RPG的目标有效性为100%,高于RULF的94.9%,说明RPG生成的目标更符合Rust的语法和语义规则。

  • 漏洞发现能力:表示生成的模糊测试目标能够发现多少个漏洞。文章的结果显示,RPG能够发现25个之前未知的漏洞,高于RULF的8个,说明RPG生成的目标更能够触发Rust库中的隐藏漏洞。

五、案例研究

添加图片注释,不超过 140 字(可选)

六、局限性讨论

参数提供器的局限性:文章的方案使用了一个参数提供器,包含了Rust库中定义的数据结构类型和一些常用的数据结构类型,作为泛型参数的候选。然而,这个参数提供器可能不能覆盖所有可能的类型,导致一些泛型函数无法被调用。文章的方案也没有考虑用户自定义的类型,可能导致一些泛型函数的调用不符合用户的期望。

类型推断的不完善性:文章的方案使用了一个轻量级的类型推断引擎,根据API依赖和泛型约束,推断泛型参数的具体类型。然而,这个类型推断引擎可能不能处理一些复杂的类型关系,例如多态性,继承,重载等,导致一些泛型函数的调用不正确或失败。

模糊测试的不确定性:文章的方案使用了AFL++作为模糊测试工具,对生成的目标进行模糊测试,以发现漏洞。然而,模糊测试本身是一个不确定的过程,可能受到很多因素的影响。

六、总结和展望

6.1 总结

  • 文章提出了一种自动化的模糊测试目标生成技术,用于支持Rust库的模糊测试,能够有效地检测Rust库中由不安全代码或复杂API序列交互导致的漏洞。

  • 文章提出了一种基于池的序列生成和过滤方法,能够生成多样化和深度的API序列,覆盖更多的API和依赖,同时保持目标的精简和高效。

  • 文章提出了一种泛型支持和有效性检查方法,能够处理Rust库中广泛使用的泛型函数,通过类型推断和参数提供器为泛型参数提供合适的类型,并保持类型的一致性,同时对API序列进行移动-借用检查和泛型声明检查,以确保API序列的语法和语义有效性。

  • 文章在50个流行的Rust库上评估了RPG的性能,使用AFL++作为模糊测试工具,发现了25个之前未知的漏洞,显著优于现有的方案。

6.2 未来工作

  • 尽管本文提出的多种序列生成方法以及泛型调度方法已经能够有效生成模糊测试目标,但在实际代码库中,仍有一些无法调用的函数。主要是因为这些函数依赖于其它库的数据类型。因此,未来的模糊测试目标生成可以协同生成多个库的序列,并考虑Rust 库的交互。

  • 本文从提高模糊测试目标的角度来改进 Rust 库的模糊测试结果,但目前仍然使用 AFL 等传统框架来实现模糊器。因此,在未来的 Rust 库模糊测试中,可以通过改进模糊器使之更适配于 Rust 库的特性,从而检测更多的错误

  • 扩展参数提供器,以覆盖更多的类型,包括用户自定义的类型,以增加泛型函数的调用可能性和符合用户的期望。改进类型推断引擎,以处理更复杂的类型关系,例如多态性,继承,重载等,以增加泛型函数的调用正确性和成功率。

【参考文献】

[1] RPG: Rust Library Fuzzing with Pool-based Fuzz TargetGeneration and Generic Support. ICSE 2024.

[2] RULF: Rust library fuzzing via API dependency graph traversal. ASE 2021.

[3] Understanding memory and thread safety practices and issues in real-world Rust programs. PLDI 2020.

[4] Rust Library Fuzzing. IEEE Software 39, 5 (2022), 105–108.

[5] How do programmers use unsafe Rust? OOPSLA 2020.

[6] MirChecker: Detecting Bugs in Rust Programs via Static Analysis. CCS 2021

这篇关于RPG:一种面向Rust库的模糊测试目标自动生成技术(ICSE‘24)的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/484059

相关文章

性能测试介绍

性能测试是一种测试方法,旨在评估系统、应用程序或组件在现实场景中的性能表现和可靠性。它通常用于衡量系统在不同负载条件下的响应时间、吞吐量、资源利用率、稳定性和可扩展性等关键指标。 为什么要进行性能测试 通过性能测试,可以确定系统是否能够满足预期的性能要求,找出性能瓶颈和潜在的问题,并进行优化和调整。 发现性能瓶颈:性能测试可以帮助发现系统的性能瓶颈,即系统在高负载或高并发情况下可能出现的问题

字节面试 | 如何测试RocketMQ、RocketMQ?

字节面试:RocketMQ是怎么测试的呢? 答: 首先保证消息的消费正确、设计逆向用例,在验证消息内容为空等情况时的消费正确性; 推送大批量MQ,通过Admin控制台查看MQ消费的情况,是否出现消费假死、TPS是否正常等等问题。(上述都是临场发挥,但是RocketMQ真正的测试点,还真的需要探讨) 01 先了解RocketMQ 作为测试也是要简单了解RocketMQ。简单来说,就是一个分

AI一键生成 PPT

AI一键生成 PPT 操作步骤 作为一名打工人,是不是经常需要制作各种PPT来分享我的生活和想法。但是,你们知道,有时候灵感来了,时间却不够用了!😩直到我发现了Kimi AI——一个能够自动生成PPT的神奇助手!🌟 什么是Kimi? 一款月之暗面科技有限公司开发的AI办公工具,帮助用户快速生成高质量的演示文稿。 无论你是职场人士、学生还是教师,Kimi都能够为你的办公文

【专题】2024飞行汽车技术全景报告合集PDF分享(附原数据表)

原文链接: https://tecdat.cn/?p=37628 6月16日,小鹏汇天旅航者X2在北京大兴国际机场临空经济区完成首飞,这也是小鹏汇天的产品在京津冀地区进行的首次飞行。小鹏汇天方面还表示,公司准备量产,并计划今年四季度开启预售小鹏汇天分体式飞行汽车,探索分体式飞行汽车城际通勤。阅读原文,获取专题报告合集全文,解锁文末271份飞行汽车相关行业研究报告。 据悉,业内人士对飞行汽车行业

pdfmake生成pdf的使用

实际项目中有时会有根据填写的表单数据或者其他格式的数据,将数据自动填充到pdf文件中根据固定模板生成pdf文件的需求 文章目录 利用pdfmake生成pdf文件1.下载安装pdfmake第三方包2.封装生成pdf文件的共用配置3.生成pdf文件的文件模板内容4.调用方法生成pdf 利用pdfmake生成pdf文件 1.下载安装pdfmake第三方包 npm i pdfma

poj 1258 Agri-Net(最小生成树模板代码)

感觉用这题来当模板更适合。 题意就是给你邻接矩阵求最小生成树啦。~ prim代码:效率很高。172k...0ms。 #include<stdio.h>#include<algorithm>using namespace std;const int MaxN = 101;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int n

poj 1287 Networking(prim or kruscal最小生成树)

题意给你点与点间距离,求最小生成树。 注意点是,两点之间可能有不同的路,输入的时候选择最小的,和之前有道最短路WA的题目类似。 prim代码: #include<stdio.h>const int MaxN = 51;const int INF = 0x3f3f3f3f;int g[MaxN][MaxN];int P;int prim(){bool vis[MaxN];

poj 2349 Arctic Network uva 10369(prim or kruscal最小生成树)

题目很麻烦,因为不熟悉最小生成树的算法调试了好久。 感觉网上的题目解释都没说得很清楚,不适合新手。自己写一个。 题意:给你点的坐标,然后两点间可以有两种方式来通信:第一种是卫星通信,第二种是无线电通信。 卫星通信:任何两个有卫星频道的点间都可以直接建立连接,与点间的距离无关; 无线电通信:两个点之间的距离不能超过D,无线电收发器的功率越大,D越大,越昂贵。 计算无线电收发器D

【测试】输入正确用户名和密码,点击登录没有响应的可能性原因

目录 一、前端问题 1. 界面交互问题 2. 输入数据校验问题 二、网络问题 1. 网络连接中断 2. 代理设置问题 三、后端问题 1. 服务器故障 2. 数据库问题 3. 权限问题: 四、其他问题 1. 缓存问题 2. 第三方服务问题 3. 配置问题 一、前端问题 1. 界面交互问题 登录按钮的点击事件未正确绑定,导致点击后无法触发登录操作。 页面可能存在

业务中14个需要进行A/B测试的时刻[信息图]

在本指南中,我们将全面了解有关 A/B测试 的所有内容。 我们将介绍不同类型的A/B测试,如何有效地规划和启动测试,如何评估测试是否成功,您应该关注哪些指标,多年来我们发现的常见错误等等。 什么是A/B测试? A/B测试(有时称为“分割测试”)是一种实验类型,其中您创建两种或多种内容变体——如登录页面、电子邮件或广告——并将它们显示给不同的受众群体,以查看哪一种效果最好。 本质上,A/B测