En esta página, se describen los problemas importantes y las correcciones de errores que se encontraron en android-mainline
que podrían ser significativos para los socios.
15 de noviembre de 2024
Clang se actualizó a la versión 19.0.1 para
android-mainline
yandroid16-6.12
- Resumen: La nueva versión de Clang presenta un validador de límites para los arreglos, en el que el tamaño del arreglo se almacena en una variable independiente vinculada al arreglo con el atributo
__counted_by
. Esta función puede causar un error irrecuperable del kernel si el tamaño del array no se actualiza correctamente. El mensaje de error se ve de la siguiente manera:
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 *[]')
Detalles: El validador de límites es esencial para proteger la integridad del kernel, ya que detecta el acceso fuera de los límites. Además, con
CONFIG_UBSAN_TRAP
habilitado, el validador de límites activa un pánico del kernel en cualquier hallazgo.- La versión anterior del validador de límites solo verificaba arrays de tamaño fijo y no podía verificar arrays asignados de forma dinámica. La nueva versión usa el atributo
__counted_by
para determinar los límites del array en el tiempo de ejecución y detectar más casos de acceso fuera de los límites. Sin embargo, en algunos casos, se accede al array antes de que se establezca la variable de tamaño, lo que activa el validador de límites y causa un pánico del kernel. Para abordar este problema, establece el tamaño del array inmediatamente después de asignar la memoria subyacente, como se ilustra en aosp/3343204.
- La versión anterior del validador de límites solo verificaba arrays de tamaño fijo y no podía verificar arrays asignados de forma dinámica. La nueva versión usa el atributo
Acerca de
CONFIG_UBSAN_SIGNED_WRAP
: La nueva versión de Clang limpia el desbordamiento y el desbordamiento de números enteros firmados a pesar de la marca del compilador-fwrapv
. La marca-fwrapv
está diseñada para tratar números enteros con signo como números enteros sin signo de complemento de dos con comportamiento de desbordamiento definido.- Si bien la limpieza del desbordamiento de números enteros firmados en el kernel de Linux puede ayudar a identificar errores, hay casos en los que el desbordamiento es intencional, por ejemplo, con
atomic_long_t
. Como resultado,CONFIG_UBSAN_SIGNED_WRAP
se inhabilitó para permitir que UBSAN funcione únicamente como un validador de límites.
- Si bien la limpieza del desbordamiento de números enteros firmados en el kernel de Linux puede ayudar a identificar errores, hay casos en los que el desbordamiento es intencional, por ejemplo, con
Acerca de
CONFIG_UBSAN_TRAP
: UBSAN está configurado para activar un error irrecuperable del kernel cuando detecta un problema para proteger la integridad del kernel. Sin embargo, inhabilitamos este comportamiento desde el 23 de octubre hasta el 12 de noviembre. Hicimos esto para desbloquear la actualización del compilador mientras solucionábamos los problemas conocidos de__counted_by
.
- Resumen: La nueva versión de Clang presenta un validador de límites para los arreglos, en el que el tamaño del arreglo se almacena en una variable independiente vinculada al arreglo con el atributo
1 de noviembre de 2024
- Lanzamiento de Linux 6.12-rc4
- Resumen:
CONFIG_OF_DYNAMIC
puede causar regresiones graves en los controladores defectuosos. - Detalles: Mientras se fusionaba
6.12-rc1
de Linux enandroid-mainline
, se observaron problemas con los controladores fuera del árbol que no se cargaban. El cambio que expuso los errores del controlador se identificó como confirmación274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data")
y lo revirtieron temporalmente en aosp/3287735. El cambio seleccionaCONFIG_OF_OVERLAY
, que seleccionaCONFIG_OF_DYNAMIC
. Con!OF_DYNAMIC
, el recuento de referencias enof_node_get()
yof_node_put()
se inhabilita de manera efectiva, ya que se implementan comonoops
. Si se habilitaOF_DYNAMIC
, nuevamente se exponen problemas en los controladores que implementan incorrectamente el recuento de referencias parastruct device_node
. Esto causa varios tipos de errores, como daños en la memoria, uso después de liberar y fugas de memoria. - Se deben inspeccionar todos los usos de las APIs relacionadas con el análisis de OF. La siguiente lista es parcial, pero contiene casos que hemos observado:
- Uso tras la liberación (UAF):
- Reutilización del mismo argumento
device_node
: Esas funciones llaman aof_node_put()
en el nodo determinado y, posiblemente, deban agregar unof_node_get()
antes de llamarlas (por ejemplo, cuando se llama de forma reiterada con el mismo nodo como argumento):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()
- Uso de
device_node
después de cualquier tipo de salida de ciertos bucles:for_each_available_child_of_node_scoped()
for_each_available_child_of_node()
for_each_child_of_node_scoped()
for_each_child_of_node()
- Mantener punteros directos a las propiedades
char *
dedevice_node
, por ejemplo, con lo siguiente:const char *foo = struct device_node::name
of_property_read_string()
of_property_read_string_array()
of_property_read_string_index()
of_get_property()
- Reutilización del mismo argumento
- Fugas de memoria:
- Obtener un
device_node
y olvidarse de anular su referencia (of_node_put()
). Los nodos que se devuelven de estos deben liberarse en algún momento: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()
- Obtener un
- Mantener un
device_node
de una iteración de bucle Si regresas o haces una pausa desde lo siguiente, debes soltar la referencia restante en algún momento:for_each_available_child_of_node()
for_each_child_of_node()
for_each_node_by_type()
for_each_compatible_node()
of_for_each_phandle()
- Uso tras la liberación (UAF):
- Se restableció el cambio mencionado anteriormente cuando se implementó Linux
6.12-rc4
(consulta aosp/3315251), lo que volvió a habilitarCONFIG_OF_DYNAMIC
y, potencialmente, expuso controladores defectuosos.
- Resumen: