러스트(Rust) 언어의 핵심 안전성 보장 메커니즘인 빌림 검사기(borrow checker)에서 11년 동안 숨겨져 있던 심각한 건전성(soundness) 버그가 최근 발견되었습니다. 이 버그는 공변적 필드 대입(covariant field assignment)을 통해 구조체의 수명 제약을 우회하며, 컴파일러가 오류로 처리해야 할 코드를 정상적으로 컴파일하는 문제를 일으킵니다. 결과적으로 프로그램이 이미 해제된 메모리에 접근하거나, 짧은 수명의 지역 변수 참조를 프로그램 전체 수명('static)을 가진 참조로 잘못 취급하는 등 예측 불가능한 동작을 유발할 수 있습니다.
최초 재현 코드는 `struct Q<T: 'static + Send>(Option<T>)`를 정의하고, 지역 `String`의 참조를 `q.0 = Some(&l)` 형태로 대입한 뒤, `Drop` 구현에서 이 참조를 전역 저장소에 옮겨 'static 참조로 사용하려 할 때 발생했습니다. 이 코드는 컴파일되어 실행 시 `AddressSanitizer`에서 `stack-use-after-scope` 오류를 일으키며 종료됩니다. 이후 추가적인 재현을 통해 이 버그가 'static 제약뿐만 아니라 일반적인 수명 관계나 소멸자(destructor)에서 클로저(closure)를 호출하는 코드에서도 해제된 메모리 접근을 유발할 수 있음이 확인되었습니다. 이 문제는 러스트 1.4 버전(2015년)부터 존재해 왔으며, 최신 1.85.0 버전까지 영향을 미치는 것으로 파악되었습니다.
이번 버그 발견은 러스트의 핵심 가치인 메모리 안전성 보장에 대한 신뢰도에 영향을 미칠 수 있다는 점에서 중요합니다. 러스트는 C/C++와 같은 저수준 언어에서 흔히 발생하는 메모리 관련 오류를 컴파일 시점에 방지하는 것을 목표로 하지만, 이번 버그는 이러한 안전성 보장이 특정 조건에서 깨질 수 있음을 보여줍니다. 현재 이 이슈는 최고 우선순위인 P-high로 지정되어 러스트 개발팀이 해결에 집중하고 있으며, 이는 러스트 생태계 전반의 안정성을 확보하는 데 필수적인 과제입니다. 이번 사례는 복잡한 타입 시스템을 가진 언어에서 예상치 못한 상호작용으로 인해 오랜 기간 잠재된 버그가 발생할 수 있음을 다시 한번 상기시켜 줍니다.