自 2025 年 3 月 27 日起,我们建议您使用 android-latest-release
而非 aosp-main
构建 AOSP 并为其做出贡献。如需了解详情,请参阅 AOSP 的变更。
GKI 16-6.12 android-mainline errata
使用集合让一切井井有条
根据您的偏好保存内容并对其进行分类。
本页介绍了在 android-mainline
中发现的可能对合作伙伴来说非常关键的重要问题和 bug 修复。
2024 年 11 月 15 日
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
,这可能会导致驱动程序出现问题。
本页面上的内容和代码示例受内容许可部分所述许可的限制。Java 和 OpenJDK 是 Oracle 和/或其关联公司的注册商标。
最后更新时间 (UTC):2025-03-26。
[null,null,["最后更新时间 (UTC):2025-03-26。"],[],[],null,["# GKI 16-6.12 android-mainline errata\n\nThis page describes important issues and bug fixes found on `android-mainline`\nthat might be significant to partners.\n\nNovember 15, 2024\n-----------------\n\n- **Clang is updated to 19.0.1 for `android-mainline` and `android16-6.12`**\n\n - Summary: The new version of Clang introduces a bounds sanitizer for arrays, where the array's size is stored in a separate variable linked to the array using the `__counted_by` attribute. This feature might cause a kernel panic if the array size isn't properly updated. The error message looks like this:\n\n UBSAN: array-index-out-of-bounds in common/net/wireless/nl80211.c\n index 0 is out of range for type 'struct ieee80211_channel *[] __counted_by(n_channels)' (aka 'struct ieee80211_channel *[]')\n\n - Details: The bounds sanitizer is essential to protect the integrity of the\n kernel by detecting out-of-bounds access. And with `CONFIG_UBSAN_TRAP`\n enabled, bounds sanitizer triggers a kernel panic on any finding.\n\n - Previous version of the bounds sanitizer checked only fixed-size arrays and couldn't check dynamically allocated arrays. The new version uses the `__counted_by` attribute to determine the array bounds at runtime and detect more cases of out-of-bound access. However, in some cases, the array is accessed before the size variable is set, triggering the bounds sanitizer and causing a kernel panic. To address this issue, set the array's size immediately after allocating the underlying memory, as illustrated in [aosp/3343204](https://android-review.googlesource.com/c/kernel/common/+/3343204).\n - About `CONFIG_UBSAN_SIGNED_WRAP`: The new version of Clang sanitizes signed\n integer overflow and underflow despite the `-fwrapv` compiler flag. The\n `-fwrapv` flag is designed to treat signed integers as two's complement\n unsigned integers with defined overflow behavior.\n\n - While sanitizing signed integer overflow in the Linux kernel can help identify bugs, there are instances where overflow is intentional, for example, with `atomic_long_t`. As a result, `CONFIG_UBSAN_SIGNED_WRAP` [has been disabled](https://android-review.googlesource.com/c/kernel/common/+/3343205) to allow UBSAN to function solely as a bounds sanitizer.\n - About `CONFIG_UBSAN_TRAP`: UBSAN is configured to trigger a kernel panic\n when it detects an issue to protect the integrity of the kernel.\n However, we disabled this behavior from\n [October 23](https://android-review.googlesource.com/c/kernel/common/+/3315125)\n to\n [November 12](https://android-review.googlesource.com/c/kernel/common/+/3318796).\n We did this to unblock the compiler update while we fixed known `__counted_by`\n issues.\n\nNovember 1, 2024\n----------------\n\n- **Linux 6.12-rc4 landing**\n - Summary: `CONFIG_OF_DYNAMIC` potentially causing severe regressions for faulty drivers.\n - The details: While merging Linux `6.12-rc1` into `android-mainline` we noticed issues with out-of-tree drivers failing to load. The change that exposed the driver bugs was identified as commit `274aff8711b2 (\"clk: Add\n KUnit tests for clks registered with struct clk_parent_data\")` and we temporarily reverted it in [aosp/3287735](https://android-review.googlesource.com/c/kernel/common/+/3287735). The change selects `CONFIG_OF_OVERLAY`, which selects `CONFIG_OF_DYNAMIC`. With `!OF_DYNAMIC`, ref-counting on `of_node_get()` and `of_node_put()` is effectively disabled as they are implemented as `noops`. Enabling `OF_DYNAMIC` again exposes issues in drivers wrongly implementing ref-counting for `struct device_node`. This causes various types of errors like memory corruption, use-after-free, and memory leaks.\n - All uses of OF parsing related APIs must be inspected. The following list is partial, but contains cases we have been observing:\n - Use after free (UAF):\n - Reuse of the same `device_node` argument: Those functions call `of_node_put()` on the node given, potentially need to add an `of_node_get()` before calling them (for example, when calling repeatedly with the same node as argument):\n - `of_find_compatible_node()`\n - `of_find_node_by_name()`\n - `of_find_node_by_path()`\n - `of_find_node_by_type()`\n - `of_get_next_cpu_node()`\n - `of_get_next_parent()`\n - `of_get_next_child()`\n - `of_get_next_available_child()`\n - `of_get_next_reserved_child()`\n - `of_find_node_with_property()`\n - `of_find_matching_node_and_match()`\n - Use of `device_node` after any type of exit from certain loops:\n - `for_each_available_child_of_node_scoped()`\n - `for_each_available_child_of_node()`\n - `for_each_child_of_node_scoped()`\n - `for_each_child_of_node()`\n - Keeping direct pointers to `char *` properties from `device_node` around, for example, using:\n - `const char *foo = struct device_node::name`\n - `of_property_read_string()`\n - `of_property_read_string_array()`\n - `of_property_read_string_index()`\n - `of_get_property()`\n - Memory leaks:\n - Getting a `device_node` and forgetting to unref it (`of_node_put()`). Nodes returned from these need to be freed at some point:\n - `of_find_compatible_node()`\n - `of_find_node_by_name()`\n - `of_find_node_by_path()`\n - `of_find_node_by_type()`\n - `of_find_node_by_phandle()`\n - `of_parse_phandle()`\n - `of_find_node_opts_by_path()`\n - `of_get_next_cpu_node()`\n - `of_get_compatible_child()`\n - `of_get_child_by_name()`\n - `of_get_parent()`\n - `of_get_next_parent()`\n - `of_get_next_child()`\n - `of_get_next_available_child()`\n - `of_get_next_reserved_child()`\n - `of_find_node_with_property()`\n - `of_find_matching_node_and_match()`\n - Keeping a `device_node` from a loop iteration. If you're returning or breaking from within the following, you need to drop the remaining reference at some point:\n - `for_each_available_child_of_node()`\n - `for_each_child_of_node()`\n - `for_each_node_by_type()`\n - `for_each_compatible_node()`\n - `of_for_each_phandle()`\n - The earlier mentioned change was restored while landing Linux `6.12-rc4` (see [aosp/3315251](https://android-review.googlesource.com/c/kernel/common/+/3315251)) enabling `CONFIG_OF_DYNAMIC` again and potentially exposing faulty drivers."]]