CHERI가 제시하는 하드웨어 수준의 메모리 안전성
Java 백엔드 개발자에게 메모리 안전성은 GC가 대부분을 처리해주기 때문에 직접적인 고민거리가 아닐 수 있다. 그러나 서비스를 구성하는 인프라, 사이드카, 네이티브 라이브러리, 임베디드 에이전트의 상당수는 여전히 C/C++로 작성되어 있다. CHERI(Capability Hardware Enhanced RISC Instructions)는 이 영역에서 포인터 자체를 하드웨어 수준의 "캐퍼빌리티(capability)"로 재정의하여 공간적(spatial)·시간적(temporal) 메모리 안전성을 보장하는 아키텍처다. 단순한 연구 프로토타입이 아니라, Arm의 Morello 플랫폼을 통해 실제 하드웨어에서 검증된 기술이라는 점에서 주목할 필요가 있다.
CHERI에서 포인터는 단순한 주소값이 아니라, 접근 가능한 범위(bounds)와 권한(permissions)이 인코딩된 태그 달린 값이다. 이 태그는 소프트웨어가 임의로 위조하거나 확장할 수 없고, 하드웨어가 모든 메모리 접근 시점에 이를 검증한다. 덕분에 버퍼 오버플로우나 해제된 메모리 참조(use-after-free) 같은 고전적인 취약점이 실행 시점에 차단된다.
컴파트먼트 격리로 OS 경계를 대체하다
기존 보안 아키텍처에서 프로세스 간 격리는 OS의 가상 메모리와 RPC 메커니즘에 의존한다. 문제는 이 경계를 넘는 비용이 크다는 것이다. 컨텍스트 스위치, 커널 진입, 데이터 직렬화/역직렬화가 매번 발생한다. 마이크로서비스 아키텍처에서 내부 서비스 간 호출 레이턴시를 줄이기 위해 같은 프로세스 내 인메모리 호출로 합치는 결정을 해본 경험이 있다면, 이 트레이드오프를 잘 알 것이다.
CHERI는 컴파트먼트(compartment) 라는 개념으로 이 문제를 다르게 접근한다. 동일한 주소 공간 내에서도 캐퍼빌리티 권한으로 접근 범위를 제한하기 때문에, 별도 프로세스를 띄우지 않고도 모듈 간 격리를 구현할 수 있다. 전환 비용은 일반 함수 호출 수준으로 낮아지며, 어떤 컴파트먼트가 어떤 리소스에 접근할 수 있는지 정적으로 감사(audit)할 수 있어 보안 검토 측면에서도 이점이 있다.
// 기존 방식: 포인터에 경계 정보 없음
void process(char *buf, size_t len) { ... }
// CHERI 방식: 포인터 자체에 bounds가 내포됨
// 하드웨어가 범위 초과 접근 시점에 즉시 트랩 발생
void process(__capability char *buf) { ... }
CHERIoT와 대규모 코드베이스 적용 전략
CHERI의 설계 철학 중 실무적으로 중요한 지점은 점진적 도입 가능성이다. 기존 C/C++ 코드베이스를 전면 재작성하지 않아도 된다. 대부분의 코드는 컴파일러 플래그 변경만으로 CHERI 호환 바이너리로 빌드되며, 실제 메모리 안전성 위반이 발생하는 지점만 드러나는 방식으로 마이그레이션을 진행할 수 있다.
CHERIoT는 이 아키텍처를 마이크로컨트롤러 수준으로 축소한 변형이다. IoT 기기나 임베디드 환경처럼 OS 수준의 메모리 보호를 적용하기 어려운 환경에서도 동일한 격리 모델을 적용할 수 있다는 의미다. Java 기반 백엔드가 연동하는 엣지 디바이스나 펌웨어 레이어의 보안 모델을 논의할 때 참조 프레임으로 활용할 수 있다.
정리
- CHERI는 포인터를 하드웨어 캐퍼빌리티로 재정의해 C/C++ 코드의 공간적·시간적 메모리 안전성을 실행 시점에 강제한다.
- OS 수준의 프로세스 격리를 대체하는 경량 컴파트먼트 모델로, 격리 비용 없이 모듈 간 보안 경계를 구현할 수 있다.
- 대규모 코드 재작성 없이 점진적으로 도입 가능하며, CHERIoT를 통해 마이크로컨트롤러 환경까지 적용 범위가 확장된다.