CHERIoT이 MMU 없이 강력하고 사용하기 쉬운 격리를 제공하는 방식
요약
CHERIoT RTOS는 CHERI 시스템을 기반으로 하며, 기존 모놀리식 커널의 개념을 벗어나 '상호 불신'을 바탕으로 설계되었습니다. 이 아키텍처는 캐퍼빌리티(Capability)를 활용하여 각 하위 시스템 간에 봉인된 포인터(Sealed Pointer)를 전달함으로써 강력한 격리와 타입 안전성을 제공합니다. 이를 통해 전역 상태나 연결 테이블 없이도 완전한 실행 흐름 사이의 격리가 가능해집니다.
핵심 포인트
- CHERIoT는 '상호 불신' 기반으로 설계되어 전통적인 커널 개념이 없습니다.
- 캐퍼빌리티를 이용해 봉인된 포인터를 전달, 강력하고 타입 안전한 격리를 구현합니다.
- 각 하위 시스템은 호출자의 할당량 내에서만 메모리를 확보하여 자원 관리가 용이합니다.
- TLS 구획 등은 전역 상태 없이 개별 세션에만 접근 가능하여 보안성이 높습니다.
CHERIoT RTOS의 설계 선택을 다시 글로 다루고 있음. 이번에는 모든 CHERI 시스템에 권장하는 설계와, 자원이 극도로 제한된 시스템에만 적합해서 RAM이 몇 MiB보다 넉넉하다면 쓰지 말아야 할 설계를 구분해 보려 함.
질문이 있으면 여기서 답변하겠음!
캐퍼빌리티 하드웨어 지원 없이 이런 추상화를 사용하는 OS를 만드는 것도 의미가 있을까? 예를 들어 애플리케이션 개발자가 이 개념에 익숙해지는 플랫폼으로 쓸 수 있을까?
CHERI용 범용 OS를 만들 계획도 있을까?
CHERIoT에서는 소켓 상태를 가리키는 봉인된 캐퍼빌리티, 즉 불투명 포인터를 구획 간에 전달하고, TLS 계층에서는 이를 세션 상태 구조체에 담아 다시 봉인된 포인터로 반환한다고 하는데, 왜 유용한지 완전히 이해하지 못했음.
커널 공간의 포인터를 사용자 공간에 넘긴 뒤, 사용자 공간이 그 포인터로 다시 호출하면 유효한 포인터라고 바로 신뢰할 수 있다는 뜻일까? 그렇다면 write 시스템 호출 구현을 사실상 *io_sealed_ptr = *user_data; 같은 단순 복사로 줄일 수 있을까?
덧붙이자면, 그런 취지인 것 같고 적어도 블로킹 방식이라면 write가 시스템 호출일 필요조차 없어 보임.
CHERIoT는 계층적 불신이 아니라 상호 불신을 바탕으로 설계돼서, 사실상 ‘커널 공간’이라는 개념이 없음. 쓰기 호출의 첫 번째 포인터도 메모리를 복사해 넣을 목적지가 아니라, 장치나 파일시스템 등에 대한 입출력 수행 방식을 정의하는 자료구조의 핸들임.
모놀리식 커널에서는 사용자 공간이 준 핸들로 실제 상태 포인터를 찾는 테이블이 필요함. 그 구조체와 거기서 도달할 수 있는 자료구조가 쓰는 메모리를 누구에게 귀속할지 추적하는 자원 사용량 관리도 필요함. 파일 디스크립터를 다른 프로세스에 전달하려면 UNIX 도메인 소켓 등을 통한 시스템 호출로 상대 프로세스의 테이블에도 항목을 추가해야 함.
CHERIoT에서는 관련 하위 시스템에 자신의 할당 캐퍼빌리티를 직접 전달하면 됨. 하위 시스템은 호출자의 할당량에서 메모리를 확보하고 봉인된 포인터를 반환함. 자원 사용량 관리는 할당기가 일괄 처리하므로 별도로 구현할 필요가 없고, 여러 입출력 종류를 통합하는 추상화가 필요하면 자기 구획 안에 둘 수 있음.
쓰기 같은 작업에서는 구획이 직접 공개한 함수의 첫 번째 인자로 봉인된 포인터를 전달함. 가벼운 봉인 해제 연산으로 변조를 감지하거나 처음 만든 자료구조의 포인터를 복원할 수 있고, 전역 동기화 없이 그 구조에 바로 접근 가능함.
핵심은 이 추상화를 조합할 수 있다는 것임. TCP/IP 구획은 소켓 상태를 이런 방식으로 공개하고, TLS 구획은 호출자 대신 소켓을 만들어 자체 구조체에 담은 뒤 불투명하고 타입 안전한 포인터만 반환할 수 있음. 그러면 호출자는 원시 소켓에 접근할 수 없으므로, 해당 구획에서 암호화되지 않은 데이터가 나갈 경로가 없다는 보장을 감사로 검증할 수 있음.
TLS 구획 내부에는 전역 가변 상태나 연결 조회 테이블이 없음. 호출자가 TLS 연결의 봉인된 포인터를 전달하면 TLS 구획은 이를 해제해 그 호출자의 연결 상태에만 접근함. 다른 호출자의 스레드가 동시에 들어와도 각자 자기 세션 상태만 볼 수 있으므로, 다른 호출자가 버그를 악용해 임의 코드 실행 권한을 얻더라도 내 데이터에는 접근할 수 없음. 이로써 실행 흐름 사이의 완전한 격리가 가능해짐.
이런 방식은 신뢰 경계의 API 설계를 근본적으로 바꾸고, 일반적인 라이브러리 경계와 훨씬 비슷하게 만들어 줌.
AI 자동 생성 콘텐츠
본 콘텐츠는 GeekNews의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기