Linux에서 Rust: 핵심이 아닌 가장자리만 고치기

발행: (2026년 2월 5일 오후 06:15 GMT+9)
7 min read
원문: Dev.to

Source: Dev.to

Introduction

2022년, 리누스 토발즈는 리눅스 커널에 러스트 지원을 병합하기로 결정했습니다—버전 6.1이 새로운 러스트 인프라스트럭처를 포함한 첫 릴리스였습니다. 이는 C를 거부하거나 커널을 다시 쓰려는 시도가 아니라, C는 여전히 커널의 기반이라는 점을 강조합니다. 바뀐 점은 커널의 보안 위험이 주로 핵심에서 발생하는 것이 아니라, 현실적인 제약 하에 인간이 작성한 방대하고 확장되는 주변 코드에서 온다는 인식이 생겼다는 것입니다. 커널이 성장함에 따라 개발자들은 복잡하고 비동기적이며 하드웨어에 의해 구동되는 경로 전반에 걸쳐 메모리 할당과 해제를 수동으로 추적해야 했으며, 이는 경험이 풍부한 프로그래머에게도 오류가 발생하기 쉬운 작업이었습니다.

Kernel Memory Management and Garbage Collection

리눅스 커널이 메모리 관리에 가비지 컬렉터(GC)를 사용하지 않은 근본적인 이유는 결정론적 성능이 요구되기 때문입니다. 커널 환경에서는 CPU가 하드웨어 인터럽트에 응답하고 시스템 자원을 마이크로초 단위로 관리해야 합니다. GC는 메모리를 스캔하고 정리하기 위해 시스템을 일시 정지시키는 “stop‑the‑world” 이벤트를 도입하는데, 이는 허용할 수 없는 지연과 시스템 장애를 초래할 수 있습니다. 따라서 커널은 전통적으로 kmallockfree와 같은 C 함수를 이용한 수동 메모리 관리에 의존해 왔습니다.

Where Most Vulnerabilities Originate

이 핵심 메모리 관리 서브시스템이 대부분의 exploitable 버그가 발생하는 곳은 아닙니다. 페이지 할당자, slab/SLUB, 가상 메모리 레이어, 그리고 MMU 인터랙션 코드는 매우 복잡하지만, 동시에 중앙집중식이며, 철저히 감사되고 소수의 전문가 그룹에 의해 유지 관리됩니다. 수십 년에 걸친 검토 덕분에 변경이 드물고, 수정이 필요할 경우에도 신중히 접근합니다. 버그가 발생하기도 하지만, 비교적 드물고 발생 시 시스템 전반에 영향을 미칩니다.

대부분의 메모리 안전 취약점은 이 할당자를 사용하는 코드, 즉 디바이스 드라이버, 네트워킹 스택, 파일 시스템 및 기타 주변 서브시스템에서 비롯됩니다. 이 코드는 방대하고 하드웨어에 특화되어 있으며, 종종 벤더나 일시적인 기여자에 의해 작성됩니다. C에서는 컴파일러가 콜백, 인터럽트 및 비동기 경로 전반에 걸친 객체 수명을 강제할 수 없습니다. 그 결과, use‑after‑free, double‑free, 잘못된 별칭(aliasing) 버그가 지속적으로 발생하며, 이는 과거에 심각한 커널 익스플로잇의 큰 비중을 차지했습니다.

Rust’s Approach to Memory Safety

러스트는 이러한 위험을 메모리 관리 로직을 인간의 머리에서 컴파일러로 옮김으로써 해결합니다. 고유한 소유권, 빌림(borrowing), 수명(lifetime) 시스템을 통해 러스트는 코드가 실행되기 전에 메모리가 올바르게 다루어졌는지 보장합니다. 무거운 백그라운드 프로세스를 이용해 메모리를 관리하는 런타임과 달리, 러스트는 컴파일 타임에 이 안전성을 확보하며 런타임 오버헤드가 전혀 없습니다. 이는 러스트가 C만큼 효율적으로 프리 스탠딩 커널 환경에서 동작하면서도 인간 오류의 가장 흔한 유형에 대한 수학적 보증을 제공한다는 것을 의미합니다.

Current Adoption Strategy

커널 커뮤니티는 새로운 디바이스 드라이버와 추상화 계층에 러스트를 주로 사용함으로써 외과적(surgical) 접근 방식을 취하고 있습니다. 프로세스 스케줄러와 메모리 관리 유닛과 같은 핵심 서브시스템은 그 복잡성과 수십 년에 걸친 최적화 때문에 여전히 C로 유지됩니다. 이 하이브리드 모델은 수백만 줄에 달하는 기존의 기능적인 C 코드를 전부 다시 쓰는 불가능한 작업 없이도 커널이 보다 안전한 미래로 진화할 수 있게 합니다.

Back to Blog

관련 글

더 보기 »