DASICS (Dynamic in-Address Space Isolation by Code Segment) secure processor implementation based on NutShell
Reproduction of Heartbleed Attack (CVE-2014-0160), for research purpose ONLY
DASICS(Dynamic in-Address-Space Isolation by Code Segments)是一种安全处理器设计方案,通过对不同代码片段访问的内存地址空间进行隔离并设置各自的访存权限,从而实现对非预期的越界访存和跳转的防护。这类越界访存可能来自于包括第三方恶意代码, 软件bug, 利用猜测执行的(如Spectre)漏洞在内的各种情况。
DASICS设计思想和具体实现请查看我们提供的DASICS白皮书
使用方式可以访问下载pdf版本的用户手册
相关学术论文和资料:
我们实现了对RISC-V架构Linux内核的修改,以支持DASICS相关安全处理机制,主要修改在如下几个仓库:
我们实现了QEMU的DASICS版本
我们在开源的RISC-V处理器NutShell上实现了DASICS的硬件原型,并成功在FPGA上启动Linux并进行简单的安全测试
我们实现了基础的DASICS测试,测试代码build目录在riscv-rootfs/apps/dasics-test,目前有四个基本的测试:
# riscv-rootfs/apps/dasics-test
test
├── dasics-test-free.c
├── dasics-test-jump.c
├── dasics-test-ofb.c
└── dasics-test-rwx.c
这个教程主要指导如何在QEMU模拟器上把我们提供的支持DASICS功能的Linux跑起来,并进行一些基础的测试。
如果不想进行下面的操作,可以直接使用我们提供的开箱即用的dasics-qemu 环境包,这里面包含了按照下面的骤准备好的各个文件,但由于可能缺少库文件会导致出错,因此我们还是建议按照下面的步骤准备相关文件.
解压后,进入dasics-qemu目录,运行如下命令:
./qemu-system-riscv64 -machine virt -bios none -kernel ~/qemu-test/dasics/bbl -m 1G -nographic -append "console=ttyS0 rw root=/dev/vda" -drive file=../img,format=raw,id=hd0 -device virtio-blk-device,drive=hd0
git clone https://github.com/DASICS-ICT/QEMU-DASICS.git
qemu-system-riscv64可执行文件cd QEMU-DASICS
./configure --target-list=riscv64-softmmu
make clean && make
qemu-system-riscv64在riscv64-softmmu目录下,接下来我们需要制作一个virtio盘,在QEMU-DASIC目录下执行下列命令:./qemu-img create -f raw img 1G
mkfs.ext4 img
sudo mount img tmp_mount/
上面最后一步是为了把 img mount到一个文件夹tmp_mnt上,然后进tmp_mnt修改就可以修改img里的内容。
到此QEMU的准备完成
首先要确认有riscv编译工具链,如果没有可以从源码制作,注意最好使用11.1.0版本的gcc,也可以使用我们在release中提供的预编译包,下面我们按照预编译包的方式进行讲解:
解压dasics-riscv-toolchain.tar.gz,在dasics-riscv-toolchain目录下有riscv64-unknown-elf和riscv64-unknown-linux-gnu两个目录
设置好RISCV变量并将工具链添加到环境变量中,假设你的dasics-riscv-toolchain工具链路径为$(DASICS_TOOL_CHAIN),运行如下命令((建议添加到~/.bashrc或者~/.zshrc中):
export RISCV=$(DASICS_TOOL_CHAIN)/riscv64-unknown-linux-gnu
export PATH=$(DASICS_TOOL_CHAIN)/riscv64-unknown-elf/bin:$PATH
export PATH=$(DASICS_TOOL_CHAIN)/riscv64-unknown-linux-gnu/bin:$PATH
riscv64-unknown-elf-和riscv64-unknown-linux-gnu-,下列命令都应该显示是11.1.0 版本的gccriscv64-unknown-linux-gnu-gcc -v
riscv64-unknown-elf-gcc -v
riscv-linux、riscv-pk、riscv-rootfs仓库clone下来git clone https://github.com/DASICS-ICT/riscv-linux.git
git clone https://github.com/DASICS-ICT/riscv-rootfs.git
git clone https://github.com/DASICS-ICT/riscv-pk.git
RISCV_ROOTFS_HOME,为riscv-rootfs的路径(建议添加到~/.bashrc或者~/.zshrc中),假设是$(PATH_TO_YOUR_RISCV_ROOTFS)
export RISCV_ROOTFS_HOME=$(PATH_TO_YOUR_RISCV_ROOTFS)
riscv-rootfs是制作内存文件系统使用的仓库,这个目录下面apps/busybox是我们需要的一些busybox基本工具,apps/dasics-test是我们dasics测试的build目录。我们在riscv-rootfs目录下运行make all
成功后,我们已经在riscv-rootfs/rootfsimg目录下创建好了内存文件系统,文件系统描述见riscv-rootfs/rootfsimg/initramfs-dasics.txt文件
接下来我们进入riscv-linux编译linux内核,需要注意的是,如果我们是在QEMU上跑linux,需要进入riscv-linux/arch/riscv/Kconfig, 在105-108行将CONFIG_ZYNQ_ONBOARD设置为n
//riscv-linux/arch/riscv/Kconfig
config ZYNQ_ONBOARD
# def_bool y
def_bool n
riscv-linux目录下运行下述命令(qemu_defconfig文件在riscv-linux/arch/riscv/configs下)make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- qemu_defconfig
riscv-pk目录下运行下述命令,成功之后在riscv-pk/build目录下得到我们的bbl文件,这个文件包含了boot loader、linux kernel以及我们制作的内存文件系统make qemu
QEMU-DASICS目录运行下述命令(假设我们上一步中得到的bbl路径为$(PATH_TO_BBL):cd riscv64-softmmu
./qemu-system-riscv64 -machine virt -bios none -kernel $(PATH_TO_BBL) -m 1G -nographic -append "console=ttyS0 rw root=/dev/vda" -drive file=../img,format=raw,id=hd0 -device virtio-blk-device,drive=hd0
/root目录下放置了4个编译好的dasics测试,/root/scripts/run-dasics-test.sh是跑所有测试的脚本,执行如下命令:sh root/scripts/run-dasics-test.sh
这个教程主要指导如何将我们修改的NutShell处理器核以及Linux惊吓放到PYNQ-Z2 FPGA板上跑起来。
同样如果不想进行下述步骤,可以使用我们release里给出的dasics-pynq包,里面包含准备好的BOOT.BIN和RV_BOOT.bin,可以直接跳转到上板步骤
安装 mill
确保python在$PATH中
在 PYNQ-Z2 页面上下载 PYNQ-Z2 Board File,并将其加入Vivado安装目录中的Vivado/2019.2/data/boards/board_files中
这一步基本和qemu中类似,因此就简述一下差别
需要和qemu一样先export RISCV变量和RISCV_ROOTFS_HOME变量
在riscv-rootfs中运行make all
查看riscv-linux/arch/riscv/Kconfig, CONFIG_ZYNQ_ONBOARD需要设置为y
在riscv-linux中运行make ARCH=riscv CROSS_COMPILE=riscv64-unknown-linux-gnu- zynq_dasics_defconfig
在riscv-pk中运行make,生成的bbl.bin 在riscv-pk/build文件夹下,将bbl.bin改名为RV_BOOT.bin
git clone https://github.com/DASICS-ICT/NutShell-DASICS.git
cd NutShell-DASICS
git checkout dev-dasics-ucas-os
make BOARD=pynq
确保vivado在$PATH中(可能需要source Vivado安装目录下的Vivado/2019.2/settings64.sh)
将fpga/board/run.tcl第2行和第6行的-jobs 20修改为合适的并发数
在NutShell-DASICS所在目录下获取 Xilinx/device-tree-xlnx 仓库,并切换到xilinx-v2019.2 tag
运行以下命令生成启动镜像:
cd fpga && make PRJ=prj BOARD=pynq STANDALONE=true bootgen
准备SD卡,对SD卡进行分区,并对SD卡第一个分区进行格式化
将BOOT.BIN和RV_BOOT.bin拷贝到SD卡的第一个分区
板卡上电之后可以看到linux启动,其余步骤和qemu测试相同