En esta página, se describen los problemas importantes y las correcciones de errores que se encontraron en android-mainline y que podrían ser significativos para los socios.
15 de noviembre de 2024
Se actualizó Clang a la versión 19.0.1 para
android-mainlineyandroid16-6.12- Resumen: La nueva versión de Clang introduce un verificador de límites para los arrays, en el que el tamaño del array se almacena en una variable independiente vinculada al array 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 sanitizador de límites es esencial para proteger la integridad del kernel, ya que detecta los accesos fuera de los límites. Además, con
CONFIG_UBSAN_TRAPhabilitado, el sanitizador de límites activa un error de kernel ante cualquier hallazgo.- La versión anterior del verificador 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_bypara 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 filtro de límites y provoca un error grave del kernel. Para solucionar 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 verificador 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 corrige el desbordamiento y el subdesbordamiento de números enteros firmados a pesar de la marca-fwrapvdel compilador. La marca-fwrapvestá diseñada para tratar los números enteros con signo como números enteros sin signo de complemento a dos con un comportamiento de desbordamiento definido.- Si bien la sanitización del desbordamiento de números enteros con signo 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_WRAPse inhabilitó para permitir que UBSAN funcione únicamente como un verificador de límites.
- Si bien la sanitización del desbordamiento de números enteros con signo 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 del 23 de octubre al 12 de noviembre. Hicimos esto para desbloquear la actualización del compilador mientras corregíamos los problemas conocidos de__counted_by.
- Resumen: La nueva versión de Clang introduce un verificador de límites para los arrays, en el que el tamaño del array se almacena en una variable independiente vinculada al array con el atributo
1 de noviembre de 2024
- Lanzamiento de Linux 6.12-rc4
- Resumen:
CONFIG_OF_DYNAMICpodría causar regresiones graves para los controladores defectuosos. - Detalles: Mientras fusionábamos Linux
6.12-rc1enandroid-mainline, notamos problemas con los controladores externos que no se cargaban. El cambio que expuso los errores del controlador se identificó como la confirmación274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data")y lo revertimos 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. HabilitarOF_DYNAMICnuevamente expone problemas en los controladores que implementan incorrectamente el recuento de referencias parastruct device_node. Esto provoca varios tipos de errores, como corrupción de memoria, uso después de liberar y pérdidas 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 los 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 proporcionado, por lo que es posible que deban agregar unof_node_get()antes de llamarlas (por ejemplo, cuando se llama repetidamente 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_nodedespué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 de
char *desdedevice_node, por ejemplo, con lo siguiente:const char *foo = struct device_node::nameof_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_nodey olvidarse de quitarle la 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_nodede una iteración de bucle Si regresas o interrumpes la ejecución dentro de lo siguiente, debes descartar 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):
- El cambio mencionado anteriormente se restableció mientras se incorporaba Linux
6.12-rc4(consulta aosp/3315251), lo que habilitóCONFIG_OF_DYNAMICnuevamente y, posiblemente, expuso controladores defectuosos.
- Resumen: