内核异常: zfs_fillpage 中的长度下溢 → 无法控制的 memset (mmap 读取竞争导致内存不足), 主机卡死
作者: tokyovigilante创建于 2026年8月13日更新于 2026年9月10日
标签Type: Defect
系统信息 | 类型 | 版本/名称 | —— | 分发名称 | Proxmox VE | 分发版本 | 9.2.10 (基于 Debian) | 内核版本 | 7.0.14-8-pve (#1 SMP PREEMPT_DYNAMIC, PREEMPT(lazy)) | 架构 | x86_64 (AMD EPYC 4545P, 128 GiB RAM) | OpenZFS 版本 | zfs-2.4.3-pve1 (kmod) | 池: 单个池"xserve", 55.9T NVMe, ONLINE, 没有错误, 关闭重复数据消除, ~16% 限制。 # 描述您观察到的问题 主机在 ZFS mmap 读路径中发生了致命的内核错误。一个进程 ("nifmake", 作为一个无权限用户在一个无权限 LXC 容器中运行的构建工具) 在 ZFS 上的一个内存映射文件上发生了内存页错误。错误显示了从 zfs_fillpage → dmu_read 调用的 memset,其长度为负数:
- RDX: ffffffffffff6a00 (memset 计数, ≈ -0x9600) - R14: ffffffffffffe000, R15: 0000000000002000, R13: 0000000000007600 - 发生错误的地址 CR2: ffff8bb330a00000, 错误代码 0x0003 (存在, 写入, 权限违规) - 也就是说, runaway memset 写入了内核内存,直到它碰到受保护的页面。 这与文件在页面错误发生时同时被截断一致,因此 fillpage 路径中的 i_size - page_offset 变为负数。 上下文: 主机上的两个容器处于持续的 memcg OOM-kill 暴风雨中 (内核 OOM 杀手反复杀死它们的 cgroup 中的任务)。错误发生在页面错误上下文中;主机没有恢复 (panic_on_oops=0) 并一直卡在了手动电源切换后大约 18 分钟后。 在 7.0.2→7.0.14 和几个 zfs 点版本之间观察到的行为。 早期的卡顿没有留下 pstore 记录 (日志在活动中就停止了),这与相同的错误-然后卡顿模式一致。 但是,只有此次发生被通过 EFI pstore 捕获。 可能与历史报告 #4705 (zfs_fillpage 超出范围, 2016) 有关。 # 说明如何重现问题 尚无最小重现器。 当它触发时的条件: 1. 无权限 LXC 容器在 ZFS 支持的根文件系统上 (Proxmox)。 2. 两个容器中的重大 memcg OOM 压力 (OOM 杀手反复杀死任务,中断写入操作)。 3. 在文件被修改/截断的同时,通过 mmap 读取文件 (构建工作负载 "nifmake")。 可能与历史报告 #4705 (zfs_fillpage 超出范围, 2016) 有关。 # 附上系统日志中的任何警告/错误/回溯信息
内容来源: openzfs/zfs