
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 컨텍스트 전환(즉, 샌드박스와 호스트 애플리케이션 간)은 단 10사이클 정도 소요되며, LFI는 단일 주소 공간에서 수천 개의 샌드박스를 지원할 수 있습니다: 각 샌드박스에 최대 4GiB의 메모리가 할당된 약 64K(Arm64) 또는 약 3K(x86-64)입니다.
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 브랜치에서 찾을 수 있습니다.