요즘 갑자기 읽어야하는 논문들이 SFI 관련이어서, 베이스 지식을 좀 다지려고 따로 정리한다. (3일만에 논문 4개는 너무해요) https://www.cse.psu.edu/~gxt29/papers/sfi-final.pdf <- 이 문서를 참고하여 정리하였다.
Introduction
컴퓨터 시스템을 보호하기 위해서는 여러개의 'protection domain'을 가져야한다.
예를 들어 Kernel mode에서는 low한 작업을 한 권한이 있지만 user mode에는 해당 권한이 없는 것처럼!
시스템의 신뢰되지 않은 요소들을(untrusted components) 혹은 신뢰가 필요한 요소들을 따로 고립하는 건 매우매우 자연스럽다.
시스템의 untrusted components를 별도의 protection domain에서 관리하여 최소한의 권한을 부여하고, priveileged protection domain과의 상호작용을 제어하는 것이 바람직하다.(Provos et al., 2003; Brumley and Song, 2004).
아래 표를 보면 이게 무슨 말인지 대충 감을 잡을 수 있을 것이다.
Virtual machine과 process는 다 알것이므로 language-based isolation을 봐보자.
languaged based isolation은 고급 언어(예:Java) 등을 기반으로 isolate하는 기법이다.
예를 들어 자바를 공부해봤다면 들어봤을 JVM(Java Virtual Machine)과 Common Language Runtime (CLR, Common Language Infrastructure (CLI) 2006)은 static/dynamic 분석을 통해 type-based isolation을 구현한다. 하지만 dynamic check로 인한 overhead가 존재할 수 있다.
Software-based Fault Isolation(SFI)는 '프로세스 내'에서 logical protection domain을 설정하기 위한 기계 코드 수준의 sw 기술이다.
메인 아이디어는 untrusted components에 대한 메모리 영역을 지정하고, 그 component의 메모리 액세스를 제한하고 전송 동작 등등을 제어하기 위해 구성 요소에 위험한 명령(?)을 instrument하는 것이다.
여기서 좋은 것은 SFI에서는 protection domain이 프로세스 내에 존재하기 때문에 context switching overhead가 낮다는 것이다.
SFI는 다양하게 구현될 수 있는데, machine-code interpreter나 machine-code rewriter, 또한 컴파일러 등에서 구현될 수 있다.
우리는 주소 공간을 Logical Fault Domains(LFD)라는 영역들로 나누게 된다. 그리고 LFD는 LFD 밖과 고립되어야 한다.
또한 LFD간의 communication도 생각해봐야 한다.
Basic SFI Scheme
SFI의 핵심은 'guard instruction'이다. 이건 주소가 sandbox 내에 있다는 것을 보장한다.
SFI는 ARM64에서 아래처럼 구현될 수 있다.
add xA, xB, wC, uxtw (참고로 xn은 64bit reg를 wn는 32bit reg를 의미한다. (예전에 정리해 놓은 글: [Embedded/ARM] - [ARM] ARM Register / Processor Mode)
uxtw를 붙이면 wC가 64bit로 확장된다.
여기서 xB의 하위 32bit가 0인 경우 xA에는 xC의 하위 32bit는 그대로 유지한 채, 상위 32bit는 xB의 것으로 대체한 효과를 볼 수 있다. 예를 들어 샌드박스들이 4GiB의 크기로 align되어있고 xB에 sandbox의 base 주소가 들어간다면 저 연산은 주소를 샌드박스 내에 있게끔 보장하게 되는 것이다.