Auf dieser Seite werden wichtige Probleme und Fehlerkorrekturen beschrieben, die bei android-mainline
gefunden wurden und für Partner von Bedeutung sein könnten.
15. November 2024
Clang wurde für
android-mainline
undandroid16-6.12
auf Version 19.0.1 aktualisiert.- Zusammenfassung: Die neue Version von Clang führt einen Grenzwert-Sanitizer für Arrays ein, bei dem die Größe des Arrays in einer separaten Variablen gespeichert wird, die über das Attribut
__counted_by
mit dem Array verknüpft ist. Diese Funktion kann zu einer Kernel-Panik führen, wenn die Arraygröße nicht richtig aktualisiert wird. Die Fehlermeldung sieht so aus:
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 *[]')
Details: Der Bounds Sanitizer ist wichtig, um die Integrität des Kernels zu schützen, indem er Zugriffe außerhalb des zulässigen Bereichs erkennt. Wenn
CONFIG_UBSAN_TRAP
aktiviert ist, löst der Bounds Sanitizer bei jeder gefundenen Abweichung einen Kernel-Panik aus.- Die vorherige Version des Grenzwert-Sanitizers überprüfte nur Arrays mit fester Größe und konnte dynamisch zugewiesene Arrays nicht prüfen. In der neuen Version wird das Attribut
__counted_by
verwendet, um die Arraygrenzen zur Laufzeit zu ermitteln und mehr Fälle von Zugriffen außerhalb des Gültigkeitsbereichs zu erkennen. In einigen Fällen wird jedoch auf das Array zugegriffen, bevor die Variable „size“ festgelegt wurde. Dies löst den Grenzwert-Sanitizer aus und führt zu einer Kernel-Panik. Legen Sie die Größe des Arrays direkt nach der Zuweisung des zugrunde liegenden Arbeitsspeichers fest, wie in aosp/3343204 dargestellt.
- Die vorherige Version des Grenzwert-Sanitizers überprüfte nur Arrays mit fester Größe und konnte dynamisch zugewiesene Arrays nicht prüfen. In der neuen Version wird das Attribut
CONFIG_UBSAN_SIGNED_WRAP
: Die neue Version von Clang behebt trotz des Compiler-Flags-fwrapv
Über- und Unterlauf von signed integer. Das Flag-fwrapv
ist so konzipiert, dass vorzeichenbehaftete Ganzzahlen als vorzeichenlose Ganzzahlen im Zweierkomplement mit definiertem Overflow-Verhalten behandelt werden.- Das Entfernen von Überläufen bei signed integer im Linux-Kernel kann zwar dazu beitragen, Fehler zu identifizieren, es gibt aber Fälle, in denen ein Überlauf beabsichtigt ist, z. B. bei
atomic_long_t
. Daher wurdeCONFIG_UBSAN_SIGNED_WRAP
deaktiviert, damit UBSAN nur als Grenzwert-Sanitizer verwendet werden kann.
- Das Entfernen von Überläufen bei signed integer im Linux-Kernel kann zwar dazu beitragen, Fehler zu identifizieren, es gibt aber Fälle, in denen ein Überlauf beabsichtigt ist, z. B. bei
CONFIG_UBSAN_TRAP
: UBSAN ist so konfiguriert, dass ein Kernel-Panic ausgelöst wird, wenn ein Problem erkannt wird, um die Integrität des Kernels zu schützen. Dieses Verhalten wurde jedoch vom 23. Oktober bis zum 12. November deaktiviert. Dadurch konnten wir das Compiler-Update freischalten, während wir bekannte__counted_by
-Probleme behoben haben.
- Zusammenfassung: Die neue Version von Clang führt einen Grenzwert-Sanitizer für Arrays ein, bei dem die Größe des Arrays in einer separaten Variablen gespeichert wird, die über das Attribut
1. November 2024
- Linux 6.12-rc4 veröffentlicht
- Zusammenfassung:
CONFIG_OF_DYNAMIC
kann bei fehlerhaften Treibern zu schwerwiegenden Rückschritten führen. - Details: Beim Zusammenführen von Linux
6.12-rc1
mitandroid-mainline
haben wir Probleme festgestellt, bei denen nicht im Stamm enthaltene Treiber nicht geladen werden konnten. Die Änderung, die die Treiberfehler aufgedeckt hat, wurde als Commit274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data")
identifiziert und wir haben sie vorübergehend in aosp/3287735 rückgängig gemacht. Durch die Änderung wirdCONFIG_OF_OVERLAY
ausgewählt, wodurchCONFIG_OF_DYNAMIC
ausgewählt wird. Mit!OF_DYNAMIC
ist die Referenzzählung fürof_node_get()
undof_node_put()
effektiv deaktiviert, da sie alsnoops
implementiert sind. WennOF_DYNAMIC
wieder aktiviert wird, treten Probleme in Treibern auf, die die Referenzzählung fürstruct device_node
falsch implementieren. Dies führt zu verschiedenen Arten von Fehlern wie Speicherbeschädigung, Use-After-Free und Speicherlecks. - Alle Verwendungen von APIs zum Parsen von OF-Dateien müssen geprüft werden. Die folgende Liste ist unvollständig, enthält aber Fälle, die wir beobachtet haben:
- Use after free (UAF):
- Wiederverwendung desselben
device_node
-Arguments: Diese Funktionen rufenof_node_put()
auf dem angegebenen Knoten auf und müssen vor dem Aufruf möglicherweise eineof_node_get()
hinzufügen (z. B. bei wiederholtem Aufruf mit demselben Knoten als Argument):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()
- Verwendung von
device_node
nach jeder Art von Beendigung bestimmter Schleifen:for_each_available_child_of_node_scoped()
for_each_available_child_of_node()
for_each_child_of_node_scoped()
for_each_child_of_node()
- Direkte Verweise auf
char *
-Properties ausdevice_node
beibehalten, z. B. mit:const char *foo = struct device_node::name
of_property_read_string()
of_property_read_string_array()
of_property_read_string_index()
of_get_property()
- Wiederverwendung desselben
- Speicherlecks:
device_node
abrufen und vergessen, die Referenz aufzuheben (of_node_put()
). Die von diesen zurückgegebenen Knoten müssen irgendwann freigegeben werden: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()
device_node
aus einer Schleifeniteration beibehalten Wenn Sie von einem der folgenden Elemente aus zurückkehren oder eine Unterbrechung einfügen, müssen Sie die verbleibende Referenz irgendwann löschen:for_each_available_child_of_node()
for_each_child_of_node()
for_each_node_by_type()
for_each_compatible_node()
of_for_each_phandle()
- Use after free (UAF):
- Die oben erwähnte Änderung wurde beim Einspielen von Linux
6.12-rc4
(siehe aosp/3315251) wiederhergestellt, wodurchCONFIG_OF_DYNAMIC
wieder aktiviert wurde und möglicherweise fehlerhafte Treiber auftraten.
- Zusammenfassung: