Firma Google ogłosiła włączenie języka programowania Rust do listy języków dopuszczonych do rozwoju platformy Android. Kompilator języka Rust został włączony do drzewa kodu źródłowego Android już w 2019 roku, ale wsparcie dla tego języka pozostawało eksperymentalne. Jednymi z pierwszych komponentów w Rust, które mają być dostarczane w Androidzie, są nowe implementacje mechanizmu międzyprocesowej komunikacji Binder oraz stosu Bluetooth.
Wdrożenie Rust odbywa się w ramach projektu mającego na celu zwiększenie zabezpieczeń, promowanie technik bezpiecznego programowania oraz poprawę efektywności identyfikacji problemów związanych z pamięcią w Androidzie. Zauważono, że około 70% wszystkich krytycznych podatności wykrytych w Androidzie jest spowodowanych błędami w obsłudze pamięci. Zastosowanie języka Rust, który skupia się na bezpiecznej pracy z pamięcią i zapewnia automatyczne zarządzanie pamięcią, pozwoli zmniejszyć ryzyko wystąpienia podatności spowodowanych błędami w zarządzaniu pamięcią, takich jak odwołania do obszaru pamięci po jego zwolnieniu oraz przekroczenia granic bufora.
Bezpieczna praca z pamięcią w Rust jest zapewniana podczas kompilacji poprzez sprawdzanie odniesień, śledzenie własności obiektów oraz uwzględnianie czasu życia obiektów (zakresu widoczności), a także poprzez ocenę poprawności dostępu do pamięci w czasie wykonywania kodu. Rust oferuje również środki ochrony przed przepełnieniami całkowitymi, wymaga obowiązkowej inicjalizacji wartości zmiennych przed ich użyciem, lepiej obsługuje błędy w standardowej bibliotece, stosuje koncepcję niemutowalności odniesień i zmiennych domyślnie oraz oferuje silną statyczną typizację w celu minimalizacji błędów logicznych.
W Androidzie bezpieczna praca z pamięcią jest zapewniana w już wspieranych językach Kotlin i Java, jednak nie nadają się one do rozwoju komponentów systemowych z powodu dużych narzutów. Rust umożliwia osiągnięcie wydajności zbliżonej do języków C i C++, co pozwala na jego wykorzystanie do opracowania niskopoziomowych części platformy oraz komponentów do interakcji z sprzętem.
Aby zapewnić bezpieczeństwo kodu w C i C++ na Androidzie, stosuje się izolację sandboxową, analizę statyczną oraz testowanie fuzzingowe. Możliwości izolacji sandboxowej są ograniczone i osiągnęły swoje granice (dalsze dzielenie na procesy nie jest uzasadnione z punktu widzenia zużycia zasobów). Wśród ograniczeń stosowania sandboxu wymienia się duże narzuty i wzrost zużycia pamięci spowodowane koniecznością tworzenia nowych procesów oraz występowanie dodatkowych opóźnień związanych z używaniem IPC.
Jednakże sandbox nie eliminuje luk w kodzie, a jedynie zmniejsza ryzyko i utrudnia przeprowadzenie ataku, ponieważ do eksploatacji konieczne jest wykrycie nie jednej, a kilku podatności. Metody oparte na testowaniu kodu są ograniczone tym, że do wykrycia błędów konieczne jest stworzenie warunków do ujawnienia problemu. Obejście wszystkich możliwych wariantów jest niemożliwe, dlatego wiele błędów pozostaje niezauważonych.
Dla procesów systemowych w Androidzie firma Google stosuje „regułę dwóch”, zgodnie z którą każdy dodawany kod musi spełniać nie więcej niż dwa z trzech warunków: praca z niezweryfikowanymi danymi wejściowymi, użycie niebezpiecznego języka programowania (C/C++) oraz wykonywanie bez rygorystycznej izolacji sandboxowej (posiadanie podwyższonych przywilejów). Z tej zasady wynika, że kod do przetwarzania danych zewnętrznych powinien być albo ograniczony do minimalnych przywilejów (izolowany), albo napisany w bezpiecznym języku programowania.
Google nie ma na celu przepisania istniejącego kodu C/C++ na Rust, lecz planuje używać tego języka do tworzenia nowego kodu. Użycie Rust dla nowego kodu ma sens, ponieważ statystyki pokazują, że większość błędów pojawia się w nowym lub niedawno zmienionym kodzie. W szczególności około 50% wykrywanych błędów związanych z pamięcią w Androidzie występuje w kodzie napisanym mniej niż rok temu.

Źródło: opennet.ru
