Fil-C는 포인터 기반 메모리 안전성을 C/C++ 언어에서 구현하는 새로운 방식인 InvisiCaps를 소개함
동적 포인터 역량 모델(Dynamic Pointer Capability Model)을 통해 메모리 접근 제어 및 안전성 보장
이전 모델(PLUT, SideCaps, MonoCaps)의 성능 및 호환성 문제를 개선하여 실용성 증대
64비트 시스템에서 64비트 포인터 크기를 유지하며 메모리 안전성을 달성하는 것이 핵심
InvisiCaps는 각 포인터가 접근 가능한 메모리 객체를 동적으로 추적하는 포인터 역량 시스템(Pointer Capability System)을 기반으로 합니다. 이를 통해 객체 범위를 벗어난 접근, 해제된 객체 접근, 읽기 전용 데이터 쓰기 등을 동적으로 금지하여 메모리 안전성을 확보합니다. 특히, 프로그램이 보는 포인터는 실제로는 정수 값(intval)과 하위 경계(lower bound)로 구성되며, 런타임은 이 하위 경계를 신뢰하여 접근을 제어합니다.
PLUT(256비트 포인터, 제한된 유니온 지원)와 SideCaps(느린 성능, 유니온 미지원)는 호환성 및 성능 문제가 있었습니다. MonoCaps는 타입 추론을 개선했지만, 여전히 GC가 필요하고 포인터 크기가 컸습니다. InvisiCaps는 64비트 포인터 크기를 유지하면서도 성능 오버헤드를 4배 수준으로 줄였고, 유니온 사용을 지원하며 스레드 안전성을 보장합니다. 이는 이전 모델들의 주요 단점을 해결한 것입니다.
InvisiCaps의 핵심은 프로그램이 포인터의 메타데이터(Metadata)를 직접 조작할 수 없다는 점입니다. 포인터의 역량 정보는 프로그램 주소 공간 외부의 보조 단어(Aux Word)에 저장되며, 이는 데이터 격리 아키텍처(Data Isolation Architecture)를 통해 프로그램이 접근할 수 없습니다. 공격자가 포인터 역량을 조작하려 해도, 이는 곧 메모리 접근 위반으로 감지되어 프로그램이 패닉(Panic) 상태에 빠지게 됩니다.
InvisiCaps는 함수 포인터와 같은 특수 객체에 대한 접근도 안전하게 처리합니다. 함수 포인터의 경우, 실제 진입점을 가리키는 `intval`과 데이터 접근을 금지하는 함수 역량(Function Capability)을 분리합니다. 또한, 스레드나 `jmp_buf`와 같은 런타임 내부 객체에 대한 접근도 보조 단어(Aux Word)의 플래그를 통해 엄격히 제어하여, 이러한 특수 객체에 대한 데이터 접근을 원천적으로 차단합니다.
Lobsters 커뮤니티에서는 InvisiCaps가 메모리 인접성(Memory Locality)을 활용하여 역량을 저장하므로 공격자가 이를 변조할 수 있다는 우려가 제기되었습니다. 그러나 글쓴이는 이러한 시도 자체가 경계 검사(Bounds Checking)에 의해 감지되어 프로그램이 충돌(Crash)하므로 안전하다고 설명합니다. 이는 C 표준에서 정의되지 않은 동작(Undefined Behavior)까지 지원하려는 Fil-C의 팬적인 호환성(Fanatical Compatibility) 목표와 일맥상통합니다.