0/2 已展开

LLM 分析

Linux 6.18.47 stable 公告分析

系列概况

字段内容
主题Linux 6.18.47 稳定版发布公告
作者Greg Kroah-Hartman(gregkh)
版本6.18.47(SUBLEVEL 由 46 → 47)
性质stable 维护点版本(point release),不是 RFC 也不是新特性系列
规模多驱动/子系统的 bugfix 集合;可见 hunks:Makefiledrivers/block/null_blk/zoned.cdrivers/bluetooth/hci_aml.c
Message-ID2026082713-escalate-oval-540f@gregkh2026082713-uncover-devotion-6767@gregkh
完整性公告正文与示例 patch 都已给出

补丁目的

6.18.47 是 6.18 系列的最新稳定点版本,Greg KH 提醒所有 6.18 用户必须升级。它合并了一批回溯到 stable 分支的修复,主要目的:

  • 修复 null_blk 在 zone 配置异常时可能除零或参数校验不严的 bug;
  • 修复 hci_aml 蓝牙驱动固件加载路径上对 firmware->size 的越界访问隐患;
  • 同时收尾大量其他子系统(NVMe target、HID、IOMMU、SMMU、net/nfc/dma 等)的回归/正确性补丁。

旧流程的问题

  • null_blkmb_to_sects() 中直接使用 dev->zone_size_sects,如果用户传入过大或非法 zone_size,位移结果可能为 0,后续 do_div 等运算存在除零风险;并且原校验只判断 is_power_of_2,忽略了 zone_size == 0 的边界。
  • hci_amlaml_download_firmware() 没有检查 firmware->size 是否足够容纳 aml_fw_len 结构体头,直接把 firmware->data 当作结构体指针解引用;此外 fw_len 形参缺 const,可读性/类型系统上不严谨。

新流程

user sets zone_size
        |
        v
null_init_zoned_dev()
   1. reject zone_size == 0      // new
   2. require power-of-two        // existing
   3. compute zone_size_sects
   4. if zone_size_sects == 0    // new (overflow/saturation guard)
         -> -EINVAL
        |
        v
mb_to_sects(mb)
   WARN + return 0 if dev->zone_size_sects == 0   // new

固件加载:

request_firmware()
   |
   v
if firmware->size < sizeof(*fw_len)   // new bound check
   bail out with bt_dev_err()
   |
   v
treat firmware->data as struct aml_fw_len (const)   // const-correct

Patch 概览

  • MakefileSUBLEVEL = 47
  • drivers/block/null_blk/zoned.c:补 0 检查与 power-of-two 校验。
  • drivers/bluetooth/hci_aml.c:补固件 size 上界检查 + const 形参。
  • 其余 patch 在公告 body 中以 git shortstat 风格列出,覆盖 HID/NVMe/IOMMU/NFC/net 等,本次分析不展开。

关键实现

null_blk/zoned.c 三个点:

static inline sector_t mb_to_sects(unsigned long mb)
{
+   if (WARN_ON_ONCE(!dev->zone_size_sects))
+       return 0;
    return mb * dev->zone_size_sects;
}

- if (!is_power_of_2(dev->zone_size)) {
-     pr_err("zone_size must be power-of-two\n");
+ if (!dev->zone_size || !is_power_of_2(dev->zone_size)) {
+     pr_err("zone_size must be non-zero power-of-two\n");

+ if (!dev->zone_size_sects) {
+     pr_err("zone_size too large or too small, leads to zero sectors\n");
+     return -EINVAL;
+ }

hci_aml.c

-static int aml_download_firmware(struct hci_dev *hdev, const char *fw_name)
-{
-    struct aml_fw_len *fw_len = NULL;
+static int aml_download_firmware(struct hci_dev *hdev, const char *fw_name)
+{
+    const struct aml_fw_len *fw_len = NULL;

- fw_len = (struct aml_fw_len *)firmware->data;
+ if (firmware->size < sizeof(*fw_len)) {
+     bt_dev_err(hdev, "Firmware is too small ...");
+     ...
+ }

类比

这就像物业对公寓做“例行检修”:主体结构(6.18 大版本)不变,只是把 null_blk 配电箱里那块可能跳闸的零值保险丝换成带过流保护的,把 hci_aml 那扇没装门禁的小门补一道锁(size 检查 + const 标记)。住户(用户)不必搬走,但应该配合升级。

更具体:null_blk 是“模拟硬盘”,zone_size_sects == 0 相当于把一个扇区容量算成 0——任何基于它的“每个磁道多少字节”计算都会除零;补丁就是先量一下门宽是不是 0,再让人进去。hci_aml 的固件 size 检查则像快递员先看包裹是不是太小装不下标签(aml_fw_len),再决定要不要拆。

Highlight:风险与注意点

  • null_blk 之前的版本确实在用户/测试代码中触发过 divide by zero,是已知的 stable 回溯点;如果自研基于 null_blk 跑 fuzz,请确认升级。
  • hci_aml 的 size 检查说明厂商固件历史上可能比 header 还短,回归后下游设备初始化会直接 bt_dev_err 失败,注意日志关键字。
  • stable 点版本经常包含驱动“行为收紧”(如新增 WARN_ON_ONCE),若你之前依赖某个“未文档化”的容错行为,可能在 6.18.47 上看到 WARN,需关注 dmesg。
  • 本帖不是 RFC、也不是单独 patch 系列,而是 release announcement,所以分类上是 bugfix 集合(讨论/公告形式)。

版本变化

单版本公告,无 vN→vN+1 的多轮迭代;从公告 body 中可以看到此次包含的子系统修复覆盖面很广(NVMe target、HID、SMMU、NFC、net 等),但具体 patch 内容未在输入中给出。

一句话总结

Linux 6.18.47 是 6.18 系列的例行 stable 收尾版本,重点修复了 null_blk 在 zone_size 异常时的除零风险与 hci_aml 蓝牙驱动固件 size 检查缺失,所有 6.18 用户应当升级。

+-------------------+        +------------------------+
| 6.18.46 (older)   |  -->   | 6.18.47 (this release) |
+-------------------+        +------------------------+
        |                              |
        |  null_blk: zone_size_sects    |
        |  may be 0 -> div-by-zero      |
        |                              |
        |  hci_aml: no firmware size    |
        |  check -> out-of-bounds read  |
        v                              v
   risky under fuzz              guarded with WARN_ON_ONCE
                                 and explicit -EINVAL paths