Do bazy kodu jądra Linux, na podstawie której powstaje wersja 6.18, przyjęto implementację mechanizmu międzyprocesowej komunikacji Binder, napisaną w języku Rust. Binder jest używany w systemie Android do organizacji interakcji między procesami oraz zdalnego wywoływania metod (jeden proces Android może wywołać metodę lub funkcję w innym procesie Android, używając Bindera do identyfikacji, wywołania i przesyłania argumentów między procesami). Kod Bindera został przepisany na Rust w ramach projektu mającego na celu zwiększenie bezpieczeństwa, promowanie technik bezpiecznego programowania oraz poprawę wydajności wykrywania problemów związanych z pamięcią w Androidzie (około 70% wszystkich niebezpiecznych luk w zabezpieczeniach wykrytych w Androidzie jest spowodowanych błędami związanymi z pamięcią).
Wykorzystanie Rust pozwoliło rozwiązać pewne problemy, z którymi borykali się deweloperzy Bindera, w tym błędy związane z liczeniem referencji, blokadami oraz sprawdzaniem granic, a także znacznie zmniejszyć złożoność obsługi błędów. Implementacja Bindera w Rust jest funkcjonalnie zbliżona do oryginalnej wersji napisanej w języku C, przechodzi wszystkie testy AOSP (Android Open-Source Project) i może być używana do tworzenia stabilnych edycji systemu Android. Mimo zaawansowanych możliwości i wsparcia dla obiektów o skomplikowanej semantyce własności, sterownik w Rust ma mniejszą objętość niż jego odpowiednik w C — 5.5 wobec 5.8 tysiąca linii kodu.
W opisie commita autor wymienia następujące motywy dla przepisania Bindera:
- Binder rozwija się już od 15 lat i w tym czasie jego funkcjonalność oraz złożoność znacznie wzrosły — projekt znajduje się na styku wszystkich komponentów Androida i obejmuje wiele zadań wykraczających poza IPC:
- prawidłowa analiza i przekształcanie zawartości transakcji, które mogą zawierać wiele obiektów różnych typów (na przykład wskaźników, deskryptorów plików), współdziałających ze sobą;
- monitorowanie rozmiarów pul wątków w przestrzeni użytkownika oraz zapewnienie przydzielania transakcji do wątków w taki sposób, aby unikać wzajemnych blokad w przypadku wyczerpania wątków w puli;
- śledzenie liczników referencji obiektów, współużytkowanych przez kilka procesów, poprawnie przesyłając zmiany liczników referencji między procesami.
- przetwarzanie różnych scenariuszy wystąpienia błędów oraz połączenie 13 różnych blokad, 7 liczników linków i zmiennych atomowych. Przy tym powinien wykonywać podobne zadania jak najszybciej i najdokładniej.
- W starym kodzie narosło znaczne zadłużenie techniczne, które komplikowało zarówno wyszukiwanie błędów, jak i dalszy rozwój. Na przykład w jądrze występują duże funkcje liczące ponad tysiąc linii kodu, wątpliwe metody obsługi błędów oraz złożone struktury.
- Binder jest krytycznym elementem Androida z punktu widzenia bezpieczeństwa, ponieważ elementy platformy działające w izolowanych środowiskach sandbox, takie jak proces renderowania w Chrome i SW Codec, mają do niego bezpośredni dostęp, a luka w Binderze umożliwi obejście izolacji. Wysoka złożoność w połączeniu z zadłużeniem technicznym znacznie utrudnia utrzymanie wysokiego poziomu bezpieczeństwa w Binderze.
Źródło: opennet.ru
