一种指令级Linux内核瞬时故障注入方法研究(2)
时间:2015-10-21 10:19 文章来源:http://www.lunwenbuluo.com 作者:张影,杨麦顺,张兴军 点击次数:
在LKM的支持下,故障注入模块不再受限于CPU对指令的权限检查,进而对内核空间代码及数据进行读写操作,实现故障注入。同时,LKM的动态装载性允许内核模块的灵活加载,故障注入模块可独立编译,不需要重新编译内核和重新引导,提高了开发效率。
3.3断点支持
为能将故障精确地注入Linux内核,IFIMK将使用Linux内核提供的Kprobe113接口为故障注入模块提供断点支持。Kprobe提供了一个方法可以动态进入内核,并且不会影响到内核的正常执行。应用时首先注册_个Kprobe探测点,这个探测点指定了将要注入故障的内核指令的线性地址,并在其提供的自定义处理函数pre_handler中实现故障注入操作,Kprobe将探测点的指令用断点指令cc(int3指令的机器码)代替,int3是x86处理器定义的一种陷阱类异常,处理过程与中断相似。
当内核再次执行到该探测点时,int3断点指令被执行,程序转入故障注入模块中执行,故障注入操作完成后,程序从异常中返回。
3.4故障的注入及触发
IFIMK作为一种指令级的故障注入方法,它以目标指令的地址作为切入点,涉及到目标指令及目标指令的运行环境等两方面故障的注入。对目标指令注入故障,可以监测系统对内存RAM故障引起的程序变异M做出的反馈。对运行环境注入故障,将有利于分析CPU各个寄存器故障对系统的影响。
如上所述,故障注入操作在Kprobe自定义处理函数pre_handler中实现,其格式如下:
intpre_handler(structkprobe*p,structpt_regs*regs)
其中,structkprobe*p是pre_handler函数的第1个参数;addr是structkprobe结构体的其中一项,保存了目标指令的地址。structpt_regs*regs是该函数的第2个参数,这个结构体是内核栈的部分映像,如图2所示,当程序中断转移时,此结构保存了中断时的CPU环境,包括ss,sp,flags,cs,ip,orig_ax,gs,fs,es,ds,ax,bp,di,si,dx,cx和bx等17项内容,完整地描述了目标指令运行时CPU环境。对指令运行环境注入故障可通过对pt_regs结构体的数据进行改写实现。
在故障注入模块中,目标指令故障注入通过对指令地址对应的内存代码段进行写操作实现,运行环境故障注入通过对pt_regs结构体对应的内核栈进行写操作实现。
故障的注入通过对内存不同区域的写操作完成,故障的触发则通过异常返回机制完成,异常返回时程序通过调用IRET指令和出栈指令将内核栈中保存的寄存器值重新加载进CPU的各个寄存器中。根据ip寄存器给出的指令地址,CPU将目标指令从内存代码段读出并加载进指令寄存器中。此时的寄存器值和目标指令均是根据测试人员的需求被注入故障的数据。
3.5内核与外部的通信
为满足故障注入模块与测试人员的交互需求,比如向故障注入模块提供故障模式等输入数据,IFIMK采用/proc文件系统作为内核模块与用户程序的通信接口。在IFIMK方法中,故障模式由测试人员在用户空间给出,出于对内核数据的保护,内核空间与用户空间不能直接通信,故障模式无法传送到故障注入模块。/proc虚拟文件系统提供了一种特殊的通信机制,通过将故障模式读写函数重新映射到内存读写控制函数上,建立了一条故障注入模块与用户程序之间的数据通道,从而允许故障注入模块接收来自测试人员的故障注入命令。
4实验及结果分析
4.1实验关键步骤描述
IFIMK程序执行流程如图3所示。
具体步骤如下:
(1)IFIMK方法通过查询内核符号表System.map获取目标函数的首地址,通过Linux反汇编命图2内核堆栈与structpt_regs的映射令objdump查询目标指令相对于函数首地址的移量,偏移量和首地址之和即为所求目标指令的地址。
(2)给定目标指令的地址、故障位置及故障类型生成故障模式,通过/proc虚拟文件系统传入故障注入内核模块。
(3)根据传入的故障模式,将探测点加入到目标指令所在的地址,当程序再次执行到目标指令时,故障注入操作将被触发。下面是Kprobe探测点注册的核心代码,根据用户空间传来的故障模式fau_model初始化_个structkprobe类型变量kp,通过register_kprobe函数实现探测点注册。
staticintinit_kprobe(void)
{char*name=fau_model.symbolname;kprobe_opcode_t*modaddr=fau_model.offset+(kprobe_opcode_t*)fau_model.symboladdr;
kp.addr=(kprobe_opcode_t*)(fau_model.symboladdr);
kp.offset=fau_model.offset;kp.pre_handler=handler_pre;kp.post_handler=handler_post;register_kprobe(&kp);return0;}
在pt_regs结构体中,ip项为即将执行的指令地址,Kprobe会在接下来的单步执行的准备工作中重新给ip项赋值,使它指向目标指令。同样Kprobe通过重新向flags赋值,为目标指令开启单步运行模式,使目标指令运行完后重新回到故障注入模块。当程序从int3返回,内核找内容向寄存器恢复时,orig_ax项会被跳过,不会返回到寄存器中。所以IFIMK将不对ip,flags和orig_ax三项内容注入故障。
(4)再次执行到目标指令地址时,int3断点触发,故障注入操作被执行,目标指令故障注入通过对指令的写操作实现,运行环境故障注入通过对pt_regs结构体的写操作实现。
(5)接下来执行目标指令,故障被触发。
4.2实验过程
本文实验以UbuntulO.04发行版,Linux2.6.32内核版本为目标系统,进行故障注入实验。一方面验证IFIMK方法的可行性,一方面根据实验结果分析故障类型对系统的失效率的影响。
实验共设计了6种故障类型,如表1所示。分别有末位置〇、末位置1、末位翻转、全置〇、全置1、置随机数等,来模拟单粒子翻转(SEU)、多比特翻转(MBU)对系统运行的影响。
为了提高系统测试的效率,使故障快速出现,IFIMK针对常用的系统调用测试,有do_fork,do_execve,do_exit,do_time,do_signal等。这样,测试人员可有针对性的对特定系统调用进行调用,以使故障尽快被触发,减少其潜伏时间。实验证明,这种方法是可行且高效的。
对目标指令的选择,也尽可能全面,有条件转移指令je,无条件转移指令call,栈操作指令push,数据传送指令mov,逻辑运算指令xor等。
- 论文部落提供核心期刊、国家级期刊、省级期刊、SCI期刊和EI期刊等咨询服务。
- 论文部落拥有一支经验丰富、高端专业的编辑团队,可帮助您指导各领域学术文章,您只需提出详细的论文写作要求和相关资料。
-
- 论文投稿客服QQ:
2863358778、
2316118108
-
- 论文投稿电话:15380085870
-
- 论文投稿邮箱:lunwenbuluo@126.com