先梳理一下syzkaller的工作方式,这样便于理解为什么syzkaller的搭建这么复杂:
一般测试的Linux内核都需要运行在虚拟机上进行测试,应该很少直接用实体机上测试,因此需要qemu
来支持硬件虚拟机。其次,Linux内核只有核是没办法运行的,还需要发行版外环境的支持,所以我们还需要使用debootstrap
来生成一个小型的Linux发行版用于测试。
因此syzkaller的使用其实主要需要两个东西,一个是要测试的Linux内核,一个是小型发行版以便运行内核。也因此,syzkaller环境的搭建实际上也是为了满足以上这两个内容:
my.cfg
文件(用于指定内核和发行版)VMware Ubuntu16.04
sudo apt-get install gcc g++ m4 make libncurses5-dev libssl-dev texinfo build-essential openssl zlibc minizip libidn11-dev libidn11 flex bison git debootstrap qemu-system-x86 libelf-dev
在/home/lyg
下创建一个工作目录(lyg是用户名,请根据自己的系统进行修改),以便完成各种最新软件的编译:
mkdir workspace
cd workspace
mkdir bin fuzz source
sudo vim ~/.bashrc
添加:
export GOPATH=/home/lyg/workspace/fuzz/syzkaller
export GOROOT=/home/lyg/workspace/bin/go
export PATH=$GOPATH/bin:$PATH
export PATH=$GOROOT/bin:$PATH
export GCC=/home/lyg/workspace/bin/gcc8.1.0
source ~/.bashrc
具体软件包括:gmp-6.1.0、mpfr-3.1.4、mpc-1.0.3、gcc8.1.0,下载至workspace
目录下并在该目录下解压。
在workspace
目录下创建tmp
文件夹,进入该目录进行如下操作,并在每个操作结束后删除tmp
文件夹下的所有文件。(命令中的路径信息根据自己的情况进行修改)
../gmp-6.1.0/configure --prefix=/home/lyg/workspace/bin/gmp6.1.0
make -j4
sudo make install
rm –r *
../mpfr-3.1.4/configure --prefix=/home/lyg/workspace/bin/mpfr3.1.4 --with-gmp=/home/lyg/workspace/bin/gmp6.1.0
make -j4
sudo make install
rm –r *
../mpc-1.0.3/configure --prefix=/home/lyg/workspace/bin/mpc1.0.3 --with-gmp=/home/lyg/workspace/bin/gmp6.1.0 --with-mpfr=/home/lyg/workspace/bin/mpfr3.1.4
make -j4
sudo make install
rm –r *
#可能在/usr/lib/x86_64-linux-gnu/中找不到 libmpfr.so.4,所以这里要建立一个符号链接;已存在就忽略
sudo ln -s /home/lyg/workspace/bin/mpfr3.1.4/lib/libmpfr.so.4 /usr/lib/x86_64-linuxgnu/libmpfr.so.4
对gcc的编译过程可能会非常久(笔者是大约1h):
../gcc-8.1.0/configure --prefix=/home/lyg/workspace/bin/gcc8.1.0 --enable-threads=posix --disable-checking --disable-multilib --enable-languages=c,c++ --with-gmp=/home/lyg/workspace/bin/gmp6.1.0 --with-mpfr=/home/lyg/workspace/bin/mpfr3.1.4 --with-mpc=/home/lyg/workspace/bin/mpc1.0.3
make -j4
sudo make install
rm –r *
sudo ln -s /home/lyg/workspace/bin/gcc8.1.0/bin/gcc /usr/local/bin/gcc8
sudo ln -s /home/lyg/workspace/bin/gcc8.1.0/bin/g++ /usr/local/bin/g++8
将内核文件下载至workspace/source
目录下并解压,然后进入内核根目录执行如下命令:
make CC="$GCC/bin/gcc" defconfig
make CC="$GCC/bin/gcc" kvmconfig # 这条命令可能会报ERROR,可以忽略
接下来编辑.config
文件,对该文件中如下的行进行编辑。(注意:以下这些命令应该是以注释如“CONFIG_KCOV is not set”形式存在的,因此需要将该注释转换即可。部分不存在的需要手动添加,但注意不要添加在末尾,应添加在中间。)
CONFIG_KCOV=y
CONFIG_DEBUG_INFO=y
CONFIG_KASAN=y #这个默认配置中可能没有,需要添加
CONFIG_KASAN_INLINE=y #这个默认配置中可能没有,需要添加
CONFIG_CONFIGFS_FS=y
CONFIG_SECURITYFS=y
接着执行如下命令:(编译过程较久,30mins)
make CC="$GCC/bin/gcc" olddefconfig
make CC="$GCC/bin/gcc" -j8
编译结束后会产生镜像如下:
linux-5.10.9/vmlinux
linux-5.10.9/arch/x86/boot/bzImage
在source
目录下创建文件夹image
,进入该目录下载文件create-image.sh
(需要外网),当然也可以直接去GitHub找到syzkaller的仓库,然后在tools文件夹下找到该文件复制出来。
wget https://raw.githubusercontent.com/google/syzkaller/master/tools/create-image.sh
赋予其执行权:
chmod 777 create-image.sh
由于该脚本中调用的debootstrap
会访问debian的官网镜像,但是由于网络原因(开梯子也不行),导致下载速度过慢且易产生错误,因此需要对该文件进行更改,将镜像路径替换为清华镜像。如下图中笔者添加了下面黄色框所在行的内容,用来指定镜像路径。(由于环境问题,可能也进入绿色框中执行,因此必要时需要对绿色框中内容也进行替换并删除黄色框这一行内容。由于笔者的环境不会经过绿色框,因此不做修改。)
修改完后运行该脚本:
./create-image.sh
运行结果如下:
运行结束后会在该目录下生成文件stretch.img
。
首先检测系统是否支持虚拟化,使用命令如下:
egrep -c '(vmx|svm)' /proc/cpuinfo
如果得到的回复值大于0,则表明虚拟化支持已开启;否则如果是真实主机需要重启并进入BIOS开启VT虚拟化,如果是VMware则需要勾选虚拟化支持如下:
当支持虚拟化后使用如下命令进行测试:
sudo qemu-system-x86_64 \
-kernel /home/lyg/workspace/source/linux-5.10.9/arch/x86/boot/bzImage \
-append "console=ttyS0 root=/dev/sda debug earlyprintk=serial slub_debug=QUZ"\
-hda /home/lyg/workspace/source/image/stretch.img \
-net user,hostfwd=tcp::10021-:22 -net nic \
-enable-kvm \
-nographic \
-m 2G \
-smp 2 \
-pidfile vm.pid \
2>&1 | tee vm.log
进入登录界面即为成功(使用root用户不需要密码即可登录)。
syzkaller是用go语言完成的,因此其安装和执行需要go环境支持。去go官网下载go然后将该压缩包解压至~/.bashrc
中声明的GOROOT
目录中,即目录/home/lyg/workspace/bin
中即可。GOPATH
指明了go的默认工作目录。
从GitHub上下载syzkaller压缩包,放入/home/lyg/workspace/fuzz/syzkaller/src/github.com/google
目录下并解压。进入解压后文件夹执行git防止出错(已有git的忽略):
git init
git config user.name "lyg" #名称随意
git config user.email "[email protected]" #邮箱随意
git add *
git commit -m "some init msg"
此时可能git会报一个错说“由于.gitignore
文件的存在bin会被忽略”,这个错误不用处理。
接着在该目录下执行make
完成syzkaller的编译。此处调用了go,而由于网络原因可能下载速度较慢,提高下载速度的方法在这里。
编译结束后在该文件夹下创建文件my.cfg
(注意更改目录),如下:
{
"target": "linux/amd64",
"http": "127.0.0.1:56741",
"workdir": "/home/lyg/workspace/fuzz/syzkaller/src/github.com/google/syzkaller-master/workdir",
"kernel_obj": "/home/lyg/workspace/source/linux-5.10.9",
"image": "/home/lyg/workspace/source/image/stretch.img",
"sshkey": "/home/lyg/workspace/source/image/stretch.id_rsa",
"syzkaller": "/home/lyg/workspace/fuzz/syzkaller/src/github.com/google/syzkaller-master",
"procs": 8,
"type": "qemu",
"vm": {
"count": 4,
"kernel": "/home/lyg/workspace/source/linux-5.10.9/arch/x86/boot/bzImage",
"cpu": 1,
"mem": 1024
}
}
现在可以测试运行syzkaller了:
sudo ./bin/syz-manager -config=my.cfg