꽤 인상적인 블로그가 올라왔네요.
요약하자면 안드로이드의 C/C++ 메모리 보안 취약점은 고위험 취약점의 70%을 차지하고 인적, 경제적 비용이 많이 들고 있다고 설명했습니다. 그리고 AOSP는 이제 메모리 안전 언어로 코틀린/자바외에 Rust언어를 추가한다고 공지했네요.
이하 구글 번역(+수정)
- 시스템 프로그레밍
Java 및 Kotlin과 같은 관리 언어(역주: 자동 메모리 관리 언어)는 Android 앱 개발을위한 최상의 옵션입니다. 이러한 언어는 사용 용이성, 휴대 성 및 안전을 위해 설계되었습니다. Android 런타임 (ART)은 개발자를 대신하여 메모리를 관리합니다. Android OS는 Java를 광범위하게 사용하여 Android 플랫폼의 상당 부분을 메모리 버그로부터 효과적으로 보호합니다. 불행히도 OS의 하위 계층의 경우 Java 및 Kotlin은 옵션이 아닙니다.
로우 레벨 OS에는 C, C ++ 및 Rust와 같은 시스템 프로그래밍 언어가 필요합니다. 이러한 언어는 제어 및 예측 가능성을 목표로 설계되었습니다. 저수준 시스템 리소스 및 하드웨어에 대한 액세스를 제공합니다. 리소스가 적고 예측 가능한 성능 특성이 있으며 C 및 C ++의 경우 개발자가 메모리 수명 관리를 담당합니다. 불행히도, 특히 복잡하고 다중 스레드 코드베이스에서이 작업을 수행 할 때 실수하기 쉽습니다.
Rust는 메모리 액세스가 유효한지 확인하고 객체 수명 / 소유권 및 런타임 검사를 시행하기 위해 컴파일 시간 검사의 조합을 사용하여 메모리 안전 보장을 제공합니다. 이러한 안전성은 C 및 C ++와 동등한 성능을 제공하면서 달성됩니다.
- 샌드박스의 한계
C 및 C ++ 언어는 이와 동일한 안전 보장을 제공하지 않으며 강력한 격리가 필요합니다. 모든 Android 프로세스는 샌드 박스 처리되며, 기능에 추가 격리 및 박탈이 필요한지 여부를 결정하기 위해 규칙 2를 따릅니다. 2의 규칙은 간단합니다. 세 가지 옵션이 주어지면 개발자는 다음 세 가지 옵션 중 두 가지만 선택할 수 있습니다.
Android의 경우 이는 코드가 C / C ++로 작성되고 신뢰할 수없는 입력을 파싱하는 경우 엄격하게 제한되고 권한이없는 샌드박스 내에 포함되어야 함을 의미합니다. Rule of 2를 준수하면 보안 취약성의 심각도와 악용 가능성을 줄이는 데 효과적이지만 제한이 있습니다. 샌드 박싱은 비용이 많이 듭니다. 필요한 새 프로세스는 추가 오버 헤드를 소비하고 IPC 및 추가 메모리 사용으로 인해 대기 시간을 발생시킵니다. 샌드 박싱은 코드에서 취약점을 제거하지 않으며 높은 버그 밀도로 인해 효율성이 감소하여 공격자가 여러 취약점을 함께 연결할 수 있습니다. Rust와 같은 메모리 안전 언어는 두 가지 방법으로 이러한 한계를 극복하는 데 도움이됩니다.
1)코드 내의 버그 밀도를 낮추어 현재 샌드 박싱의 효율성을 높입니다.
2)샌드 박싱 요구 사항을 줄여 리소스에 대해 더 안전하고 가벼운 새로운 기능을 도입 할 수 있습니다.
-중략-
- 예방 우선
Rust는 다양한 다른 언어 특징을 현대화하여 코드의 정확성을 향상시킵니다.
1.메모리 안전성- 컴파일러와 런타임 검사의 조합을 통해 메모리 안전성을 강화합니다.
2. 데이터 동시성- 데이터 경합을 방지합니다. 이를 통해 사용자가 효율적이고 스레드로부터 안전한 코드를 쉽게 작성할 수있게되면서 Rust의 Fearless Concurrency(두려움 없는 동시성) 슬로건에 부합합니다.
3. 보다 표현적인 유형 시스템- 논리적 프로그래밍 버그 (예 : newtype 래퍼, 내용이있는 열거 형 변형)를 방지합니다. 참조 및 변수는 기본적으로 변경 불가능합니다. 개발자가 최소 권한의 보안 원칙을 따르고 실제로 의도 한 경우에만 참조 또는 변수를 변경 가능하도록 표시하도록 지원합니다. C ++에는 const가 있지만 자주 사용되지 않고 일관성없이 사용되는 경향이 있습니다. 이에 비해 Rust 컴파일러는 결코 변경되지 않는 변경 가능한 값에 대한 경고를 제공하여 잘못된 가변성 주석을 방지하는 데 도움을줍니다.
4. 표준 라이브러리에서 더 나은 오류 처리- Result에서 잠재적으로 실패한 호출을 래핑하여 컴파일러가 필요한 값을 반환하지 않는 함수에 대해서도 사용자가 실패를 확인하도록 요구합니다. 이는 처리되지 않은 오류로 인해 발생하는 Rage Against the Cage 취약점과 같은 버그로부터 보호합니다. ?연산자를 통해 오류를 쉽게 전파 할 수 있습니다. 운영자와 낮은 오버 헤드를 위해 결과를 최적화하는 Rust는 사용자가 오류가있는 함수를 동일한 스타일로 작성하고 동일한 보호를 받도록 권장합니다.
5. 초기화- 사용하기 전에 모든 변수를 초기화해야합니다. 초기화되지 않은 메모리 취약점은 역사적으로 Android 보안 취약점의 3-5 %의 근본 원인이었습니다. Android 11에서는이 문제를 줄이기 위해 C / C ++에서 메모리를 자동 초기화하기 시작했습니다. 그러나 0으로 초기화하는 것이 항상 안전하지는 않습니다. 특히 반환 값과 같은 경우 잘못된 오류 처리의 새로운 원인이 될 수 있습니다. Rust는 사용하기 전에 모든 변수를 해당 유형의 유효한 멤버로 초기화하여 의도하지 않게 안전하지 않은 값으로 초기화하는 문제를 방지해야합니다. C / C ++ 용 Clang과 유사하게 Rust 컴파일러는 초기화 요구 사항을 인식하고 이중 초기화의 잠재적 인 성능 오버 헤드를 방지합니다.
6. 더 안전한 정수 처리- 기본적으로 Rust 디버그 빌드에 대해 오버플로 삭제 기능이 설정되어있어 프로그래머가 실제로 오버플로를 계산하려는 경우에는 Wrapping_add를 지정하고 그렇지 않은 경우에는 saturating_add를 지정하도록 권장합니다. Android의 모든 빌드에 대해 오버플로 삭제를 활성화하려고합니다. 또한 모든 정수 유형 변환은 명시적 형변환입니다. 개발자는 변수에 할당 할 때 또는 다른 유형으로 산술을 시도 할 때 함수 호출 중에 실수로 형변환 할 수 없습니다.
- 다음 계획
Android 플랫폼에 새로운 언어를 추가하는 것은 큰 작업입니다. 유지 관리해야하는 툴체인 및 종속성, 업데이트해야하는 테스트 인프라 및 도구, 교육을 받아야하는 개발자가 있습니다. 지난 18 개월 동안 우리는 Android 오픈 소스 프로젝트에 Rust 지원을 추가했으며 앞으로 몇 달 동안 공유 할 얼리 어답터 프로젝트가 몇 개 있습니다. 이를 더 많은 OS로 확장하는 것은 다년간의 프로젝트입니다. 이 블로그에 더 많은 업데이트를 게시 할 예정입니다.
출처: https://security.googleblog.com/2021/04/rust-in-linux-kernel.html