
トップレベルのリポジトリ for LFI: 実用的で効率的で安全なソフトウェアベースのサンドボックス
Lightweight Fault Isolation (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 tools (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プログラムをビルドして実行した後、さらにいくつかの方向性を追求したいかもしれません。以下のガイドを参考にしてください:
lfi-bench を使用したベンチマークの設定: ガイド。このリポジトリは以前 zyedidia/lfi に存在し、LFIの初期実装を保持していました。そのソースは lfi-research ブランチにあります。