MemoryFaultInjection
#1配置安装
##1.1目录结构
|-- LICENSE
|-- README.md
|-- src ==== 源代码目录
| |-- bugs bug目录 ==== 记录程序的所有bug
| |-- engine 驱动 ==== 为应用程序和工具提供服务
| |-- injector 应用程序 ==== 故障注入工具的源码
| `-- tools 工具包 ==== 实现的外部接口命令
`-- workspace ==== 测试目录
目录
描述
Creator
Contributiors
injector
故障注入工具的上层应用
qianjun(钱军老师)
qianjun, fenggang, gatieme
engine
故障注入工具的驱动层
gatieme
gatieme
tools
故障注入的驱动接口层, 针对驱动实现的上层应用工具包
gatieme
fenggang, gatieme
##1.2构建过程
在src目录下进行make后,会依次进入
make
进入engine, injector, tools目录完成驱动, 应用程序和工具包的构建
###1.2.1构建驱动
编译驱动
进入engine目录构建驱动
目标驱动memoryEngine.ko
安装驱动程序
insmod memeoryEngine.ko
会在/proc/memoryEngine/目录目录下创建如下设备文件
ctl kFuncName memVal physicalAddr pid signal taskInfo virtualAddr
###1.2.2构建应用程序
进入injector目录下构建应用程序
应用程序memoryInject
Usage:
./memInjector -c fault.conf -e program [arguments]
./memInjector -c fault.conf -p pid
Arguments:
1. fault description scripts.
2. workload, workload can be a executable program or a running process ID.
###1.2.3构建工具包
进入tools目录下构建命令工具接口
工具集合如下
工具
描述
getpinfo
获取某个进程的信息
readpa
读取物理地址
writepa
对某个物理地址进行写操作
v2p
将逻辑地址转换为物理地址
##1.3使用说明
##1.4地址选项
参数
描述
text
进程代码段(text)
data
进程数据段(data)
stack
进程栈段(stack)
kstack
进程内核栈(kstack)
##1.5虚拟地址
参数
描述
random
随机random
其他方式未实现
##1.6故障注入类型
参数
描述
one_bit_0
一位置0
one_bit_1
一位置1
one_bit_flip
一位反转
word_0
word清0
page_0
一页清
#2编译问题
##2.1内核目录问题
编译驱动使用了uname -r来获取内核头文件的地址
如果linux系统升过级请,自动为内核头文件建立链接
sudo ln -s 2.6.32-573.18.1.el6.x86_64 2.6.32-504.el6.x86_64
##2.2内核配置问题
在这里不说语法和API, 就说说在2.6.28.10内核(好像在2.6.25+的内核中就是这样了)中使用mmap()注意的事项.
###2.2.1内核配置选项
在新的内核中, 有两个选项和mmap()映射内存`/dev/mem有关
CONFIG_X86_PAT
CONFIG_STRICT_DEVMEM
内核中有这样一段话 :
CONFIG_STRICT_DEVMEM:
If this option is disabled, you allow userspace (root) access to all
of memory, including kernel and userspace memory. Accidental
access to this is obviously disastrous, but specific access can
be used by people debugging the kernel. Note that with PAT support
enabled, even in this case there are restrictions on /dev/mem
use due to the cache aliasing requirements.
If this option is switched on, the /dev/mem file only allows
userspace access to PCI space and the BIOS code and data regions.
This is sufficient for dosemu and X and all common users of /dev/mem.
只有在.config文件中设置CONFIG_STRICT_DEVMEM=n才能获得对整个memory的访问权限, 在默认情况下, CONFIG_STRICT_DEVMEM=y, 这也就是之前mmap总是报错 : Operation not permitted的原因.
设置这个选项后, 编译kernel, 然后运行mmap的实例程序, mmap还是返回错误 : Invalid argument. 后来查到还需要设置编译选项CONFIG_X86_PAT=n, 这个选项也是默认开启的, 但是要关闭这个选项还需要开启CONFIG_EXPERT, 否则CONFIG_X86_PAT总是关不掉.
设置好这三个编译选项后, 重新编译kernel, 然后运行tool, 发现kernel已经解除了对mmap的访问限制, 可以正确读取对应物理地址的内容了.
最后还可以通过修改内核源代码来实现,具体的源文件时在/drivers/char/目录下的mem.c文件
static inline int range_is_allowed(unsigned long pfn, unsigned long size);
所以,如果要使用mmap映射/dev/mem文件的话, 必须将这两个量取消.
如果不取消CONFIG_STRICT_DEVMEM, 则/dev/mem不允许映射;
如果不取消CONFIG_X86_PAT, 则内核空间不能映射, 调用mmap的时候会出现Invalid Parameter错误
##2.2.2检查内核选项
可以使用如下命令检查内核中对于这两个参数选项的配置
cat /usr/src/linux-headers-uname -r/.config | grep -E "CONFIG_STRICT_DEVMEM|CONFIG_X86_PAT"
##2.2.3内核设置问题
在.config文件中设置:
CONFIG_X86_PAT=n
CONFIG_STRICT_DEVMEM=n
或者在以下路径中设置取消两个选项 :
CONFIG_X86_PAT的位置在 :
Processor type and features —>
[ ] x86 PAT support
CONFIG_STRICT_DEVMEM的位置在 :
Kernel hacking —>
[ ] Filter access to /dev/mem
#3BUG描述
##3.1bug-001
编号 : bug-001
描述 : 地址空间修改失败
详细信息
执行sudo ./memInjector -l stack -m random -t word_0 -p 1
将进程1的栈区域某块地址随机清0的时候失败
问题定位
未知
##3.2bug-002
编号 : bug-001
描述 : -e指定加载可执行程序时, execv传入参数的问题
详细信息
执行sudo ./memInjector -l stack -m random -t word_0 -e ls -al
执行运行"ls -al"程序,对该程序栈区域某块地址随机清0的时候execv失败
问题定位:
系统执行"ls -al"的方式是通过fork子进程, 然后execv来执行的
但是execv接收两个参数, 1--可执行程序路径, 2--可执行程序的参数
我们的问题就在于第2个参数传入的程序运行参数有问题
##3.3bug-003
编号:bug-003
描述:SIGSEG
详细信息:
workspace/hello
sudo ./memInjector -l stack -m random -t word_0 -p `pidof hello`
出现SIGSEGV