KernelGPT: LLM for Kernel Fuzzing

KernelGPT: Enhanced Kernel Fuzzing via Large Language Models

  • 1.Introduction
  • 2.Background
    • 2.1.Kernel and Device Drivers
    • 2.2.Kernel Fuzzing
      • 2.2.1.Syzkaller规约
      • 2.2.2.规约生成
  • 3.Approach
    • 3.1.Driver Detection
    • 3.2.Specification Generation
      • 3.2.1.Command Value
      • 3.2.2.Argument Type
      • 3.2.3.Type Definition
    • 3.3.Specification Validation and Repair
  • 4.Implementation
  • 5.Evaluation
    • 5.1.Overall Results
    • 5.2.Comparison with Baselines
    • 5.3.Kernel Bug Detection
  • 6.Conclusion
  • 7.参考文献

1.Introduction

kernel fuzzing是检测内核漏洞(crash、缓冲区溢出写等)的常用手段,kernel fuzzing通常生成大量的system call作为test input。

Syzkaller是目前最受欢迎的一款kernel fuzzing工具。许多工作从种子生成种子选择引导变异系统调用规约生成4个方面改进Syzkaller。其中使用syzlang编写的系统调用规约成为其中最关键的组件之一,对Syzkaller的有效性做出了重大贡献,使其能够涵盖更多的内核模块。这些规约指定了系统调用的类型及其相互依赖关系,从而使得能够生成更多有效的系统调用序列,深入探索内核代码逻辑。

然而,手写系统调用规约需要对内核有深入了解。为解决这个问题,近年来的一些研究专著于自动化生成系统调用规约,特别是针对设备驱动程序的系统调用规约生成。

DIFUSE和SyzDescribe利用静态代码分析来识别设备驱动程序系统调用处理程序并推断其相应的规约,下图展示了基于静态分析技术的规约生成工具的工作流程。

  • 最初,专家们借助于他们对内核代码库和现有Syzkaller规约示例的理解手动定义规则,将设备驱动程序源代码转换为规约。

  • 然后,这些规则硬编码到静态分析工具中,这是一个挑战性较大且耗时的过程。生成的系统调用规约的准确性和有效性严重依赖于这些映射规则的全面性。而且,随着内核代码库的演变,这些映射规则经常发生变化。

请添加图片描述

以图2a和图2b为例,这两图展示了与设备映射驱动程序相关的两个结构体变量的源代码,该驱动程序负责将物理块设备映射到更高级别的虚拟块设备。

具体而言,变量 _ctl_fops_dm_misc 是设备操作处理程序及其引用,对于推断设备名称至关重要。当前的系统调用规约生成器,如SyzDescribe,通常依赖于结构体 miscdevice 中的 .name 字段来确定用于驱动程序交互的设备名称,这是一种常规用例。

然而,在这个例子中,正确的设备名称实际上是在 .nodename 字段中指定的,这是一种合法但罕见的用例,导致SyzDescribe错误地推断。此外,SyzDescribe还无法准确分析 ioctl 的命令值,这是与设备交互的系统调用接口。这是因为命令值在代码中被修改过 —— cmd = _IOC_NR(command) ——其中 command 是用户提供的命令值。这样的情况在SyzDescribe中没有考虑到,导致其在生成的规约中错误地将 cmd 而不是用户提供的 command 用作命令值,如图2c所示。

请添加图片描述

为此,作者提出了基于LLM的规约推断方法KernelGPT,Kernel GPT包含下面几个步骤:

  • 1.使用LLM根据设备操作处理程序代码及其引用来推断设备名称及生成其初始化规约。

  • 2.为了恢复驱动程序的命令值、参数类型和类型定义,KernelGPT迭代地应用LLM来分析相关的源代码。

  • 3.最后,KernelGPT通过询问LLM来处理遇到的错误消息来验证和修复生成的规约。

2.Background

2.1.Kernel and Device Drivers

1.内核

内核是操作系统的核心,为用户空间应用程序提供关键功能,包括虚拟内存、文件系统、网络和设备访问。为了保障所有应用程序和用户的安全,用户空间与内核之间的交互受限于明确定义的系统调用(syscall)接口,如POSIX标准。通过syscalls由用户空间应用程序触发的内核漏洞和崩溃具有重大风险,因为它们影响所有使用内核的应用程序,攻击可能绕过内核执行的所有安全策略。因此,通过syscall接口检测内核漏洞至关重要。

2.设备驱动程序

在Linux中,设备被抽象为文件,通常位于 /dev 目录中,并且可以通过相同的syscall机制访问。设备驱动程序在初始化时向内核注册其syscall处理程序。然后,内核将从用户空间分发syscalls到相应的驱动程序处理程序。

在图2中的示例中,驱动程序首先构建了 struct file_operations 类型的变量 _ctl_fops(图2a),将syscalls映射到特定的驱动程序处理程序,如 .open.unlocked_ioctl 指向的函数。然后,驱动程序创建了 struct miscdevice 类型的变量 dm_misc,将 struct file_operations 整合,并在 .nodename 字段中指定设备文件。最后,驱动程序调用 misc_register(&_dm_misc) 向内核注册。当应用程序试图打开由 .nodename 表示的文件(如 /dev/mapper/control),内核会调用注册的 dm_open 函数,并将其返回的文件描述符(fd)与设备映射驱动程序关联。以后,内核将使用 fd 分派到相应的注册处理程序,例如 ioctl(fd,...) 将触发 dm_ctl_ioctl

驱动开发者通常在处理程序中实现标准控制逻辑,如 .open.close.release。然而,许多驱动程序还需要独特的控制逻辑,这在syscall接口中没有相似的对应,例如,设备映射驱动程序需要一个操作来获取所有 dm 设备名称的列表(图2d)。对于这样的驱动程序特定操作,开发者通常使用通用的 ioctl(int fd, unsigned long request, void *argp) syscall作为调度程序来调用相应的驱动程序函数。

  • 第一个参数 fd 是设备文件的打开文件描述符。

  • 第二个参数 request 用作命令标识符以选择要执行的操作。

  • 第三个参数 argp 被转换为驱动程序特定的数据类型,以在内外传递信息。例如,要获取 dm 设备名称列表,应用程序首先构造驱动程序特定的结构 struct dm_ioctl data = ...;,然后通过 int fd = open("/dev/mapper/control"); 打开设备文件。然后,通过 ioctl(fd, DM_LIST_DEVICES, &data); 可以检索设备名称。由于每个驱动程序可能需要与特定命令标识符相关联的唯一数据类型,这种专门的使用将 ioctl 转化为成千上万个syscalls,其接口在很大程度上没有得到很好的文档化或标准化。

2.2.Kernel Fuzzing

模糊测试(fuzzing)是检测内核漏洞最有效的技术之一。kernel fuzzers生成syscalls并在目标内核上执行,通常启用sanitizers,直到发生崩溃。Syzkaller是基于覆盖引导的内核fuzzer,已发现并修复了数千个内核漏洞。Syzkaller使用领域特定语言syzlang定义syscall规约,引导测试用例生成,使其能够深入内核的代码路径。

2.2.1.Syzkaller规约

允许在定义syscall时考虑参数的类型和依赖关系,允许为同一个syscall定义多个实例,每个实例可以具有具体的参数值。再以 ioctl 为例,无类型信息的指针的具体类型取决于命令标识符的值,而这又取决于前一次 open 调用使用的具体文件名。这使得syzkaller能够灵活处理依赖于先前调用结果的情况,如 ioctl 中底层类型依赖于命令标识符的值。

图3展示了MSM驱动程序的三个syscall的规约(为简化起见,某些参数和名称已被省略或缩短)。syscall openat$msm 是syscall openat的一个实例,其中msm是一个自定义但唯一的名称,用于区分syscall实例。该规约为 openat$msm 定义了具体的参数值 "/dev/msm" — MSM设备的名称。对于Syzkaller可以动态创建的参数,规约概述了它们的类型,例如 ioctl$NEWioctl$CLOSE 的arg参数分别是指向结构体 drm_msm_submitqueue 和整数 msm_submitqueue_id 的指针。

请添加图片描述
在syzlang中,有一种特殊类型 resource,用于表示syscalls之间的依赖关系。一个资源必须在被其他调用用作输入之前由调用生成。图3中的规约引入了两个资源,fd_msm 代表一个打开的文件描述符,msm_submitqueue_id 代表MSM驱动程序内部使用的队列ID。资源 fd_msmopenat$msm 返回,然后作为 ioctl$NEWioctl$CLOSE 的输入参数使用。因此,Syzkaller只会在openat$msm之后放置 ioctl$NEWioctl$CLOSE

更细粒度的依赖关系也得到支持,比如在结构体中指定对一个字段的依赖关系。例如,对于 ioctl$NEWarg 参数的 inout 注解表示结构体 drm_msm_submitqueue 既用作输入又用作输出。在 drm_msm_submitqueue 中,字段 msm_submitqueue_id 具有out 注解,表示它是输出。由于 ioctl$CLOSEmsm_submitqueue_id 为输入,因此只有在 ioctl$NEW 填充了msm_submitqueue_id 之后才能生成 ioctl$CLOSE。有了这个规约,Syzkaller可以大大缩小搜索空间,并专注于 fuzz drm_msm_submitqueue 的内部字段。

2.2.2.规约生成

尽管它们很有效,规约通常是由Syzkaller和内核开发人员手动编写的,需要开发人员对内核和特定内核模块有深入的专业知识。因此,现有的Syzkaller规约只涵盖一部分syscalls,特定设备驱动程序的规约则相对缺乏。现有的规约也可能在内核演进时变得过时。

自动化规约生成显然是研究热点,但面临一些关键挑战。其中之一是提取预期的参数值类型定义。另一个是推断syscalls之间的依赖关系并在参数中编码这些依赖关系。未能解决这些挑战将导致不准确的规约,降低模糊测试活动的有效性。

在规约自动生成方面:

  • KSG通过打开现有设备文件并探测内核以找到被访问的数据结构,动态地找到syscall处理程序结构。然后,通过符号执行收集类型和范围信息。

  • DIFUSE和SyzDescribe都对内核源代码进行静态分析,识别常见的实现模式以生成规约。

    • DIFUZE从常见设备注册函数使用的数据结构列表中找到syscall处理程序。

    • SyzDescribe首先找到内核模块的初始化函数,然后追踪到找到syscall处理程序的函数指针。

    • DIFUZE和SyzDescribe都遵循特定的编程模式,以提取设备名称和命令标识符,例如,在处理程序内部的 switch case 可能根据命令值调用相应的子处理程序。现有的规约生成方法主要依赖于在分析工具中硬编码人工总结的模式,以将源代码实现转换为syscall规约。相反,KernelGPT利用LLMs的潜力自动化和改进规约推断规则的学习,从而提高性能。

3.Approach

图4为KernelGPT的overview,它利用代码提取器和LLM自动生成驱动程序规约以增强kernel fuzzing。KernelGPT以内核代码库和定位的设备操作处理程序为输入,通过三个自阶段操作:1.Driver Detection(驱动程序检测),2.Specification Generation(规约生成),以及3.Specification Validation and Repair(规约验证和修复)。

  • 首先,KernelGPT使用LLMs通过推断设备名称和它们的初始化规约来识别驱动程序。

  • 随后,KernelGPT确定描述设备的 ioctl 处理程序的命令值、参数类型和类型定义。(这个应该是test input对应的syscall所需要的具体参数)

  • 最后,KernelGPT验证生成的规约。如果发现错误,它将尝试用错误信息来引导LLM修复错误。

请添加图片描述
在解析代码时,作者使用的LLVM的API进行代码解析搜索内核代码,以定位初始化 ioctl 处理程序函数的设备操作处理程序结构的实例。

具体来说,作者搜索操作处理程序结构中的 ioctlunlocked_ioctl 字段的初始化实例。例如,图2a中的设备映射驱动程序通过使用dm_ctl_ioctl 函数初始化 _ctl_fops 结构中的 unlocked_ioctl 字段。作者标记 dm_ctl_ioctlioctl 处理程序,_ctl_fops 为设备操作处理程序。

KernelGPT的重点是从源代码推断出规约,而不是定位设备操作或 ioctl 处理程序。

3.1.Driver Detection

Driver Detection的主要目的是推测驱动设备名称以及生成初始化操作对应的规约

图5为Driver Detection用到的prompt示例,包括: 指令(Instruction部分)、操作处理程序的源代码(结构体变量 _ctl_fops 的初始化部分)及其引用(结构体 _dm_misc 的初始化部分,其中引用了 _ctl_fops),最后是由LLMs生成的规约。LLM不仅将确定设备名称(图5中的 DEVICE NAME),还将分析与设备关联的初始化规约(INITIALIZATION)。

通常,对于大多数驱动程序,初始化操作是使用 syscall openatsyz_open_dev 进行描述的。设备映射驱动程序中,操作处理程序_ctl_fopsstruct miscdevice _dm_misc 的初始化代码中被引用。通过对这个部分代码的分析,LLM能够确定正确的设备名称,本例中为mapper/control,基于 miscdevice 结构体中的 nodename 字段。

请添加图片描述

3.2.Specification Generation

在这个阶段,作者通过利用LLM分析驱动程序的源代码生成 ioctl 的规约。为了提高LLM的性能,作者将该过程分为三个阶段:推断命令值识别参数类型类型定义

这种结构化的方法使LLM能够在每个阶段集中精力在一个特定的方面,从而提高效率和专注力。与设备名称推断过程类似,作者在规约生成的每个阶段都使用few-shot prompt。

这一步在实现时需要考虑两方面因素:

  • 1.尽管像GPT-4这样的最新LLM支持128K的上下文大小,但向LLM提供所有与驱动程序相关的代码仍然是不切实际的。

  • 2.这一步目标是推断 ioctl 处理程序的命令值和参数类型,不是所有代码或辅助函数都与这一目标相关。

3.2.1.Command Value

推断命令值示例如图6所示。prompt包括与推断任务相关的函数的源代码,涵盖 ioctl 处理程序函数和与命令值分析相关的任何辅助函数。比如之前 _ctl_fops 结构体的 unlocked_ioctl 字段被赋值为 dm_ctl_ioctl 函数,那么推断命令值就需要分析 dm_ctl_ioctl 函数的源代码。

LLM的输出是成功推断的命令值集合。如果推测命令值还需要分析其它函数,作者要求LLM列出“缺失”分派函数的名称和调用详细信息(分析结果 UNKNOWN 字段)。此外,还包括使用命令值变量的代码片段。如果LLMs识别出任何未知的命令值,KernelGPT将继续分析新识别出的分派函数,并整合其在上一步中的使用信息。前一步 的UNKNOWN 字段的输出在引导后续步骤时作为参考。

比如在示例中分析 dm_ctl_ioctl 时LLM反馈需要继续分析 ctl_ioctl 函数,继续分析 ctl_ioctl 时LLM反馈需要分析 lookup_ioctl 函数,不过在分析 ctl_ioctl 时,LLM已经确定参数值 DM_VERSION。(这可能意味着推断命令值设计多轮分析多个结果),到目前为止,LLM已经确定命令值 DM_VERSION 的处理函数为 ctl_ioctl

请添加图片描述

3.2.2.Argument Type

在确定了命令值之后,接下来便要分析该命令对应的参数类型,如图7 prompt所示。这一步骤的输入为命令推断的输出,包括相关函数和展示参数用法的代码片段。KernelGPT随后提取这些相关函数的源代码,并将其输入LLM,由它们来识别参数类型。如果涉及其它函数,那么这个类型仍然会被标记为 UNKNOWN。在这种情况下,KernelGPT会利用LLMs提供的新信息继续其分析工作。

图7展示了设备映射器驱动程序中针对 DM_REMOVE_ALL 命令值的参数推断的实际例子。在之前的步骤中,LLM识别与该命令值相关的函数为 remove_all,以及引用该函数的代码。因此,KernelGPT向LLM提供了 remove_all 的源代码,以指导参数类型推断。通过分析其签名,LLM推断出该参数应该是指向 struct dm_ioctl 结构的指针。此外,LLM将 struct dm_ioctl放置在 TYPES 字段中,为下一阶段的类型定义分析做好准备。

注:这一步SyzDescribe通过规则进行推断,SyzDescribe只分析 ioctl 调用分析对应的命令值及对应的参数类型。比如下面代码片段中,SyzDescribe通过对 ifswitch 的条件分析判断命令值为 cmd_1cmd_2cmd_3 之一,当命令值为 cmd_1 时,参数 arg 会被转换为 struct xx_type 类型。因此这里需要复杂的启发式规则识别参数类型。因此推测用LLM是为了更好地识别这类转换操作识别真正的参数类型。

long xx_ioctl(struct file *file, int cmd, long arg) {switch (cmd) {case cmd_1:struct xx_type xx_arg;copy_from_user(&xx_arg, arg, sizeof(xx_arg));...break;case cmd_2:fd = get_unused_fd_flags(...);file = anon_inode_getfile(..., &no_fops, ...);fd_install(fd, file);return fd;default:xx = file->private_date;if (xx.ops->ioctl)xx.ops->ioctl(file, cmd, arg);}if (cmd == cmd_3) {...}...

请添加图片描述

3.2.3.Type Definition

在识别了参数类型之后,KernelGPT继续为这些类型生成规约。图8展示了在这一阶段使用的提示。本质上,KernelGPT从Linux内核代码库中检索类型定义源代码。然后将这个源代码呈现给LLM,由它们创建相应的Syzkaller规约。在类型定义中引用了嵌套类型的情况下,LLM被指示在它们的输出中将它标记为 UNKNOWN。这些被标记的类型将在后续步骤中进一步分析。

图8中展示的类型定义推断例子涉及一个示例:PhysDevAddr_struct 结构体中的一个字段是一个由 SCSI3Addr_struct 结构体类型组成的数组。由于这个新引用的结构体 SCSI3Addr_struct 的源代码没有包含在提供的信息中,因此预期LLM会将其标识为 UNKNOWN 。这种标识表明SCSI3Addr_struct 需要在后续步骤中进一步分析。(疑问:这一步好像可以直接用解析工具层次化生成,无需LLM

请添加图片描述

3.3.Specification Validation and Repair

在这一阶段,受到最新基于LLM的程序修复研究启发,作者旨在验证由KernelGPT生成的规约,并自动更正任何无效的部分。这一步骤极为关键,因为LLM在规约生成过程中可能出错。为了解决这一问题,作者采用了Syzkaller的工具syz-extract来验证规约的有效性,该工具能够识别语法错误,如未定义的变量和类型。首先,KernelGPT通过syz-extract提供的错误信息定位规约中的错误之处,并将错误信息与相应规约匹配。接着,针对检测到错误的规约,KernelGPT通过提供few-shot prompt向LLM反馈。

如图9所示,这个过程包括向LLM提供错误的规约、相应的错误信息以及内核代码库中的相关源代码以供修复。之后,LLM预期将输出修正后的正确规约。

这里 vfio_pci_hot_reset_info 的类型描述最初是错误的。这是因为syzlang要求数组 [type, length]规约 中的长度必须是一个常数,而g中使用了可变长度的数组。在syzlang中,可变长度数组的正确格式仅为 array[type]。通过分析syz-extract生成的错误信息 “count is unsupported on all arches”,LLMs修复了这个问题,通过将 devices 重新定义为可变长度数组,并将count指定为类型 len[devices],从而使得规约与syzlang的要求保持一致。

请添加图片描述

4.Implementation

1.Source Code Extractor

作者采用LLVM工具链实现了Linux内核源代码提取器。该提取器通过模式匹配解析内核代码库,识别设备操作处理程序,并准备输入数据供KernelGPT使用。此外,它还提取操作处理程序内的 ioctl 处理程序及其引用位置,并编译内核中的所有函数、结构体、联合和枚举定义。这些定义在LLMs需要时,为规约生成和修复提供指导。

2.LLM

KernelGPT基于最先进的LLM GPT4构建。在每一步分析中,作者通过OpenAI API访问GPT4,并设置低温度参数为0.1。分析的最大迭代次数 MAX_ITER 默认设置为5。

3.Few-shot prompting

  • 为了推断设备名称和命令值,作者采用了3-shot prompt来适应LLM的上下文大小限制。这是因为在这两个步骤中涉及到的函数源代码通常较长,这需要限制少量示例的数量。

  • 相比之下,对于其他阶段,如参数类型推断和类型定义分析,作者选择了6次提示。

  • 在修复阶段,考虑到潜在的错误多样性以及必要的修复信息和错误消息通常的简洁性,作者选择了9次提示的策略。这种方法旨在为LLM提供对修复过程的更广泛理解。

4.Driver Selection

在初步评估中,作者专注于为Syzkaller中未曾描述的驱动程序或处理程序创建规约。这一重点极为重要,因为缺少规约的驱动程序通常未经过彻底测试。因此,这些驱动程序成为作者的关注焦点。在设备名称分析之后,作者首先确认Syzkaller是否已存在该设备的规约。如无现有规约,作者便着手生成新的规约。目前,作者的主要工作集中在常规驱动程序,如字符和块设备,而网络和USB设备的规约生成则计划在未来进行。

5.Evaluation

  • RQ1:KernelGPT为未描述的内核驱动生成的规约数量及其质量如何?质量主要通过覆盖率衡量。

  • RQ2:与baseline相比,KernelGPT生成的系统调用规约的质量如何?主要也是通过覆盖率比较。

  • RQ3:KernelGPT生成的规约能否检测到内核中的real-world bug?

作者选择了Linux内核版本6.7作为target,该版本于2023年11月5日发布,hash标识为d2f51b。此外,为了规约生成和评估,作者使用了Linux内核的syzbot配置。这个选择为谷歌在通过QEMU对Linux内核进行模糊测试时的决策。

作者的Fuzzing配置遵循默认的Syzkaller设置,使用4个QEMU实例,每个实例利用2个CPU核心。为了确保公平比较并减轻崩溃重现的影响,作者在收集和比较覆盖范围结果时禁用了reproduce 特性。为了展示KernelGPT生成的规约的质量,作者选择了SyzDescribe (当前SOTA系统调用规约生成方法)和由人类专家制定的现有Syzkaller规约作为基准。

5.1.Overall Results

在syzbot内核配置下检测到132个 ioctl 处理程序,不包括网络和USB驱动程序处理程序。在这些设备中,有50个(占37.9%)根据KernelGPT推断的设备名称在Syzkaller中被识别为缺少规约。然后,作者为这些未描述的驱动程序生成规约,成功推断出其中的39个,如表1所示。

请添加图片描述
对于其余设备未能生成规约的失败主要归因于几个原因。

  • 首先,它们代码的复杂逻辑使得LLMs难以理解,特别是当 ioctl 函数的源代码过长时,阻碍了GPT4的理解能力。

  • 此外,当要分析的源代码超过GPT4的上下文限制时,它就无法正确推断。

在KernelGPT成功生成的39个规约中,有24个直接通过验证,另外8个通过KernelGPT成功修复,使它们能够通过验证检查。然而,KernelGPT无法修复其余的7个规约。对于32个有效的规约,作者使用这些经过验证的规约运行Syzkaller,并其中有17个可以执行。设备无法执行的一个潜在原因是它们需要复杂的初始化步骤,这些步骤无法在规约中定义(例如,像 syz_open_dev 这样的辅助函数),或者无法被GPT4准确推断。另一个可能的因素是这些设备在syzbot内核配置中没有启用。

作者分别对每个新检测到的驱动程序进行了8小时的测试,使用了默认设置。结果显示在表2中,# Descriptions 列显示每个设备的系统调用规约数量,Cov 列是作者为每个设备独立生成的规约进行8小时模糊测试时覆盖的行数。 Unique Cov 列反映了与标准Syzkaller设置相比的唯一覆盖情况,在相同条件下激活了所有3,912个系统调用。在这个标准设置中,覆盖了143,838行。由Kernel GPT生成的先前未解决的驱动程序的规约增加了129个(3.3%)规约,并有助于覆盖额外的6,668个(5%)唯一行。这些数字突显了为先前未解决的驱动程序提供规约的重要性,并展示了作者生成的规约的有效性。

请添加图片描述
除了单独运行每个驱动程序的规约外,作者将所有新驱动程序的规约与原始的Syzkaller规约集成在一起。这意味着在一次运行中,同时执行由KernelGPT生成的新规约和Syzkaller中的现有规约。鉴于系统调用数量庞大,约为四千个左右,作者将这个组合运行的模糊测试时长延长到了24小时。随后,将此组合运行的覆盖结果与在相同设置下仅运行现有的Syzkaller规约的结果进行比较。集成KernelGPT为未描述的驱动程序合成的规约已被证明是有效的,触发的崩溃数量比仅使用现有的Syzkaller规约多28.6%(28 vs. 36)。就代码覆盖率而言,由于实验的初步性质和规模较小,结果相对较为适度。由于KernelGPT引入的新系统调用规约数量相对较小(129),与总数(3912)相比,集成后的代码覆盖率增加适度,额外覆盖了1.5K行。尽管如此,即使是这个有限规模的实验也突显了使用KernelGPT推断更多系统调用的规约的巨大潜力,这可能在未来的应用中实现更为有效的内核模糊测试。

5.2.Comparison with Baselines

为评估KernelGPT生成的规约质量,作者选择了10个由baseline方法(Syzkaller和SyzDescribe )规约的“现有”设备。作者使用KernelGPT为这些设备生成规约,并在独立的运行中比较了每个规约的覆盖结果,仅启用了规约中包含的系统调用。

请添加图片描述
表3显示了KernelGPT、SyzDescribe和Syzkaller生成的规约的结果,在8小时的模糊测试后详细列出了系统调用数量、定义的类型和行覆盖情况。KernelGPT实现了最高的行覆盖,超过基线方法21.3%以上,突显了其生成高质量规约以提升模糊测试性能的效果。此外,KernelGPT为驱动程序定义了最多的类型,展示了其在类型分析方面的强大能力。对于SyzDescribe,两个规约未能产生覆盖,其中一个问题源于SyzDescribe对设备名称的错误推断。总体而言,比较结果表明KernelGPT在描述的驱动程序上甚至超过了Syzkaller,预示着将KernelGPT应用于更多驱动程序可能取得更显著的效果。

5.3.Kernel Bug Detection

表4展示了KernelGPT在未描述的驱动程序中检测到的漏洞。到目前为止,KernelGPT已经检测到8个独特的漏洞,其中7个以前是未知的。值得注意的是,所有这些漏洞都无法通过默认配置的Syzkaller检测到。

请添加图片描述

KernelGPT检测到的7个新漏洞均位于两个新描述的驱动程序中,分别是device mapper和CEC。

第一个漏洞是在设备映射器驱动程序中的 ctl_ioctl 函数中发现的 kmalloc 漏洞,而第二个漏洞是在 dm_table_create 函数中发现的 kmalloc 漏洞。

它们的成因不同但相似:驱动程序忽略了对 kvmalloc 分配大小的检查,导致可能分配过大的内存大小。具体而言:

  • bug1崩溃与 dm_ioctl 结构中的 data_size 字段有关。该字段在 copy_param 过程中的数据结构准备阶段中分配内存起着关键作用。

  • bug2问题集中在 DM_TABLE_LOAD_CMD 命令值和 target_count 字段。在执行 dm_table_create 时,这些元素对于分配目标至关重要。值得注意的是,尽管SyzDescribe为此驱动程序生成了一个规约,但其中包含有误的设备文件名、错误的命令值和不精确的类型,因此未能检测到这两个漏洞。第一个漏洞已经得到了内核开发人员的确认。

其余5个的新发现的漏洞都是在CEC驱动程序中发现的,这是一个用于HDMI CEC硬件的标准化内核接口。

  • bug3: 图10包含与 KASAN: slab-use-after-free Read in cec_queue_msg_fh 漏洞相关的代码片段,其中CEC驱动程序从已被 kfree(fh) 释放的变量中读取数据。

  • bug4: 在 cec_transmit_msg_fh 中发生的 ODEBUG漏洞是由于驱动程序试图使用 kfree(data) 释放活动对象。

  • bug5: cec_data_cancel 中的WARNING是由CEC驱动程序内部检查触发的,该检查期望变量处于当前或挂起状态。

  • bug6: INFO: task hung in cec_claim_log_addrs 中的问题是由于内核挂起,因为CEC设备等待配置任务的完成。

  • bug7: 在 cec_transmit_done_ts 中发生的一般保护错误是由于CEC设备尝试引用一个非规范地址,导致内核崩溃。

请添加图片描述

6.Conclusion

在本文中,作者提出了KernelGPT,这是第一个利用LLM自动生成系统调用规约以增强kernel fuzzing的方法。它采用迭代式方法自主生成规约的所有必要组件,并使用验证反馈进一步修复这些规约。初步结果表明,KernelGPT有助于提高Syzkaller的覆盖率,并检测到了7个先前未知的新描述驱动程序中的漏洞。此外,Syzkaller团队表示有兴趣将由KernelGPT生成的规约整合进规约库。

7.参考文献

Yang C, Zhao Z, Zhang L. KernelGPT: Enhanced Kernel Fuzzing via Large Language Models[J]. arXiv preprint arXiv:2401.00563, 2023.

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/648049.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

基于静态顺序表实现通讯录

目录 一、设计框架 1、功能要求​ 2、菜单函数的实现 二、头文件实现​ Contact.h SeqList.h 三、Test.h 四、通讯录的初始化和销毁 五、增加通讯录 六、在通讯录中查找姓名下标 七、删除通讯录 八、显示通讯录 九、查找通讯录 一、设计框架 test.c:通…

《尊思想人文地理环境》新书亮相,叶无为集30年智慧破解环境密码

在探索人与自然和谐共生的今天,叶无为教授的新作《尊思想人文地理环境》应时而生,为读者揭开了地理环境与人文发展之间深刻联系的神秘面纱。本书集结了作者三十多年的实战经验,通过易医体系对大自然的山川河流进行独到解析,融合传…

飞越天空之城

欢迎来到程序小院 飞越天空之城 玩法:左边的按钮是控制小人儿飞起来的方向的,右边的按钮是控制它飞的高度的, 左边控制在正上方时可以让小人儿沿着一个方向飞跃,否则会撞到两边的黑墙, 右边的按钮如果加足够的话&…

GPTs大受欢迎但问题多,企服厂商的AI Agent更被B端客户器重

2023年11月,OpenAI在首届开发者大会上推出了GPTs和Assitant API,不仅改写了AI Agent的构建范式,也把AI智能体的应用推向一个新高潮。 GPTs和GPT商店,使得用户无需编码通过自然语言就能创建并拥有多个专属私人助理,且可…

【Servlet】如何编写第一个Servlet程序

个人主页:兜里有颗棉花糖 欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 兜里有颗棉花糖 原创 收录于专栏【Servlet】 本专栏旨在分享学习Servlet的一点学习心得,欢迎大家在评论区交流讨论💌 Servlet是Java编写的服务器端…

5.【SpringBoot3】文件上传

1. 文件上传到本地 需求分析 在用户更换头像或发布文章时,需要携带一个图片的 url 地址,该 url 地址是当用户访问文件上传接口,将图片上传成功后,服务器返回的地址。所以,后台需要提供一个文件上传接口,用…

Android HIDL概述与绑定模式的实现

一、前言 Android O(8.0) 版本之后,底层实现有了比较大的变化,最显著的一个方面就是 HIDL 机制的全面实施。本文对于理解系统源码中 Gnss、Usb、Camera 等模块的工作原理有极大帮助。 二、HIDL 设计目的 在 Android O(8.0) 之前系统的升级牵扯多方协作…

Python tkinter (5) 选项按钮与复选框

Python的标准Tk GUI工具包的接口 tkinter系列文章 python tkinter窗口简单实现 Python tkinter (1) —— Label标签 Python tkinter (2) —— Button标签 Python tkinter (3) —— Entry标签 Python tkinter (4) —— Text控件 目录 CheckButton 简单示例 获取选中 Ra…

RBD —— Visualizing fractured geometry

RBD Exploded View(与Exploded View SOP类似)从中心炸开几何体,以更好查看被破碎和约束的碎块; 可视化高精度和低精度几何体的不同,Show Proxy Geometry显示代理几何体; Show Constraints显示约束&#xff…

6.jmeter非GUI命令及Beanshell组件

一、非GUI(界面)命令详解 1. -n 使用非gui方式,不能单独使用,必须和-t(指定jmeter的脚本)一起用。 #cmd命令行模式下,进入存放测试jmx文件的目录下 jmeter -n -t hello.jmx只会生成一个log日…

数据结构实验八:排序的应用

目录 一、实验目的 二、实验原理 1.直接插入排序 2.快速排序 三、实验内容 实验1 代码 截图 实验2 代码 截图 一、实验目的 1、掌握排序的基本概念; 2.掌握并实现以下排序算法:直接插入排序、快速排序。 二、实验原理 1.直接插…

如何选择便捷安全的黄金交易平台?

黄金交易平台的介绍 黄金交易平台是一个提供方便、安全的方式进行黄金交易的网上平台。 投资者可以通过这些平台进行黄金的买卖,参与黄金市场的投资活动。 这些平台提供了一个简单易用的界面,让投资者可以方便地进行交易操作。 选择合适的黄金交易平台…

小土堆pytorch学习笔记002

1、TensorBoard的使用 (1)显示坐标: from torch.utils.tensorboard import SummaryWriter import numpy as np from PIL import Imagewriter SummaryWriter("logs") # 写入的位置 log_dir logs # writer.add_image() "…

【LeetCode: 148. 排序链表 + 链表 + 归并排序】

🚀 算法题 🚀 🌲 算法刷题专栏 | 面试必备算法 | 面试高频算法 🍀 🌲 越难的东西,越要努力坚持,因为它具有很高的价值,算法就是这样✨ 🌲 作者简介:硕风和炜,…

今天来看看工商业储能收益模式有哪些

安科瑞武陈燕acrelcy 2023 年有望成为工商业储能的发展元年,主要原因2023年工商业储能的经济性有望大幅提升。工商业储能下游主要为工商业企业,投资是否具有经济性是工商业需求的核心因素之一,而2023年工商业储能经济性或将显著提升&#xf…

shared_ptr 与 unique_ptr 的转换 笔记

推荐B站文章: 6.shared_ptr与unique_ptr_哔哩哔哩_bilibilihttps://www.bilibili.com/video/BV18B4y187uL?p6&vd_sourcea934d7fc6f47698a29dac90a922ba5a3我的往期文章: 独占指针:unique_ptr 与 函数调用-CSDN博客https://blog.csdn.n…

【Docker】构建镜像

一般来说我们不需要自己构建镜像,这些镜像在docker hub上面已经有现成的了,比如常用的数据库、应用软件等。 某些情况我们还是需要自己来构建: 找不到现成的镜像,比如自己开发的应用程序 需要在镜像中加入特定的功能/软件 Docker提供了两种…

C++入门学习(十五)运算符

算术运算符&#xff1a;用于处理四则运算赋值运算符&#xff1a;用于将表达式的值赋给变量比较运算符&#xff1a;用于表达式的比较&#xff0c;并返回一个真值或假值逻辑运算符&#xff1a;用于根据表达式的值返回真值或假值 一、加减乘除 #include <iostream> #incl…

Ubuntu20.04 安装 ROS noetic + MAVROS

本文在 AlphaCatOvO【ROS】在 Ubuntu 20.04 安装 ROS 的详细教程 基础上&#xff0c;根据实际安装经验&#xff0c;稍微进行补充。 一、安装Ubuntu20.04 假设已经正确安装。 二、安装 ROS noetic 2.1 换源 执行 sudo apt update sudo mv /etc/apt/sources.list /etc/apt/…

A股市场风云!深圳开股票账户交易佣金费用最低是多少?

最近A股市场表现出色&#xff0c;呈现出风云状态&#xff01;投资者纷纷涌入股市&#xff0c;推动股指不断攀升。一方面&#xff0c;政府出台了一系列政策来稳定市场&#xff0c;如加强监管力度、推动资本市场改革等&#xff0c;为投资者提供了更多机会和便利条件。另一方面&am…