GKI 16-6.12 android-mainline errata

本页介绍了在 android-mainline 中发现的可能对合作伙伴很重要的重要问题和 bug 修复。

2024 年 11 月 1 日

  • Linux 6.12-rc4 着陆
    • 摘要:CONFIG_OF_DYNAMIC 可能会导致有缺陷的驱动程序出现严重回归问题。
    • 详细信息:在将 Linux 6.12-rc1 合并到 android-mainline 时,我们发现了外部驱动程序无法加载的问题。导致暴露驱动程序 bug 的更改被识别为提交 274aff8711b2 ("clk: Add KUnit tests for clks registered with struct clk_parent_data"),我们已在 aosp/3287735 中暂时还原了该更改。该更改会选择 CONFIG_OF_OVERLAY,后者会选择 CONFIG_OF_DYNAMIC。 使用 !OF_DYNAMIC 时,对 of_node_get()of_node_put() 的引用计数实际上会被停用,因为它们是作为 noops 实现的。再次启用 OF_DYNAMIC 会暴露驱动程序错误地为 struct device_node 实现引用计数的问题。这会导致各种类型的错误,例如内存损坏、释放后使用和内存泄漏。
    • 必须检查与 OF 解析相关的所有 API 用法。以下列表并非详尽无遗,但包含我们一直在观察到的情况:
      • 释放后再使用 (UAF):
        • 重复使用相同的 device_node 实参:这些函数会对给定节点调用 of_node_put(),可能需要在调用它们之前添加 of_node_get()(例如,在以相同节点作为实参重复调用时):
          • 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()
        • 在从某些循环退出后使用 device_node
          • for_each_available_child_of_node_scoped()
          • for_each_available_child_of_node()
          • for_each_child_of_node_scoped()
          • for_each_child_of_node()
        • 保留指向 device_node 中的 char * 属性的直接指针,例如使用以下方法:
          • const char *foo = struct device_node::name
          • of_property_read_string()
          • of_property_read_string_array()
          • of_property_read_string_index()
          • of_get_property()
      • 内存泄漏:
        • 获取 device_node 但忘记取消引用它 (of_node_put())。从以下位置返回的节点需要在某个时间点释放:
          • 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 进行循环迭代。如果您要从以下代码中返回或中断,则需要在某个时间点丢弃剩余的引用:
        • for_each_available_child_of_node()
        • for_each_child_of_node()
        • for_each_node_by_type()
        • for_each_compatible_node()
        • of_for_each_phandle()
    • 在发布 Linux 6.12-rc4 时,恢复了前面提到的更改(请参阅 aosp/3315251),再次启用了 CONFIG_OF_DYNAMIC,并可能会公开有故障的驱动程序。