GN⁺: C를 안전한 Rust로 컴파일하는 공식화된 방법
(arxiv.org)-
C를 안전한 Rust로 컴파일하기
-
Rust 언어의 인기가 급증하고 있지만, 많은 중요한 코드베이스는 여전히 C로 작성되어 있으며, 이를 수작업으로 다시 작성하는 것은 현실적이지 않음. 따라서 C를 Rust로 자동 번역하는 것이 매력적인 대안으로 떠오름.
-
기존의 여러 연구들은 Rust의 다양한 기능(예: unsafe)을 사용하여 C의 점점 더 많은 부분을 처리하는 방향으로 나아가고 있음. 그러나 자동화의 전망이 매력적이지만, unsafe에 의존하는 코드를 생성하면 Rust가 제공하는 메모리 안전성 보장이 무효화되며, 따라서 기존 코드베이스를 메모리 안전한 언어로 포팅하는 주요 이점이 사라짐.
-
우리는 다른 경로를 탐색하여 C를 안전한 Rust로 번역하는 방법을 연구함. 즉, Rust의 타입 시스템을 준수하여 메모리 안전성을 쉽게 보장하는 코드를 생성하는 것임.
-
우리의 연구는 여러 독창적인 기여를 포함함:
- C의 일부를 안전한 Rust로 타입 지향 번역
- Rust의 슬라이스와 분할 연산을 사용하여 C의 포인터 산술을 표현할 수 있는 "분할 트리" 기반의 새로운 정적 분석
- 어떤 빌림이 가변적이어야 하는지를 정확히 추론하는 분석
- Rust의 비소유 및 소유 할당 구분과 호환되는 C의 구조체 타입에 대한 컴파일 전략
-
우리는 이 방법론을 기존의 형식적으로 검증된 C 코드베이스에 적용함: HACL* 암호화 라이브러리, EverParse의 이진 파서 및 직렬화기. 지원하는 C의 부분 집합이 두 응용 프로그램을 안전한 Rust로 번역하기에 충분함을 보여줌.
-
평가 결과, Rust의 별칭 규율을 위반하는 몇몇 부분에 대해서는 자동화된 외과적 재작성으로 충분하며, 삽입된 몇몇 전략적 복사본이 성능에 미치는 영향은 미미함을 확인함.
-
특히, HACL*에 대한 접근 방식의 적용 결과, 모든 현대 알고리즘을 구현한 80,000 라인의 검증된 암호화 라이브러리가 순수 Rust로 작성됨. 이는 최초의 사례임.
Hacker News 의견
-
Rust로 프로젝트를 포팅하면서 몇 가지 결론을 얻음
- C 프로그램을 Rust로 변환하면 Rust의 엄격한 제약 덕분에 버그를 빠르게 발견할 수 있음
- C에서 Rust로의 자동 변환은 완전히 해결되지 않을 문제로, 두 언어의 설계가 근본적으로 다르기 때문임
- 일부 경우에는 C에서 Rust로의 포팅이 불가능할 수 있으며, 이는 설계 자체에 내재된 불안전성 때문임
- 도구의 발전이 포팅 과정을 더 원활하게 만들 것임
-
기존의 형식적으로 검증된 C 코드베이스와 일반적인 시스템 C 코드베이스는 다름
-
2002년에 연구자들이 Cyclone이라는 안전한 C 방언에 대한 논문을 발표했으며, C에서 Cyclone으로 코드를 포팅하면서 안전성 버그를 발견함
- 이러한 수동 또는 자동 변환은 안전한 언어의 채택을 증가시키고 기존 버그를 발견할 가능성이 있음
-
Rust로의 단순한 번역은 안전한 부분과 불안전한 부분을 생성할 수 있으며, 수동 작업은 불안전한 영역의 안전성을 검증하는 것에 집중할 수 있음
- 불안전한 부분이 크더라도 이점이 있을 수 있음
-
C의 작은 부분을 컴파일하는 접근 방식에 대한 기대가 낮음
- Rust의 소유권 모델이 실제 C 프로그램과 너무 다르기 때문임
-
Zig의 C 변환 기능과 비교에 대한 궁금증
- Zig는 새로운 코드와 기존 C 코드의 혼합 환경을 잘 생성하며, C 컴파일러로도 사용 가능함
- Linux 커널 유지보수자들이 Zig를 C의 대체로 고려하지 않는 이유에 대한 궁금증
-
C2Rust
가 형식적으로 올바른 코드를 생성할 수 있는지에 대한 질문- Rust 코드를 생성하는 소스 코드에 대한 링크가 보이지 않음
-
C 라이브러리가 작동한다면 Rust의 불안전성을 사용해 번역하는 것이 가치가 있을 수 있음
- Rust는 일반적으로 라이브러리가 부족함
-
높은 최적화 수준이 Rust의 속도를 크게 향상시키지 못한 점이 흥미로움
- O3 최적화 수준에서 C를 Rust로 한 번에 컴파일하는 것이 얼마나 잘 작동할지에 대한 궁금증