Przestrzeń nazw konsolidatora

Zadbaj o dobrą organizację dzięki kolekcji Zapisuj i kategoryzuj treści zgodnie ze swoimi preferencjami.

Dynamiczny linker stawia czoła dwóm wyzwaniom w projekcie Treble VNDK:

  • Biblioteki współdzielone SP-HAL i ich zależności, w tym biblioteki VNDK-SP, są ładowane do procesów frameworka. Powinny istnieć pewne mechanizmy zapobiegające konfliktom symboli.
  • dlopen() i android_dlopen_ext() mogą wprowadzić pewne zależności środowiska uruchomieniowego, które nie są widoczne w czasie kompilacji i mogą być trudne do wykrycia przy użyciu analizy statycznej.

Te dwa wyzwania można rozwiązać za pomocą mechanizmu przestrzeni nazw konsolidatora . Ten mechanizm zapewnia dynamiczny linker. Może izolować współdzielone biblioteki w różnych przestrzeniach nazw linkera, aby biblioteki o tej samej nazwie biblioteki, ale z różnymi symbolami, nie powodowały konfliktu.

Z drugiej strony mechanizm przestrzeni nazw konsolidatora zapewnia elastyczność, dzięki czemu niektóre biblioteki współdzielone mogą być eksportowane przez przestrzeń nazw konsolidatora i używane przez inną przestrzeń nazw konsolidatora. Te wyeksportowane biblioteki współdzielone mogą stać się interfejsami programowania aplikacji, które są publiczne dla innych programów, jednocześnie ukrywając szczegóły ich implementacji w przestrzeniach nazw konsolidatora.

Na przykład /system/lib[64]/libcutils.so i /system/lib[64]/vndk-sp-${VER}/libcutils.so to dwie biblioteki współdzielone. Te dwie biblioteki mogą mieć różne symbole. Są one ładowane do różnych przestrzeni nazw konsolidatora, dzięki czemu moduły frameworka mogą zależeć od /system/lib[64]/libcutils.so , a biblioteki współdzielone SP-HAL mogą zależeć od /system/lib[64]/vndk-sp-${VER}/libcutils.so .

Z drugiej strony /system/lib[64]/libc.so jest przykładem biblioteki publicznej, która jest eksportowana przez przestrzeń nazw linkera i importowana do wielu przestrzeni nazw linkera. Zależności /system/lib[64]/libc.so , takie jak libnetd_client.so , są ładowane do przestrzeni nazw, w której znajduje się /system/lib[64]/libc.so . Inne przestrzenie nazw nie będą miały dostępu do tych zależności. Ten mechanizm hermetyzuje szczegóły implementacji, zapewniając jednocześnie interfejsy publiczne.

Jak to działa?

Dynamiczny linker jest odpowiedzialny za ładowanie bibliotek dzielonych określonych we wpisach DT_NEEDED lub bibliotek dzielonych określonych przez argument dlopen() lub android_dlopen_ext() . W obu przypadkach dynamiczny linker znajduje przestrzeń nazw linkera, w której znajduje się wywołujący i próbuje załadować zależności do tej samej przestrzeni nazw linkera. Jeśli dynamiczny linker nie może załadować biblioteki współdzielonej do określonej przestrzeni nazw konsolidatora, pyta on przestrzeń nazw konsolidatora o wyeksportowane biblioteki współdzielone.

Format pliku konfiguracyjnego

Format pliku konfiguracyjnego jest oparty na formacie pliku INI. Typowy plik konfiguracyjny wygląda tak:

dir.system = /system/bin
dir.system = /system/xbin
dir.vendor = /vendor/bin

[system]
additional.namespaces = sphal,vndk

namespace.default.isolated = true
namespace.default.search.paths = /system/${LIB}
namespace.default.permitted.paths = /system/${LIB}/hw
namespace.default.asan.search.paths = /data/asan/system/${LIB}:/system/${LIB}
namespace.default.asan.permitted.paths = /data/asan/system/${LIB}/hw:/system/${LIB}/hw

namespace.sphal.isolated = true
namespace.sphal.visible = true
namespace.sphal.search.paths = /odm/${LIB}:/vendor/${LIB}
namespace.sphal.permitted.paths = /odm/${LIB}:/vendor/${LIB}
namespace.sphal.asan.search.paths  = /data/asan/odm/${LIB}:/odm/${LIB}
namespace.sphal.asan.search.paths += /data/asan/vendor/${LIB}:/vendor/${LIB}
namespace.sphal.asan.permitted.paths  = /data/asan/odm/${LIB}:/odm/${LIB}
namespace.sphal.asan.permitted.paths += /data/asan/vendor/${LIB}:/vendor/${LIB}
namespace.sphal.links = default,vndk
namespace.sphal.link.default.shared_libs = libc.so:libm.so
namespace.sphal.link.vndk.shared_libs = libbase.so:libcutils.so

namespace.vndk.isolated = true
namespace.vndk.search.paths = /system/${LIB}/vndk-sp-29
namespace.vndk.permitted.paths = /system/${LIB}/vndk-sp-29
namespace.vndk.links = default
namespace.vndk.link.default.shared_libs = libc.so:libm.so

[vendor]
namespace.default.isolated = false
namespace.default.search.paths = /vendor/${LIB}:/system/${LIB}

Plik konfiguracyjny zawiera:

  • Kilka właściwości mapowania sekcji katalogu na początku dla dynamicznego linkera, aby wybrać efektywną sekcję.
  • Kilka sekcji konfiguracyjnych przestrzeni nazw konsolidatora:
    • Każda sekcja zawiera kilka przestrzeni nazw (wierzchołki grafu) i kilka łączy awaryjnych między przestrzeniami nazw (łuki grafu).
    • Każda przestrzeń nazw ma własną izolację, ścieżki wyszukiwania, dozwolone ścieżki i ustawienia widoczności.

Poniższe tabele szczegółowo opisują znaczenie każdej właściwości.

Właściwość mapowania sekcji katalogu

Nieruchomość Opis Przykład

dir. name

Ścieżka do katalogu, którego dotyczy sekcja [ name ] .

Każda właściwość mapuje pliki wykonywalne w katalogu do sekcji konfiguracji przestrzeni nazw konsolidatora. Mogą istnieć dwie (lub więcej) właściwości, które mają tę samą name , ale wskazują na różne katalogi.

dir.system = /system/bin
dir.system = /system/xbin
dir.vendor = /vendor/bin

Oznacza to, że konfiguracja określona w sekcji [system] dotyczy plików wykonywalnych ładowanych z /system/bin lub /system/xbin .

Konfiguracja określona w sekcji [vendor] dotyczy plików wykonywalnych ładowanych z /vendor/bin .

Właściwości relacji

Nieruchomość Opis Przykład
additional. namespaces

Lista rozdzielonych przecinkami dodatkowych przestrzeni nazw (oprócz default przestrzeni nazw) dla sekcji.

additional. namespaces = sphal, vndk

Oznacza to, że w konfiguracji [system] istnieją trzy przestrzenie nazw ( default , sphal i vndk ).

namespace. name . links

Lista rozdzielonych przecinkami rezerwowych przestrzeni nazw.

Jeśli współdzielona biblioteka nie może być znaleziona w bieżącej przestrzeni nazw, dynamiczny linker próbuje załadować współdzieloną bibliotekę z rezerwowych przestrzeni nazw. Przestrzeń nazw określona na początku listy ma wyższy priorytet.

namespace. sphal. links = default, vndk

Jeśli biblioteka współdzielona lub plik wykonywalny żąda biblioteki współdzielonej, której nie można załadować do przestrzeni nazw sphal , dynamiczny linker próbuje załadować bibliotekę współdzieloną z default przestrzeni nazw.

A następnie, jeśli współdzielona biblioteka nie może być załadowana z default przestrzeni nazw, dynamiczny linker próbuje załadować współdzieloną bibliotekę z przestrzeni nazw vndk .

Ostatecznie, jeśli wszystkie próby zakończą się niepowodzeniem, dynamiczny linker zwróci błąd.

namespace. name . link. other . shared_libs

Lista rozdzielonych dwukropkami bibliotek współdzielonych, które można przeszukiwać w other przestrzeniach nazw, gdy tych bibliotek nie można znaleźć w przestrzeni name .

Ta właściwość nie może być używana z namespace. name . link. other . allow_all_shared_libs .

namespace. sphal. link. default. shared_libs = libc.so: libm.so

Oznacza to, że odsyłacz rezerwowy akceptuje tylko libc.so lub libm.so jako żądaną nazwę biblioteki. Dynamiczny linker ignoruje odsyłacz rezerwowy ze sphal do default przestrzeni nazw, jeśli żądana nazwa biblioteki nie jest libc.so lub libm.so .

namespace. name . link. other . allow_all_shared_libs

Wartość logiczna wskazująca, czy wszystkie biblioteki współdzielone mogą być przeszukiwane w other przestrzeni nazw, gdy tych bibliotek nie można znaleźć w przestrzeni name .

Ta właściwość nie może być używana z namespace. name . link. other . shared_libs .

namespace. vndk. link. sphal. allow_all_shared_libs = true

Oznacza to, że wszystkie nazwy bibliotek mogą przechodzić przez łącze rezerwowe z vndk do przestrzeni nazw sphal .

Właściwości przestrzeni nazw

Nieruchomość Opis Przykład
namespace. name . isolated

Wartość logiczna, która wskazuje, czy dynamiczny linker powinien sprawdzić, gdzie znajduje się biblioteka współdzielona.

Jeśli isolated ma wartość true , można załadować tylko biblioteki współdzielone, które znajdują się w jednym z katalogów search.paths (z wyłączeniem podkatalogów) lub w jednym z katalogów permitted.paths (w tym podkatalogach).

Jeśli isolated jest false (domyślnie), dynamiczny linker nie sprawdza ścieżki bibliotek współdzielonych.

namespace. sphal. isolated = true

Oznacza to, że do przestrzeni nazw sphal można załadować tylko biblioteki współdzielone w search.paths lub w permitted.paths .

namespace. name . search.paths

Oddzielona dwukropkami lista katalogów do wyszukiwania bibliotek współdzielonych.

Katalogi określone w search.paths są poprzedzone nazwą żądanej biblioteki, jeśli wywołania funkcji dlopen() lub wpisy DT_NEEDED nie określają pełnej ścieżki. Katalog określony na początku listy ma wyższy priorytet.

Gdy wartość isolated ma wartość true , biblioteki współdzielone znajdujące się w jednym z katalogów search.paths (z wyłączeniem podkatalogów) mogą być ładowane niezależnie od właściwości permitted.paths .

Na przykład, jeśli search.paths to /system/${LIB} , a permitted.paths jest pusty, /system/${LIB}/libc.so można załadować, ale /system/${LIB}/vndk/libutils.so nie można załadować.

namespace. default. search.paths = /system/${LIB}

Wskazuje to, że dynamiczny linker przeszukuje /system/${LIB} w poszukiwaniu bibliotek współdzielonych.

namespace. name . asan.search.paths

Rozdzielana dwukropkami lista katalogów do wyszukiwania bibliotek współdzielonych, gdy włączony jest AddressSanitizer (ASan) .

namespace. name . search.paths jest ignorowana, gdy ASan jest włączony.

namespace. default. asan.search.paths = /data/asan/system/${LIB}: /system/${LIB}

Wskazuje to, że gdy ASan jest włączony, dynamiczny linker najpierw przeszukuje /data/asan/system/${LIB} , a następnie przeszukuje /system/${LIB} .

namespace. name . permitted.paths

Lista rozdzielonych dwukropkami katalogów (w tym podkatalogów), w których dynamiczny linker może załadować współdzielone biblioteki (oprócz search.paths ), gdy jest isolated , jest true .

Biblioteki współdzielone, które znajdują się w podkatalogach permitted.paths , również mogą być ładowane. Na przykład, jeśli permitted.paths to /system/${LIB} , można załadować zarówno /system/${LIB}/libc.so , jak i /system/${LIB}/vndk/libutils.so .

Jeśli isolated jest false , permitted.paths są ignorowane i jest emitowane ostrzeżenie.

namespace. default. permitted.paths = /system/${LIB}/hw

Wskazuje to, że współdzielone biblioteki w /system/${LIB}/hw mogą być ładowane do izolowanej default przestrzeni nazw.

Na przykład bez permitted.paths , libaudiohal.so nie może załadować /system/${LIB}/hw/audio.a2dp.default.so do default przestrzeni nazw.

namespace. name . asan.permitted.paths

Oddzielona dwukropkami lista katalogów, do których dynamiczny linker może załadować współdzielone biblioteki, gdy ASan jest włączony.

namespace. name . permitted.paths jest ignorowany, gdy ASan jest włączony.

namespace. default. asan.permitted.paths = /data/asan/system/${LIB}/hw: /system/${LIB}/hw

Wskazuje to, że gdy ASan jest włączony, biblioteki współdzielone w /data/asan/system/${LIB}/hw lub /system/${LIB}/hw można załadować do izolowanej default przestrzeni nazw.

namespace. name . visible

Wartość logiczna, która wskazuje, czy program (inny niż libc ) może uzyskać uchwyt przestrzeni nazw konsolidatora za pomocą android_get_exported_namespace() i otworzyć bibliotekę współdzieloną w przestrzeni nazw konsolidatora, przekazując uchwyt do android_dlopen_ext() .

Jeśli visible jest true , android_get_exported_namespace() zawsze zwraca uchwyt, jeśli przestrzeń nazw istnieje.

Jeśli visible jest false (domyślnie), android_get_exported_namespace() zawsze zwraca NULL , niezależnie od obecności przestrzeni nazw. Biblioteki współdzielone mogą być ładowane do tej przestrzeni nazw tylko wtedy, gdy (1) są żądane przez inną przestrzeń nazw konsolidatora, która ma łącze rezerwowe do tej przestrzeni nazw, lub (2) są żądane przez inne biblioteki współdzielone lub pliki wykonywalne w tej przestrzeni nazw.

namespace. sphal. visible = true

Oznacza to, że android_get_exported_namespace("sphal") może zwrócić prawidłowy uchwyt przestrzeni nazw konsolidatora.

Tworzenie przestrzeni nazw linkera

W systemie Android 11 konfiguracja konsolidatora jest tworzona w czasie wykonywania w obszarze /linkerconfig zamiast używania zwykłych plików tekstowych w ${android-src}/system/core/rootdir/etc . Konfiguracja jest generowana w czasie rozruchu na podstawie środowiska uruchomieniowego, które zawiera następujące elementy:

  • Jeśli urządzenie obsługuje VNDK
  • Docelowa wersja VNDK partycji dostawcy
  • Wersja VNDK partycji produktu
  • Zainstalowane moduły APEX

Konfiguracja konsolidatora jest tworzona przez rozwiązywanie zależności między przestrzeniami nazw konsolidatora. Na przykład, jeśli istnieją jakiekolwiek aktualizacje w modułach APEX, które zawierają aktualizacje zależności, generowana jest konfiguracja konsolidatora odzwierciedlająca te zmiany. Więcej szczegółów na temat tworzenia konfiguracji konsolidatora można znaleźć w ${android-src}/system/linkerconfig .

Izolacja przestrzeni nazw linkera

Istnieją trzy typy konfiguracji. W zależności od wartości PRODUCT_TREBLE_LINKER_NAMESPACES i BOARD_VNDK_VERSION w BoardConfig.mk odpowiednia konfiguracja jest generowana podczas uruchamiania.

PRODUCT_TREBLE_
LINKER_NAMESPACES
BOARD_VNDK_
VERSION
Wybrana konfiguracja Wymóg VTS
true current VNDK Obowiązkowe dla urządzeń z systemem Android 9 lub nowszym
Pusty VNDK Lite Obowiązkowe dla urządzeń uruchomionych z systemem Android 8.x
false Pusty Legacy Dla urządzeń bez wysokich tonów

Konfiguracja VNDK Lite izoluje biblioteki współdzielone SP-HAL i VNDK-SP. W Androidzie 8.0 musi to być plik konfiguracyjny dynamicznego konsolidatora, gdy PRODUCT_TREBLE_LINKER_NAMESPACES ma wartość true .

Konfiguracja VNDK izoluje również biblioteki współdzielone SP-HAL i VNDK-SP. Ponadto ta konfiguracja zapewnia pełną izolację dynamicznego linkera. Zapewnia to, że moduły na partycji systemowej nie będą zależeć od bibliotek współdzielonych na partycjach dostawcy i na odwrót.

W systemie Android 8.1 lub nowszym konfiguracja VNDK jest konfiguracją domyślną i zdecydowanie zaleca się włączenie pełnej izolacji konsolidatora dynamicznego przez ustawienie BOARD_VNDK_VERSION na current .

Konfiguracja VNDK

Konfiguracja VNDK izoluje zależności bibliotek współużytkowanych między partycją systemową a partycjami dostawcy. W porównaniu z konfiguracjami wymienionymi w poprzednim podrozdziale różnice są przedstawione w następujący sposób:

  • Procesy ramowe

    • default , tworzone są przestrzenie nazw vndk , sphal i rs .
    • Wszystkie przestrzenie nazw są izolowane.
    • Systemowe biblioteki współdzielone są ładowane do default przestrzeni nazw.
    • SP-HAL są ładowane do przestrzeni nazw sphal .
    • Biblioteki współdzielone VNDK-SP załadowane do przestrzeni nazw vndk .
  • Procesy dostawcy

    • default , vndk i system przestrzenie nazw są tworzone.
    • default przestrzeń nazw jest izolowana.
    • Biblioteki współdzielone dostawcy są ładowane do default przestrzeni nazw.
    • Biblioteki współużytkowane VNDK i VNDK-SP są ładowane do przestrzeni nazw vndk .
    • LL-NDK i jego zależności są ładowane do system przestrzeni nazw.

Relacja między przestrzeniami nazw konsolidatora jest zilustrowana poniżej.

Wykres przestrzeni nazw linkera opisany w konfiguracji VNDK
Rysunek 1. Izolacja przestrzeni nazw konsolidatora (konfiguracja VNDK)

Na powyższym obrazku LL-NDK i VNDK-SP oznaczają następujące biblioteki współdzielone:

  • LL-NDK
    • libEGL.so
    • libGLESv1_CM.so
    • libGLESv2.so
    • libGLESv3.so
    • libandroid_net.so
    • libc.so
    • libdl.so
    • liblog.so
    • libm.so
    • libnativewindow.so
    • libneuralnetworks.so
    • libsync.so
    • libvndksupport.so
    • libvulkan.so
  • VNDK-SP
    • android.hardware.graphics.common@1.0.so
    • android.hardware.graphics.mapper@2.0.so
    • android.hardware.renderscript@1.0.so
    • android.hidl.memory@1.0.so
    • libRSCpuRef.so
    • libRSDriver.so
    • libRS_internal.so
    • libbase.so
    • libbcinfo.so
    • libc++.so
    • libcutils.so
    • libhardware.so
    • libhidlbase.so
    • libhidlmemory.so
    • libhidltransport.so
    • libhwbinder.so
    • libion.so
    • libutils.so
    • libz.so

Więcej szczegółów można znaleźć w /linkerconfig/ld.config.txt z urządzenia.

Konfiguracja VNDK Lite

Począwszy od systemu Android 8,0, dynamiczny konsolidator jest skonfigurowany do izolowania bibliotek udostępnionych SP-HAL i VNDK-SP, tak aby ich symbole nie były w konflikcie z innymi bibliotekami udostępnionymi platformy. Relacja między przestrzeniami nazw konsolidatora jest pokazana poniżej.

Wykres przestrzeni nazw linkera opisany w konfiguracji VNDK Lite
Rysunek 2. Izolacja przestrzeni nazw konsolidatora (konfiguracja VNDK Lite)

LL-NDK i VNDK-SP oznaczają następujące biblioteki współdzielone:

  • LL-NDK
    • libEGL.so
    • libGLESv1_CM.so
    • libGLESv2.so
    • libc.so
    • libdl.so
    • liblog.so
    • libm.so
    • libnativewindow.so
    • libstdc++.so (nie w konfiguracji)
    • libsync.so
    • libvndksupport.so
    • libz.so (przeniesiony do VNDK-SP w konfiguracji)
  • VNDK-SP
    • android.hardware.graphics.common@1.0.so
    • android.hardware.graphics.mapper@2.0.so
    • android.hardware.renderscript@1.0.so
    • android.hidl.memory@1.0.so
    • libbase.so
    • libc++.so
    • libcutils.so
    • libhardware.so
    • libhidlbase.so
    • libhidlmemory.so
    • libhidltransport.so
    • libhwbinder.so
    • libion.so
    • libutils.so

W poniższej tabeli wymieniono konfigurację przestrzeni nazw dla procesów struktury, która jest zaczerpnięta z sekcji [system] w konfiguracji VNDK Lite.

Przestrzeń nazw Nieruchomość Wartość
default search.paths /system/${LIB}
/odm/${LIB}
/vendor/${LIB}
/product/${LIB}
isolated false
sphal search.paths /odm/${LIB}
/vendor/${LIB}
permitted.paths /odm/${LIB}
/vendor/${LIB}
isolated true
visible true
links default,vndk,rs
link.default.shared_libs LL-NDK
link.vndk.shared_libs VNDK-SP
link.rs.shared_libs libRS_internal.so
vndk (dla VNDK-SP) search.paths /odm/${LIB}/vndk-sp
/vendor/${LIB}/vndk-sp
/system/${LIB}/vndk-sp-${VER}
permitted.paths /odm/${LIB}/hw
/odm/${LIB}/egl
/vendor/${LIB}/hw
/vendor/${LIB}/egl
/system/${LIB}/vndk-sp-${VER}/hw
isolated true
visible true
links default
link.default.shared_libs LL-NDK
rs (dla RenderScript) search.paths /odm/${LIB}/vndk-sp
/vendor/${LIB}/vndk-sp
/system/${LIB}/vndk-sp-${VER}
/odm/${LIB}
/vendor/${LIB}
permitted.paths /odm/${LIB}
/vendor/${LIB}
/data (dla skompilowanego jądra RS)
isolated true
visible true
links default,vndk
link.default.shared_libs LL-NDK
libmediandk.so
libft2.so
link.vndk.shared_libs VNDK-SP

Poniższa tabela przedstawia konfigurację przestrzeni nazw dla procesów dostawcy, która została zaczerpnięta z sekcji [vendor] w konfiguracji VNDK Lite.

Przestrzeń nazw Nieruchomość Wartość
default search.paths /odm/${LIB}
/odm/${LIB}/vndk
/odm/${LIB}/vndk-sp
/vendor/${LIB}
/vendor/${LIB}/vndk
/vendor/${LIB}/vndk-sp
/system/${LIB}/vndk-${VER}
/system/${LIB}/vndk-sp-${VER}
/system/${LIB} (przestarzałe)
/product/${LIB} (wycofane)
isolated false

Więcej szczegółów można znaleźć w /linkerconfig/ld.config.txt z urządzenia.

Historia dokumentu

Zmiany w Androidzie 11

  • W systemie Android 11 statyczne ld.config.*.txt są usuwane z bazy kodu, a LinkerConfig generuje je w środowisku uruchomieniowym.

Zmiany w Androidzie 9

  • W systemie Android 9 przestrzeń nazw konsolidatora vndk jest dodawana do procesów dostawcy, a biblioteki współdzielone VNDK są izolowane od domyślnej przestrzeni nazw konsolidatora.
  • Zastąp PRODUCT_FULL_TREBLE bardziej szczegółowymi PRODUCT_TREBLE_LINKER_NAMESPACES .
  • Android 9 zmienia nazwy następujących plików konfiguracyjnych dynamicznego konsolidatora.
    Android 8.x Android 9 Opis
    ld.config.txt.in ld.config.txt W przypadku urządzeń z izolacją przestrzeni nazw konsolidatora środowiska uruchomieniowego
    ld.config.txt ld.config.vndk_lite.txt W przypadku urządzeń z izolacją przestrzeni nazw konsolidatora VNDK-SP
    ld.config.legacy.txt ld.config.legacy.txt W przypadku starszych urządzeń z systemem Android 7.x lub starszym
  • Usuń android.hardware.graphics.allocator@2.0.so .
  • dodawane są partycje product i odm .