Linux内核(x86)入口代码模糊测试指南Part 1

本文介绍了Linux内核(x86)模糊测试的重要性,特别是针对入口代码的测试。通过分析trinity和syzkaller工具,强调了内核边界代码的复杂性和挑战。讨论了memset()的实现及其对CPU状态的影响,特别是方向标志位DF。文章还探讨了进入内核的不同方式和fuzzer的设计策略,包括关注特殊案例、压缩无关紧要的值。最后,提到了动态生成x86机器代码和系统调用的实现,以及如何通过汇编代码进行系统调用的实践。
摘要由CSDN通过智能技术生成

在本系列文章中,我们将为读者分享关于内核代码模糊测试方面的见解。

简介

对于长期关注Linux内核开发或系统调用模糊测试的读者来说,很可能早就对trinity(地址:https://lwn.net/Articles/536173/)和syzkaller(地址:https://lwn.net/Articles/677764/)并不陌生了。近年来,安全研究人员已经利用这两个工具发现了许多内核漏洞。实际上,它们的工作原理非常简单:向内核随机抛出一些系统调用,以期某些调用会导致内核崩溃,或触发内核代码中可检测的漏洞(例如缓冲区溢出漏洞)。

尽管这些Fuzzer能够对系统调用自身(以及通过系统调用可访问的代码)进行有效的模糊测试但是,对于在用户空间和内核之间的边界上发生的事情,这两款工具却鞭长莫及。实际上,这个边界处发生的事情比我们想象的更为复杂这里的代码是用汇编语言编写的,在内核可以安全地开始执行其C代码之前,必须对各种体系结构状态(CPU状态)进行安全检查,或者说是“消毒”。

本文将同读者一起,探索如何为x86平台上的Linux内核入口代码编写Fuzzer工具。

Linux内核(x86)入口代码模糊测试指南Part 1

在继续之前,不妨先简单了解一下64位内核涉及的主要两个文件

· entry_64.S64位进程的入口代码。

· entry_64_compat.S32位进程的入口代码。

总的来说,入口代码大约有1700行汇编代码(其中包括注释)所以,阅读这些代码的工作量并不算小,同时,这也只是整个内核代码中很小的一部分。

memset()示例

首先,我想给出一个从用户空间进入内核时,内核需要进行验证的CPU状态的具体例子。

在x86平台上,memset()通常是由rep stos指令实现的,因为在连续的字节范围内进行写操作方面,奇热该指令已经被CPU/微码进行了高度的优化。从概念上讲,这是一个硬件循环,它重复(rep)一个存储操作(stos)若干次;目标地址由%RDI寄存器指定,迭代次数由%RCX寄存器给出。例如,您可以使用内联汇编实现memset(),具体如下所示

static inline void memset(void *dest, int value, size_t count)
{
    asm volatile ("rep stosb"       // 4
        : "+D" (dest), "+c" (count) // 1, 2
        : "a" (value)               // 3
        : "cc", "memory");          // 5
}

对于上述内联汇编代码来说,其作用就是告诉GCC&

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值