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ędneAby 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ędneW 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ędneW 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ą:
- Dostęp do usługi
/dev/vndbinder
. - Element
{transfer, call}
łączy się zvndservicemanager
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.- 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;