GKI 16-6.12 android-mainline errata

Esta página descreve problemas importantes e correções de bugs encontradas no android-mainline que podem ser significativas para os parceiros.

1º de novembro de 2024

  • Página de destino do Linux 6.12-rc4
    • Resumo: CONFIG_OF_DYNAMIC pode causar regressões graves para drivers com falhas.
    • Detalhes: ao mesclar o Linux 6.12-rc1 com o android-mainline, notamos problemas com drivers fora da árvore que não carregavam. A mudança que expôs os bugs do driver foi identificada como confirmação 274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data") e revertemos temporariamente em aosp/3287735 (link em inglês). A mudança seleciona CONFIG_OF_OVERLAY, que seleciona CONFIG_OF_DYNAMIC. Com !OF_DYNAMIC, a contagem de referência em of_node_get() e of_node_put() é desativada, porque elas são implementadas como noops. A ativação de OF_DYNAMIC expõe novamente problemas em drivers que implementam incorretamente a contagem de referências para struct device_node. Isso causa vários tipos de erro, como corrupção de memória, uso após a liberação e vazamentos de memória.
    • Todos os usos de APIs relacionadas à análise do OF precisam ser inspecionados. A lista a seguir é parcial, mas contém casos que observamos:
      • Use After Free (UAF):
        • Reutilização do mesmo argumento device_node: essas funções chamam of_node_put() no nó fornecido, possivelmente precisam adicionar um of_node_get() antes de serem chamadas (por exemplo, quando chamadas repetidamente com o mesmo nó 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 após qualquer tipo de saída de determinados loops:
          • for_each_available_child_of_node_scoped()
          • for_each_available_child_of_node()
          • for_each_child_of_node_scoped()
          • for_each_child_of_node()
        • Manter ponteiros diretos para as propriedades char * de device_node, por exemplo, usando:
          • const char *foo = struct device_node::name
          • of_property_read_string()
          • of_property_read_string_array()
          • of_property_read_string_index()
          • of_get_property()
      • Vazamentos de memória:
        • Receber um device_node e esquecer de remover a referência (of_node_put()). Os nós retornados precisam ser liberados em algum 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()
      • Manter um device_node de uma iteração de loop. Se você retornar ou interromper o seguinte, precisará excluir a referência restante em algum 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()
    • A mudança mencionada anteriormente foi restaurada ao iniciar a 6.12-rc4 do Linux (consulte aosp/3315251, link em inglês), ativando o CONFIG_OF_DYNAMIC novamente e possivelmente expondo os drivers defeituosos.