Użyj IPC powiązania

Na tej stronie opisujemy zmiany w sterowniku Binder na Androidzie 8 oraz szczegóły na temat korzystania z IPC powiązania i listę wymaganych zasad SELinux.

Zmiany w sterowniku Binder

Począwszy od Androida 8 platforma Androida i listy HAL komunikują się teraz z przy użyciu separatora. W tej komunikacji gwałtownie zwiększa się sporządzenie relacji ruchu, Android 8 zawiera kilka ulepszeń mających na celu utrzymanie IPC separatora szybko. Dostawcy SoC i producenci OEM powinni połączyć się bezpośrednio z odpowiednich oddziałów Androida w wersji 4.4, 4.9 lub nowszej w projekcie kernel/common.

Wiele domen powiązań (kontekstów)

Common-4.4 i nowsze, w tym nadrzędne

Aby wyraźnie podzielić ruch powiązany z powiązaniem między platformę (niezależną od urządzenia) (specyficzny dla urządzenia), w Androidzie 8 wprowadzono koncepcję powiązań kontekstu. Każdy kontekst powiązania ma własny węzeł urządzenia i własny kontekst (usługę). Dostęp do Menedżera kontekstu możesz uzyskać tylko na tym urządzeniu i węzła powiązania, do którego należy, oraz podczas przekazywania węzła powiązanego przez określony jest on dostępny z tego samego kontekstu tylko przez inny proces, odizolowanie wszystkich domen od siebie. Szczegółowe informacje o korzystaniu z tej funkcji znajdziesz w sekcji vndbinder oraz vndservicemanager.

Zbieranie w postaci rozproszenia

Common-4.4 i nowsze, w tym nadrzędne

W poprzednich wersjach Androida każdy element danych w wywołaniu powiązania był kopiowany. trzy razy:

  • Po zserializacji do postaci Parcel w trakcie nawiązywania połączenia
  • W sterowniku jądra w celu skopiowania pakietu Parcel do środowiska docelowego. proces
  • Jeden raz do usunięcia z serializacji obiektu Parcel w procesie docelowym

Android 8 używa gromadzenie punktowe , by zmniejszyć liczbę kopii z 3 do 1. Zamiast najpierw serializuje dane w Parcel, dane pozostają w pierwotnym formacie. układ struktury i pamięci, a sterownik natychmiast skopiuje go do środowiska docelowego proces tworzenia konta. Gdy dane znajdą się w procesie docelowym, struktura i pamięć układ jest taki sam, a dane można odczytać bez konieczności dodatkowej kopii.

Precyzyjne blokowanie

Common-4.4 i nowsze, w tym nadrzędne

W poprzednich wersjach Androida sterownik Binder wykorzystywał globalną blokadę do ochrony przed równoczesnym dostępem do krytycznych struktur danych. Chociaż było niewiele o blokadę, głównym problemem było to, że wątek o niskim priorytecie uzyskać blokadę, a następnie wywłaszczać ją, co mogło znacznie opóźnić wątki o wyższym priorytecie, które muszą mieć taką samą blokadę. Spowodowało to zacinanie się platformy.

Wstępne próby rozwiązania tego problemu obejmowały wyłączenie tymczasowego przerwania przytrzymując globalny blokadę. Było to jednak raczej haker niż prawdziwe rozwiązanie, i ostatecznie została odrzucona przez serwer nadrzędny i odrzucona. Kolejne próby Skupiamy się na bardziej dogłębnym blokowaniu zabezpieczeń. na urządzeniach Pixel od stycznia 2017 r. Choć większość z tych zmian dotyczyła zostały opublikowane, w kolejnych wersjach wprowadzono istotne ulepszenia.

Po zidentyfikowaniu drobnych błędów w szczegółowej implementacji blokowania opracowaliśmy ulepszone rozwiązanie z inną architekturą blokowania i przesłane zmian we wszystkich popularnych gałęziach jądra systemu operacyjnego. Testujemy to na wielu różnych urządzeniach; bo nic nie wiemy nierozwiązanych problemów, jest to zalecana implementacja w przypadku urządzeń z Androidem 8.

Dziedziczenie priorytetów w czasie rzeczywistym

Common-4.4 i common-4.9 (już wkrótce)

Sterownik powiązania zawsze obsługiwał ładne dziedziczenie priorytetów. Jako coraz więcej procesów w Androidzie działa z priorytetem w czasie rzeczywistym, ma teraz sens w przypadku, gdy wątek w czasie rzeczywistym wywołuje wywołanie Binder, w procesie obsługi tego wywołania również działa z priorytetem w czasie rzeczywistym. Do obsługują te przypadki użycia, w Androidzie 8 zaimplementowano dziedziczenie priorytetów w czasie rzeczywistym. w sterowniku.

Oprócz dziedziczenia priorytetów na poziomie transakcji priorytet węzła dziedziczenie umożliwia węzłowi (obiektowi usługi powiązania) określenie minimalnej wartości priorytet, z jakim powinny być wykonywane wywołania tego węzła. Poprzednie wersje Android obsługiwał już dziedziczenie priorytetów węzłów za pomocą odpowiednich wartości, ale W Androidzie 8 dodaliśmy obsługę dziedziczenia zasad harmonogramu w czasie rzeczywistym.

Zmiany w przestrzeni użytkownika

Android 8 uwzględnia wszystkie zmiany w przestrzeni użytkownika wymagane do działania sterownik bindera we wspólnym jądrze, z jednym wyjątkiem: wyłącz dziedziczenie priorytetów w czasie rzeczywistym dla Aplikacja /dev/binder używa ioctl. W ramach kolejnych procesów programistycznych przełączyliśmy kontrolę priorytetu do bardziej szczegółowej metody, która jest stosowana do trybu powiązania (a nie kontekst). Dlatego nie ma go we wspólnej gałęzi Androida, a zamiast tego przesłanych w naszych popularnych jądrach.

Skutkiem tej zmiany jest wyłączenie dziedziczenia priorytetów w czasie rzeczywistym przez domyślnie dla każdego węzła. Zespół ds. wydajności Androida odkrył, warto włączyć dziedziczenie priorytetów w czasie rzeczywistym dla wszystkich węzłów hwbinder. Aby uzyskać ten sam efekt, wybierz ta zmiana w przestrzeni użytkownika.

Identyfikatory SHA w popularnych jądrach

Aby uzyskać niezbędne zmiany w sterowniku Binder, zsynchronizuj z odpowiednią wartością SHA:

  • Wspólny-3,18
    cc8b90c121de ANDROID: binder: nie sprawdzaj uprawnień przy przywracaniu.
  • Zwykły-4,4
    76b376eac7a2 ANDROID: binder: nie sprawdzaj uprawnień przy przywracaniu.
  • Zwykły-4,9
    ecd972d4f9b5 ANDROID: binder: nie sprawdzaj uprawnień przy przywracaniu.

Praca z IPC powiązania

W przeszłości procesy dostawcy wykorzystywały komunikację między procesami binarnymi (IPC). W Androidzie 8 węzeł urządzenia /dev/binder staje się dostępne wyłącznie w ramach procesów platformy, co oznacza, że procesy dostawcy nie są już mają do nich dostęp. Procesy dostawcy mają dostęp do /dev/hwbinder, ale muszą przekonwertować interfejsy AIDL na HIDL. Dla dostawców, którzy chcą kontynuować za pomocą interfejsów AIDL między procesami dostawcy, Android obsługuje IPC binder jako opisane poniżej. W Androidzie 10 stabilna wersja AIDL zezwala na wszystkie procesów korzystających z /dev/binder, a zarazem dbanie o stabilność gwarantuje rozwiązanie HIDL i /dev/hwbinder. Jak korzystać z wersji stabilnej AIDL, zobacz AIDL dla kont HAL.

Vndbinder

Android 8 obsługuje nową domenę Binder do użytku przez usługi dostawcy, dostęp za pomocą /dev/vndbinder zamiast /dev/binder. Za pomocą /dev/vndbinder, Android ma teraz 3 następujące funkcje: Domeny IPC:

Domena IPC Opis
/dev/binder IPC między platformą/procesami aplikacji z interfejsami AIDL
/dev/hwbinder IPC między platformą/procesami dostawcy z interfejsami HIDL
IPC między procesami dostawcy z wykorzystaniem interfejsów HIDL
/dev/vndbinder Protokół IPC między procesami dostawcy/dostawcy z interfejsami AIDL

Aby /dev/vndbinder była widoczna, sprawdź konfigurację jądra element CONFIG_ANDROID_BINDER_DEVICES ma wartość "binder,hwbinder,vndbinder" (jest to domyślne ustawienie w jądra systemu).

Zwykle procesy dostawcy nie otwierają bezpośrednio sterownika bindatora i do biblioteki przestrzeni użytkownika libbinder, która otwiera sterownika bindatora. Dodaję metodę do usługi ::android::ProcessState() wybiera sterownik segregatora dla: libbinder. Procesy dostawcy powinny wywołaj tę metodę przed wywołaniem tej metody w ProcessState, IPCThreadState ani przed wykonaniem jakichkolwiek wywołań funkcji Binder. Do należy wykonać następujące wywołanie po main() procesu dostawcy (klient i serwer):

ProcessState::initWithDriver("/dev/vndbinder");

menedżer usługi Vndservicemanager

Wcześniej usługi Binder były rejestrowane w servicemanager, z których można je pobierać przez inne procesy. Na Androidzie 8 servicemanager jest teraz używany wyłącznie przez platformę i aplikację a procesy dostawcy nie będą miały do niego dostępu.

Jednak usługi dostawców mogą teraz używać vndservicemanager, nowego instancja instancji servicemanager, która korzysta z interfejsu /dev/vndbinder zamiast /dev/binder, które zostało utworzone na podstawie tych samych źródeł co platforma servicemanager. Procesy dostawców nie muszą sprawiać, zmiana sposobu rozmowy z: vndservicemanager; gdy rozpoczyna się proces dostawcy. /dev/vndbinder, wyszukiwania usług są automatycznie przenoszone do vndservicemanager

Plik binarny vndservicemanager znajduje się w domyślnej wersji Androida Makiety urządzenia.

Zasada SELinux

Procesy dostawcy, które chcą używać funkcji powiązania do komunikacji z muszą:

  1. Dostęp do usługi /dev/vndbinder.
  2. Element {transfer, call} łączy się z vndservicemanager
  3. binder_call(A, B) w przypadku dowolnej domeny dostawcy A, która chce wywoływać metodę do domeny dostawcy B za pomocą interfejsu powiązania dostawcy.
  4. Uprawnienia dla {add, find} usług w: vndservicemanager

Aby spełnić wymagania 1 i 2, skorzystaj z vndbinder_use() :

vndbinder_use(some_vendor_process_domain);

Aby spełnić wymaganie 3, binder_call(A, B) dla dostawcy procesy A i B wymagające rozmowy na temat spowalniania mogą pozostać na swoim miejscu i nie wymagają zmiany nazwy.

Aby spełnić wymaganie 4, musisz zmienić sposób nazw usług, etykiety usług i reguły są obsługiwane.

Szczegółowe informacje na temat SELinux znajdziesz w sekcji Security- Enhanced Linux na Androidzie. Szczegółowe informacje na temat SELinux w systemie Android 8.0 można znaleźć w sekcji SELinux na Androida 8,0.

Nazwy usług

Wcześniej dostawca przetwarzał zarejestrowane nazwy usług w plikach service_contexts plik i dodaliśmy odpowiednie reguły dostępu ten plik. Przykładowy plik service_contexts z device/google/marlin/sepolicy:

AtCmdFwd                              u:object_r:atfwd_service:s0
cneservice                            u:object_r:cne_service:s0
qti.ims.connectionmanagerservice      u:object_r:imscm_service:s0
rcs                                   u:object_r:radio_service:s0
uce                                   u:object_r:uce_service:s0
vendor.qcom.PeripheralManager         u:object_r:per_mgr_service:s0

W Androidzie 8 vndservicemanager wczytuje vndservice_contexts plik. Usługi dostawców przenoszonych do vndservicemanager (i które już znajdują się w starej wersji service_contexts) należy dodać do nowego vndservice_contexts.

Etykiety usługi

Wcześniej etykiety usług, takie jak u:object_r:atfwd_service:s0 zostały zdefiniowane w pliku service.te. Przykład:

type atfwd_service,      service_manager_type;

W Androidzie 8 musisz zmienić typ na vndservice_manager_type i przenieś regułę do sekcji vndservice.te. Przykład:

type atfwd_service,      vndservice_manager_type;

reguły menedżera usługi

Wcześniej reguły przyznawały domenom dostęp z możliwością dodawania i wyszukiwania usług servicemanager Przykład:

allow atfwd atfwd_service:service_manager find;
allow some_vendor_app atfwd_service:service_manager add;

W Androidzie 8 reguły te mogą pozostać na swoim miejscu i korzystać z tej samej klasy. Przykład:

allow atfwd atfwd_service:service_manager find;
allow some_vendor_app atfwd_service:service_manager add;