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-mainlineiandroid16-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ć kernel panic, 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 granice. Gdy włączona jest opcja
CONFIG_UBSAN_TRAP, narzędzie do sprawdzania granic powoduje kernel panic w przypadku wykrycia jakiegokolwiek 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_bydo określania granic tablicy w czasie działania i wykrywania większej liczby przypadków dostępu poza granice. W niektórych przypadkach jednak dostęp do tablicy następuje przed ustawieniem zmiennej rozmiaru, co powoduje uruchomienie narzędzia do sprawdzania granic i kernel panic. 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 sprawdza przepełnienie i niedopełnienie liczb całkowitych ze znakiem pomimo flagi kompilatora-fwrapv. Flaga-fwrapvjest przeznaczona do traktowania liczb całkowitych ze znakiem jako liczb całkowitych bez znaku w systemie uzupełnień do dwóch z określonym zachowaniem w przypadku przepełnienia.- Chociaż sprawdzanie przepełnienia liczb całkowitych ze znakiem w jądrze systemu Linux może pomóc w identyfikowaniu błędów, istnieją przypadki, w których przepełnienie jest zamierzone, np. w przypadku
atomic_long_t. W związku z tym opcjaCONFIG_UBSAN_SIGNED_WRAPzostała wyłączona, aby UBSAN działał wyłącznie jako narzędzie do sprawdzania granic.
- Chociaż sprawdzanie przepełnienia liczb całkowitych ze znakiem w jądrze systemu Linux może pomóc w identyfikowaniu błędów, istnieją przypadki, w których przepełnienie jest zamierzone, np. w przypadku
Informacje o
CONFIG_UBSAN_TRAP: UBSAN jest skonfigurowany tak, aby w przypadku wykrycia problemu powodować kernel panic w celu ochrony integralności jądra. Od 23 października do 12 listopadawyłączyliśmy jednak to zachowanie. Zrobiliśmy to, aby odblokować aktualizację kompilatora, gdy naprawialiśmy znane problemy z__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 r.
- Wprowadzenie Linuksa 6.12-rc4
- Podsumowanie:
CONFIG_OF_DYNAMICmoże powodować poważne regresje w przypadku wadliwych sterowników. - Szczegóły: podczas scalania Linuksa
6.12-rc1zandroid-mainlinezauważyliśmy problemy z wczytywaniem sterowników spoza drzewa. Zmiana, która ujawniła błędy sterownika, została zidentyfikowana jako zatwierdzenie274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data"), a my tymczasowo cofnęliśmy ją w aosp/3287735. Zmiana wybieraCONFIG_OF_OVERLAY, która wybieraCONFIG_OF_DYNAMIC. W przypadku!OF_DYNAMICzliczanie odwołań wof_node_get()iof_node_put()jest skutecznie wyłączone, ponieważ są one zaimplementowane jakonoops. Ponowne włączenieOF_DYNAMICujawnia problemy w sterownikach, które nieprawidłowo implementują zliczanie odwołań dlastruct device_node. Powoduje to różne typy błędów, takie jak uszkodzenie pamięci, odwołanie do pamięci po jej zwolnieniu i wycieki pamięci. - Należy sprawdzić wszystkie użycia interfejsów API związanych z analizowaniem OF. Poniższa lista jest niepełna, ale zawiera przypadki, które zaobserwowaliśmy:
- Odwołanie do pamięci po jej zwolnieniu:
- Ponowne użycie tego samego argumentu
device_node: te funkcje wywołująof_node_put()w danym węźle, co może wymagać dodaniaof_node_get()przed ich wywołaniem (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_nodepo dowolnym typie wyjścia z niektórych 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, np. za pomocą:const char *foo = struct device_node::nameof_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:
- Pobieranie
device_nodei zapominanie o jego zwolnieniu (of_node_put()). Węzły zwracane przez te węzły 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()
- Pobieranie
- Zachowywanie
device_nodez iteracji pętli. Jeśli wracasz lub przerywasz działanie w tych pętlach, 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()
- Odwołanie do pamięci po jej zwolnieniu:
- Wcześniej wspomniana zmiana została przywrócona podczas wprowadzania Linuksa
6.12-rc4(patrz aosp/3315251) co ponownie włączaCONFIG_OF_DYNAMICi może ujawnić wadliwe sterowniki.
- Podsumowanie: