欢迎来到轻量级故障隔离(LFI)项目的顶级仓库。
LFI 是一个用于沙箱化原生代码的系统。与 WebAssembly 和 Native Client 类似,LFI 在进程内(即与宿主应用程序相同的地址空间)隔离沙箱化代码。目前,我们支持 Arm64 和 x86-64 目标,并有实验性的 RISC-V 支持。
LFI 从底层设计用于沙箱化现有代码,例如 C/C++ 库(包括汇编代码)和设备驱动程序。
LFI 追求以下目标:
非目标包括稳定的二进制格式和平台无关性。我们将利用任何架构特定的硬件特性和编译器技术来提升性能。
LFI 当前在沙箱化读取和写入时相比原生代码引入约 7%(Arm64)或 8%(x86-64)的开销,在仅沙箱化写入时引入 1.5%(Arm64)或 6%(x86-64)的开销(SPEC 2017 几何平均值)。LFI 上下文切换(即沙箱与宿主应用程序之间)仅需数十个周期,并且 LFI 可以在单个地址空间中支持数千个沙箱:约 64K(Arm64)或约 3K(x86-64),每个沙箱最多可分配 4GiB 内存。
lfi-runtime:负责加载 LFI 程序、处理宿主调用以及运行验证的运行时。lfi-verifier:LFI 验证器。lfi-rewriter:用于 GNU 汇编的 LFI 重写器,以及在链接后执行二进制转换的后链接工具(仅在 x86-64 上需要)。lfi-bind:用于生成跳板例程和初始化例程的工具,以便在 LFI 沙箱内运行库。lfi-llvm-toolchain:用于构建基于 LLVM 的 LFI 编译器工具链的脚本,以及包含 compiler-rt、musl、libc++ 和 mimalloc 的 sysroot。llvm-project:我们为 LLVM 项目开发的分支。lfi-specification:LFI 规范文档的 LaTeX 源码。lfi-bench:用于执行 LFI 性能评估的库和基准测试集合。要开始使用 LFI,你需要一个 LFI 编译器。你可以从 https://github.com/lfi-project/lfi-llvm-toolchain 获取。预构建的 aarch64 和 x86-64 编译器托管在发布版中:https://github.com/lfi-project/lfi/releases/latest。根据你的架构下载 aarch64-lfi-clang.tar.gz 或 x86_64-lfi-clang.tar.gz 捆绑包(如果你希望从 x86-64 交叉编译到 aarch64,则下载 aarch64-lfi-clang-host-x86_64.tar.gz)。
解压归档文件后,你会看到类似以下的目录结构:
├── bin
│ ├── LLVM 工具 (clang, lld, ...)
├── include
├── lfi-bin
│ ├── lfi-postlink
│ ├── lfi-rewrite
│ ├── lfi-run
│ ├── lfi-verify
│ ├── ARCH-lfi-linux-musl-clang -> ../bin/clang
│ └── ARCH-lfi-linux-musl-clang++ -> ../bin/clang++
├── lfi-clang
│ ├── ARCH-lfi-linux-musl-clang -> ../bin/clang
│ └── ARCH-lfi-linux-musl-clang++ -> ../bin/clang++
├── lib
├── libexec
├── share
└── sysroot
你需要将 lfi-bin 目录添加到你的 PATH 中。如果你已通过单独安装安装了 LFI 工具,请考虑仅将 lfi-clang 添加到 PATH。
一旦有了编译器,你应该能够构建一个简单的 C 或 C++ 程序:
#include <stdio.h>
int main() {
printf("Hello from LFI\n");
return 0;
}
使用 lfi-run 编译并运行:
$ aarch64-lfi-linux-musl-clang hello.c -O2 -o hello -static-pie
$ lfi-run -v ./hello
Hello from LFI
你可以使用预构建存档中的预构建 lfi-run 工具。你也可以轻松地从源码构建 LFI 运行时:
git clone https://github.com/lfi-project/lfi-runtime
cd lfi-runtime
meson setup build
cd build
ninja
./tools/lfi-run/lfi-run ...
lfi-run 工具主要用于基准测试和测试。它默认不运行验证(传递 -v 以启用),并且默认允许完全的文件系统访问。有关更多信息,请参阅用法(lfi-run --help)。
在构建并运行你的第一个 LFI 程序后,你可能希望探索几个进一步的方向。请参阅以下指南以获得一些建议:
此仓库之前位于 zyedidia/lfi,并保存了 LFI 的初始实现。这些源码可以在 lfi-research 分支上找到。