Na tej stronie opisujemy ważne problemy i poprawki błędów znalezione w android-mainline
, które mogą być istotne dla partnerów.
15 listopada 2024 r.
Clang został zaktualizowany do wersji 19.0.1 w przypadku
android-mainline
iandroid16-6.12
- Podsumowanie: nowa wersja Clang wprowadza narzędzie do sprawdzania granic tablic, w którym rozmiar tablicy jest przechowywany w osobnej zmiennej połączonej z tablicą za pomocą atrybutu
__counted_by
. Ta funkcja może spowodować panikę jądra, jeśli rozmiar tablicy nie zostanie prawidłowo zaktualizowany. Komunikat o błędzie wygląda tak:
UBSAN: array-index-out-of-bounds in common/net/wireless/nl80211.c index 0 is out of range for type 'struct ieee80211_channel *[] __counted_by(n_channels)' (aka 'struct ieee80211_channel *[]')
Szczegóły: narzędzie do sprawdzania granic jest niezbędne do ochrony integralności jądra przez wykrywanie dostępu poza zakresem. Gdy ta opcja jest
CONFIG_UBSAN_TRAP
włączona,CONFIG_UBSAN_TRAP
narzędzie do sprawdzania granic wywołuje panikę jądra przy każdym wykryciu problemu.- Poprzednia wersja narzędzia do sprawdzania granic sprawdzała tylko tablice o stałym rozmiarze i nie mogła sprawdzać tablic przydzielanych dynamicznie. Nowa wersja używa atrybutu
__counted_by
do określania granic tablicy w czasie działania programu i wykrywania większej liczby przypadków dostępu poza zakresem. W niektórych przypadkach jednak dostęp do tablicy następuje przed ustawieniem zmiennej rozmiaru, co powoduje uruchomienie narzędzia do czyszczenia granic i błąd krytyczny jądra. Aby rozwiązać ten problem, ustaw rozmiar tablicy natychmiast po przydzieleniu pamięci bazowej, jak pokazano w aosp/3343204.
- Poprzednia wersja narzędzia do sprawdzania granic sprawdzała tylko tablice o stałym rozmiarze i nie mogła sprawdzać tablic przydzielanych dynamicznie. Nowa wersja używa atrybutu
Informacje o
CONFIG_UBSAN_SIGNED_WRAP
: nowa wersja Clang czyści przepełnienie i niedopełnienie liczb całkowitych ze znakiem pomimo flagi kompilatora-fwrapv
. Flaga-fwrapv
ma traktować liczby całkowite ze znakiem jako liczby całkowite bez znaku w systemie uzupełnień do dwóch z określonym zachowaniem w przypadku przepełnienia.- Chociaż oczyszczanie przepełnienia liczb całkowitych ze znakiem w jądrze systemu Linux może pomóc w identyfikowaniu błędów, w niektórych przypadkach przepełnienie jest celowe, np. w przypadku
atomic_long_t
. W związku z tymCONFIG_UBSAN_SIGNED_WRAP
zostało wyłączone aby umożliwić UBSAN działanie wyłącznie jako narzędzie do sprawdzania granic.
- Chociaż oczyszczanie przepełnienia liczb całkowitych ze znakiem w jądrze systemu Linux może pomóc w identyfikowaniu błędów, w niektórych przypadkach przepełnienie jest celowe, np. w przypadku
Informacje o
CONFIG_UBSAN_TRAP
: UBSAN jest skonfigurowany tak, aby w przypadku wykrycia problemu wywoływać panikę jądra, co ma na celu ochronę integralności jądra. Wyłączyliśmy jednak to działanie w okresie od 23 października do 12 listopada. Zrobiliśmy to, aby odblokować aktualizację kompilatora, podczas gdy rozwiązywaliśmy znane problemy__counted_by
.
- Podsumowanie: nowa wersja Clang wprowadza narzędzie do sprawdzania granic tablic, w którym rozmiar tablicy jest przechowywany w osobnej zmiennej połączonej z tablicą za pomocą atrybutu
1 listopada 2024 roku
- Linux 6.12-rc4 landing
- Podsumowanie:
CONFIG_OF_DYNAMIC
może powodować poważne regresje w przypadku wadliwych sterowników. - Szczegóły: podczas scalania systemu Linux
6.12-rc1
zandroid-mainline
zauważyliśmy problemy z wczytywaniem sterowników zewnętrznych. Zmiana, która ujawniła błędy sterownika, została zidentyfikowana jako commit274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data")
i tymczasowo wycofana w aosp/3287735. Zmiana powoduje wybranie opcjiCONFIG_OF_OVERLAY
, która wybiera opcjęCONFIG_OF_DYNAMIC
. W przypadku!OF_DYNAMIC
zliczanie odwołań w przypadkuof_node_get()
iof_node_put()
jest skutecznie wyłączone, ponieważ są one implementowane jakonoops
. Ponowne włączenieOF_DYNAMIC
ujawnia problemy ze sterownikami, które nieprawidłowo implementują zliczanie odwołań dlastruct device_node
. Powoduje to różne rodzaje błędów, takie jak uszkodzenie pamięci, odwołanie do pamięci po jej zwolnieniu i wycieki pamięci. - Wszystkie zastosowania interfejsów API związanych z analizowaniem OF muszą być sprawdzane. Poniższa lista jest niepełna, ale zawiera przypadki, które obserwujemy:
- Użycie po bezpłatnym okresie próbnym:
- Ponowne użycie tego samego argumentu
device_node
: te funkcje wywołująof_node_put()
w danym węźle. Przed ich wywołaniem może być konieczne dodanieof_node_get()
(np. w przypadku wielokrotnego wywoływania z tym samym węzłem jako argumentem):of_find_compatible_node()
of_find_node_by_name()
of_find_node_by_path()
of_find_node_by_type()
of_get_next_cpu_node()
of_get_next_parent()
of_get_next_child()
of_get_next_available_child()
of_get_next_reserved_child()
of_find_node_with_property()
of_find_matching_node_and_match()
- Użycie
device_node
po dowolnym typie wyjścia z określonych pętli:for_each_available_child_of_node_scoped()
for_each_available_child_of_node()
for_each_child_of_node_scoped()
for_each_child_of_node()
- Zachowywanie bezpośrednich wskaźników do właściwości
char *
zdevice_node
, na przykład za pomocą tego kodu:const char *foo = struct device_node::name
of_property_read_string()
of_property_read_string_array()
of_property_read_string_index()
of_get_property()
- Ponowne użycie tego samego argumentu
- Wycieki pamięci:
- Uzyskanie
device_node
i zapomnienie o zwolnieniu pamięci (of_node_put()
). Węzły zwrócone z tych funkcji muszą zostać w pewnym momencie zwolnione:of_find_compatible_node()
of_find_node_by_name()
of_find_node_by_path()
of_find_node_by_type()
of_find_node_by_phandle()
of_parse_phandle()
of_find_node_opts_by_path()
of_get_next_cpu_node()
of_get_compatible_child()
of_get_child_by_name()
of_get_parent()
of_get_next_parent()
of_get_next_child()
of_get_next_available_child()
of_get_next_reserved_child()
of_find_node_with_property()
of_find_matching_node_and_match()
- Uzyskanie
- Zachowywanie
device_node
z iteracji pętli. Jeśli wracasz lub przerywasz działanie w ramach poniższych instrukcji, musisz w pewnym momencie usunąć pozostałe odwołanie:for_each_available_child_of_node()
for_each_child_of_node()
for_each_node_by_type()
for_each_compatible_node()
of_for_each_phandle()
- Użycie po bezpłatnym okresie próbnym:
- Wspomniana wcześniej zmiana została przywrócona podczas wdrażania Linuksa
6.12-rc4
(patrz aosp/3315251), co ponownie włączaCONFIG_OF_DYNAMIC
i może ujawnić wadliwe sterowniki.
- Podsumowanie: