안드로이드의 오래된 Binder C 드라이버, Rust 구현으로 교체된다

안드로이드의 오래된 Binder C 드라이버, Rust 구현으로 교체된다

안드로이드 기기 안에서 앱과 시스템 서비스가 대화할 때는 보통 Binder라는 통신 통로가 쓰입니다.

화면에 보이는 앱 하나가 카메라, 알림, 파일 저장 같은 기능을 직접 모두 처리하는 대신 운영체제의 서비스에 요청을 보내는 구조입니다. 이 통로를 Linux 커널에 이어 온 코드가 이제 큰 변화를 맞습니다.

구글 엔지니어들이 Linux 커널에 제출한 패치에 따라 기존 C 언어 Binder 드라이버가 Linux 커널 버전 7.4 개발 주기에서 제거될 예정입니다. 그 자리는 Rust로 다시 작성된 Binder 드라이버가 맡습니다. 오래된 파일을 지우는 데 그치지 않고 안드로이드의 핵심 통신 경로를 다른 구현으로 완전히 전환하는 일입니다.

Binder는 왜 중요한가

Binder 구현 이전
Binder 구현 이전

Binder는 프로세스 사이의 통신을 담당합니다. 프로세스는 실행 중인 프로그램을 뜻하는데 안드로이드에서는 앱과 시스템 서비스가 서로 다른 프로세스로 동작하는 경우가 많습니다. 한 프로세스가 다른 프로세스의 메모리를 함부로 만지지 못하게 분리하면서도 필요한 요청과 응답을 주고받으려면 정해진 통신 장치가 필요합니다.

기존 Binder C 드라이버는 15년 넘게 커널에 자리 잡았습니다. 오랜 기간 기능이 추가되면서 코드가 복잡해졌고 새로운 기능을 넣거나 취약점을 고치는 작업도 점점 조심스러워졌습니다. 이번에 제거 대상이 된 코드는 약 1만 1천 줄 규모입니다.

다만 C 코드가 오래됐다는 이유만으로 바꾸지는 않습니다. 새 Rust 구현은 이미 Linux 커널 버전 6.18에 메인라인으로 들어왔고 안드로이드 기기에서 실제로 사용되며 기능을 따라잡았습니다. 이제 실험적인 대체재 단계를 지나 다음 개발을 맡길 수 있는 구현으로 판단한 셈입니다.

Rust Binder가 맡게 될 것

안드로이드 커널의 Rust 드라이버 도입: 기대 효과 및 계획
안드로이드 커널의 Rust 드라이버 도입: 기대 효과 및 계획

Rust 버전의 가장 큰 기대 효과는 메모리 안전성입니다. C에서는 포인터가 가리키는 메모리의 유효 기간이나 배열의 경계를 개발자가 직접 관리해야 합니다. 이 부분에서 실수가 생기면 해제된 메모리를 다시 쓰거나 정해진 범위를 넘겨 읽는 문제가 발생할 수 있습니다.

Rust는 이런 메모리 접근 규칙을 컴파일 단계에서 더 엄격하게 확인합니다. 모든 오류를 자동으로 없애는 만능 장치는 아니지만 Binder처럼 권한이 높은 커널 코드에서 반복되는 실수의 범위를 줄이는 데 도움이 됩니다. 구글은 기존 드라이버를 유지하고 새 기능을 추가하는 일이 취약점을 낳을 위험도 줄어들 것으로 보고 있습니다.

성능도 교체를 막는 이유가 되지 않았습니다. 새 구현은 기존 C 드라이버와 비슷한 수준의 성능을 내며 일부 상황에서는 더 빠를 수 있다는 평가를 받았습니다. 안드로이드 앱을 실행할 때 Binder 호출이 자주 일어나는 만큼, 기능 호환성과 처리량을 함께 확인한 일은 중요합니다.

이번 변경으로 모든 안드로이드 기기의 커널이 한 번에 바뀌지는 않습니다. Linux 메인라인에 패치가 반영되는 절차가 남아 있고 각 안드로이드 제품과 장기 지원 커널이 새 드라이버를 채택하는 시점도 따로 결정됩니다. 제조사가 수정한 커널이나 오래된 제품에는 기존 구현이 더 오래 남을 수 있습니다.

커널에서 Rust의 자리가 넓어지는 과정

Binder는 Linux 커널 안에서 Rust의 역할을 보여 주는 상징적인 사례가 됐습니다. 드라이버 전체를 새 언어로 옮기려면 기존 동작과 사용자 공간의 기대를 세밀하게 맞춰야 합니다. 특히 Binder는 앱, 시스템 서비스, 안드로이드 프레임워크가 모두 의존하므로 작은 동작 차이도 호환성 문제를 일으킬 수 있습니다.

이번에는 기능 호환성을 확보한 뒤 오래된 C 구현을 정리하는 순서가 선택됐습니다. 두 구현을 계속 병렬로 유지하는 부담을 줄이고 앞으로의 최적화와 기능 추가를 Rust 쪽에 집중하려는 방향입니다. 유지보수자가 같은 기능을 두 코드에 반복해서 반영하지 않아도 된다는 이점도 있습니다.

그렇다고 Rust 전환이 곧바로 모든 커널 보안 문제를 해결하지는 않습니다. 드라이버의 논리 오류나 권한 설계 문제는 언어와 별개로 생길 수 있습니다. 새 코드를 오래 운영하고 다양한 하드웨어와 안드로이드 버전에서 검증하는 과정이 계속 필요한 이유입니다.

Linux 사용자가 당장 데스크톱에서 체감할 변화도 크지 않습니다. Binder는 일반적인 Linux 데스크톱보다 안드로이드와 커널 개발 환경에서 더 직접적으로 쓰이는 구성 요소입니다. 다만 커널이 메모리 안전성을 높이는 방향으로 이동하고 있다는 흐름은 서버와 임베디드 장치의 드라이버에도 영향을 줄 수 있습니다.

원문 뉴스 : Phoronix

🐧 Linuxroom의 생각 :

안드로이드에서 Binder는 굉장히 중요한 역할을 하고 있습니다.

보안을 위해 각각의 앱과 시스템 기능들은 서로의 영역을 함부로 침범할 수 없도록 격리되어 있습니다.

예를 들어서, 카카오톡을 사용할때, 사진을 찍어서 상대방에게 전송하려면, 카메라 앱을 불러올 필요가 있습니다. 이럴 때 카카오톡 같은 앱이 시스템 서비스에게 "카메라 좀 켜주세요" 라고 메세지를 전달해주는, 말하자면 연락 통로 가 필요한데, 그 통로의 이름이 바로 Binder인 셈이죠.

이 Binder는 원래 C 언어로 만들어져 있었습니다. 15년이나 넘게 썼고, 오래 쓰다보니 코드가 1만 1천줄이나 쌓여서 너무 복잡해지기도 했고, 새 기능을 넣거나 내부를 고치거나 할 때, 보안 허점같은 리스크가 생길 위험이 커지게 된거죠.

왜 이걸 Rust 라는 언어로 바꾸느냐 하면, 기존 C언어는 사람이 일일이 메모리를 관리해야 하기 때문에, 깜빡 실수하면 취약점이 생기기 쉬웠습니다. 반면에는 Rust는 컴파일 단계에서 실수를 자동으로 잡아내서 취약점이 생길 위험을 대폭 줄여주기 때문이지요. 더불어 속도도 굉장히 빠르고 관리하기 편한 구조를 가지고 있습니다.

당장에 바뀌는건 사실상 없지만, 기능은 똑같은데 앞으로의 보안 리스크의 해소, 및 개발자들이 편해지자고 내부 엔진을 싹 새로운걸로 뜯어고치고 있다. 라는 이야기입니다 😄


※ 각주

[1] Binder: 안드로이드의 앱과 운영체제 서비스가 서로 요청과 응답을 주고받도록 연결하는 프로세스 간 통신 장치입니다. 

[2] 프로세스: 실행 중인 프로그램을 운영체제가 관리하는 단위입니다. 서로 다른 프로세스는 메모리가 기본적으로 분리됩니다. 

[3] 메인라인: 리눅스 커널 개발 프로젝트에서 공식적으로 관리되는 주 개발 코드입니다. 

[4] Rust: 메모리 접근 규칙을 컴파일 단계에서 검사하도록 설계된 프로그래밍 언어입니다. 커널과 드라이버 개발에서도 사용 범위가 넓어지고 있습니다. 

[5] 커널: 하드웨어와 애플리케이션 사이에서 메모리, 프로세서, 장치 접근을 관리하는 운영체제의 핵심 부분입니다.