memory-safety

2 개의 포스트

대규모 환경의 Rust (새 탭에서 열림)

WhatsApp은 최근 30억 명 이상의 사용자들을 멀웨어 위협으로부터 보호하기 위해 미디어 처리 라이브러리를 Rust 언어로 재구축하여 성공적으로 배포했습니다. 이는 글로벌 규모의 서비스에서 Rust가 프로덕션 환경에 적합함을 증명한 사례로, 특히 메모리 안전성이 취약한 C/C++ 기반의 미디어 파싱 라이브러리에서 발생할 수 있는 보안 취약점을 근본적으로 해결하는 데 중점을 두었습니다. 결과적으로 WhatsApp은 성능과 메모리 효율성을 동시에 개선하면서도 사용자 보안을 한층 더 강화하는 성과를 거두었습니다. **미디어 보안의 취약점과 대응의 역사** - 이미지나 영상처럼 무해해 보이는 파일도 운영체제의 취약점을 공격하는 악성 코드를 포함할 수 있으며, 2015년 안드로이드의 'Stagefright' 취약점이 대표적인 사례입니다. - 당시 WhatsApp은 OS 라이브러리의 패치를 기다리는 대신, 자체 개발한 C++ 기반의 미디어 일관성 검사 라이브러리인 'wamedia'를 통해 표준을 준수하지 않는 파일을 사전에 차단하는 방식을 택했습니다. - 하지만 미디어 체크 로직 자체가 신뢰할 수 없는 입력을 자동으로 처리하기 때문에, 이 라이브러리 자체의 메모리 안전성을 확보하는 것이 보안의 핵심 과제로 떠올랐습니다. **Rust를 통한 대규모 현대화 및 성능 개선** - WhatsApp은 점진적인 수정 대신 기존 C++ 버전과 병행하여 Rust 버전의 라이브러리를 새롭게 개발했습니다. - 두 언어 간의 호환성을 보장하기 위해 '디퍼런셜 퍼징(Differential Fuzzing)'과 광범위한 통합 테스트를 거쳐 안전성을 검증했습니다. - 기존 160,000줄의 C++ 코드를 90,000줄의 Rust 코드로 대체했으며, 결과적으로 이전보다 더 우수한 성능과 낮은 런타임 메모리 사용량을 기록했습니다. - 안드로이드, iOS, 웹, 웨어러블 등 다양한 플랫폼 지원을 위한 빌드 시스템 구축과 바이너리 크기 최적화라는 기술적 난관을 극복하고 글로벌 배포를 완료했습니다. **다층 방어 체계 'Kaleidoscope'의 구축** - Rust로 작성된 이 라이브러리들은 'Kaleidoscope'라 불리는 종합 보안 체크 시스템의 핵심 구성 요소입니다. - 단순히 파일 구조의 결함을 찾는 것을 넘어, PDF 내의 스크립트 요소나 임베디드 파일, 확장자를 위조한 MIME 타입 변조 등을 감지합니다. - 실행 파일이나 앱 설치 파일과 같은 위험한 파일 형식을 식별하여 사용자 인터페이스(UX) 차원에서 특별 관리함으로써 비공식 클라이언트나 악성 첨부파일로부터 사용자를 보호합니다. **메모리 안전 언어 중심의 보안 로드맵** - WhatsApp의 분석에 따르면 심각도가 높은 취약점의 대부분은 C/C++의 메모리 관리 문제에서 발생하며, 이를 해결하기 위해 새로운 코드 작성 시 메모리 안전 언어(Memory Safe Language)를 기본으로 선택하고 있습니다. - 불필요한 공격 표면을 최소화하고, 기존 C/C++ 코드에 대해서는 강화된 메모리 할당자와 보안 버퍼 API를 적용하는 등 보안 보증 투자를 병행하고 있습니다. - 이번 Rust 도입의 성공을 바탕으로 향후 더 많은 영역에 Rust 채택을 가속화하여 내부 방어 체계를 지속적으로 강화할 계획입니다. **결론 및 제언** WhatsApp의 사례는 보안이 중요한 클라이언트 사이드 애플리케이션에서 Rust가 단순한 대안을 넘어 최고의 선택지가 될 수 있음을 보여줍니다. 특히 외부에서 유입되는 미가공 데이터를 파싱해야 하는 시스템이라면, 메모리 안전성이 보장되는 Rust로의 전환을 통해 보안 사고의 근본 원인을 제거하고 운영 효율성을 높이는 전략을 적극 검토할 필요가 있습니다.

Squeezing every millisecond: How we rebuilt the Datadog Lambda Extension in Rust (새 탭에서 열림)

Datadog은 기존 Go 기반의 AWS Lambda 확장이 가진 높은 오버헤드를 해결하기 위해, 이를 Rust 언어로 완전히 재작성한 'Project Bottlecap'을 진행했습니다. 이를 통해 콜드 스타트 시간을 82% 단축하고 메모리 사용량을 40% 절감했으며, 바이너리 크기를 55MB에서 7MB로 줄이는 획기적인 성능 개선을 달성했습니다. 결과적으로 리소스가 제한된 서버리스 환경에서도 사용자 애플리케이션에 영향을 주지 않고 고정밀 텔레메트리 데이터를 수집할 수 있게 되었습니다. ### 기존 범용 에이전트 기반 설계의 한계 - 초기 Datadog Lambda 확장은 다중 호스트나 클러스터 환경에 최적화된 기존 Datadog 에이전트 코드를 기반으로 구축되었습니다. - 범용 에이전트는 대규모 처리량과 캐싱, 버퍼링에 초점이 맞춰져 있어 리소스가 극도로 제한된 람다의 단기 실행 환경에는 부적합했습니다. - 종속성 제거, 바이너리 압축(UPX), 지연 로딩 등 모든 최적화 수단을 동원했음에도 불구하고 콜드 스타트 지연 시간이 450~500ms 이하로 내려가지 않는 성능 한계에 직면했습니다. - 결국 범용 도구와 서버리스 전용 도구의 스케일 차이를 인정하고, 밑바닥부터 다시 작성하는 결정을 내렸습니다. ### Lambda 환경에서 Rust 언어의 전략적 이점 - **안정성 및 메모리 안전성:** 람다 확장이 충돌하면 함수 전체가 종료되고 샌드박스가 초기화되어 다시 콜드 스타트가 발생하는데, Rust는 컴파일 타임에 메모리 안전성을 보장하여 이러한 위험을 최소화합니다. - **바이너리 경량화:** 가비지 컬렉터와 대규모 런타임이 포함된 Go와 달리, Rust는 킬로바이트 또는 낮은 메가바이트 단위의 매우 작은 바이너리를 생성하여 초기 로딩 시간을 줄입니다. - **제한된 환경의 이점:** 람다는 아마존 리눅스와 x86/Arm 아키텍처라는 고정된 환경만 고려하면 되므로, 다양한 환경을 지원해야 하는 시스템 프로그래밍에서 Rust가 가질 수 있는 복잡성 문제가 크게 완화되었습니다. ### Project Bottlecap의 핵심 설계 원칙 - **철저한 성능 오버헤드 통제:** 모든 풀 리퀘스트(PR)마다 벤치마크를 수행하여 성능 저하를 감시했으며, 성능 향상을 위해 공식 AWS SDK 사용을 포기하고 직접 AWS API 호출과 서명 로직을 작성하는 트레이드오프를 감수했습니다. - **핸들러 영향 최소화:** 람다 확장 API를 활용하여 함수 핸들러가 결과를 반환한 후에 텔레메트리를 처리함으로써, 사용자 API 응답 속도에 미치는 영향을 제거했습니다. - **다양한 플러시(Flush) 전략:** 리소스 사용량이 적은 API 함수부터 대규모 배치 작업까지 대응할 수 있도록 데이터 전송 시점을 유연하게 설정할 수 있는 구조를 갖추었습니다. 범용 소프트웨어를 특정 환경에 맞춰 최적화하는 것에는 한계가 있습니다. 특히 실행 시간과 리소스 사용량이 곧 비용과 직결되는 서버리스 환경에서는, 해당 환경의 제약 조건을 반영한 전용 도구를 구축하는 것이 초기 개발 비용이 높더라도 장기적으로 성능과 안정성 측면에서 압도적인 이점을 제공합니다.