kernel stack overflow: handle_supercmd 与 supercmd_echo 各持 4KB 栈缓冲区嵌套,event 上报改写 argv 时栈耗尽 panic
维护者通常 3 天内回复
还没有人认领这个 Issue。
评估
- 难度
- 4/5
- 预计耗时
- 3-5 天
- 新手友好度
- 45/100
- Issue 类型
- 缺陷
- 描述清晰度
- 基本清楚
- 活跃度
- 活跃
- 技术栈
- c, linux
调研方向
Start in kernel/patch/common/supercmd.c, reading supercmd_echo, handle_supercmd, and the event-to-echo path. Inspect the generated stack frames and existing cleanup paths, then exercise the execve hook under COW and memory-reclaim pressure. Done means the overlapping large stack allocations are removed or safely shared and the relevant stress scenario no longer reaches kernel stack overflow.
由索引模型根据 Issue 内容生成。
描述
概要
handle_supercmd 与 supercmd_echo 各自在栈上持有一个 char buffer[4096],且 handle_supercmd 的 buffer 在调用 supercmd_echo 时仍然存活,两个 4KB 缓冲区必然同时在内核栈上。在 execve 前置 Hook 的深调用链中,supercmd_echo 改写 argv 触发 COW 缺页 + 内存回收时,会导致 Kernel panic - not syncing: kernel stack overflow。
该问题最初在下游 fork KernelPatch-Aster 中复现并做了符号还原(详见 LyraVoid/KernelPatch-Aster#1),经对照,上游当前 main(a308d88)的 supercmd.c 与下游崩溃版本仅在 superkey 参数解析处有差异(arg1 多 2 字节),两个 4KB 栈缓冲区及其调用关系完全相同,因此在此报告。
上游相关代码(main @ a308d88)
supercmd_echo内的char buffer[4096](L43–L47)handle_supercmd内的char buffer[4096](L426)event分支设置"report success"(L476–L479) →echo:标签处调用supercmd_echo(L498–L500)
handle_supercmd 的 buffer 在整个函数生命周期内存活,version 分支、echo: 标签等多处都会调用 supercmd_echo,两个 4KB 缓冲区叠加不可避免。
下游实测崩溃(KernelPatch-Aster)
设备后台发生 kernel stack overflow(CPU 2,Comm apd)。对已安装的 kpimg 做符号还原,帧大小取自 kpimg 实际指令:
| 返回地址 | 函数+偏移 | 栈帧 |
|---|---|---|
| 0xfffffff406abfa24 | compat_copy_to_user+0x84 | 64 B |
| 0xfffffff406abeb20 | set_user_arg_ptr+0x50 | 48 B |
| 0xfffffff406abc7f0 | supercmd_echo+0x120 | 4288 B |
| 0xfffffff406abcc34 | handle_supercmd+0x400 | 5056 B |
| 0xfffffff406abb9ac | handle_before_execve+0x30c | 336 B |
| 0xfffffff406abe098 | syscall_dispatch_before+0x208 | 560 B |
supercmd_echo入口:mov x12,#0x10c0; sub sp,sp,x12→ 4288 Bhandle_supercmd入口:mov x12,#0x13c0; sub sp,sp,x12→ 5056 B
仅这两帧就占 9344 字节,已识别的 KernelPatch 帧合计至少 10352 字节(16KB 内核栈的约 63%),尚未计入 Hook 跳板、系统调用入口、缺页、内存回收和厂商调度函数。
完整路径:
execve (su event ...)
→ syscall_dispatch_before
→ handle_before_execve
→ handle_supercmd (event 分支成功)
→ supercmd_echo("report success")
→ set_user_arg_ptr(argv[0])
→ compat_copy_to_user → __arch_copy_to_user
→ do_wp_page → 内存分配/直接回收 → shrink_slab
→ 厂商调度函数
→ stack overflow(越过栈底 320 字节)
崩溃时 MemAvailable 约 2.28 GiB,属于内核栈耗尽而非整机内存不足。厂商调度函数只是最终撞到栈保护边界的位置,首要原因是 supercmd 路径上两个 4KB 栈缓冲区叠加。
修复建议
- 消除两个 4KB 栈缓冲区的叠加:改为带错误清理的堆分配(如
kmalloc/vmalloc),或重构为handle_supercmd与supercmd_echo共享同一缓冲区。不建议简单改成静态全局缓冲区,会引入并发问题。 - 考虑为事件上报提供不经过
supercmd_echo/ argv 改写的返回通道,减少后台频繁上报走这条深栈路径。 - 编译期加入大栈帧检查(如
-Wframe-larger-than=),并在 COW 缺页 + 内存回收压力场景下实测。
说明
- 崩溃复现与符号还原基于下游 Aster 构建的 kpimg;上游未单独复现,但两个 4KB 缓冲区及调用路径与下游相同(下游
e6078ee与上游a308d88的supercmd.c仅差 superkey 解析处几行)。 - 尚未用修改后的构建做复现对照,无法确认上述修改能完全消除问题。
- 如有需要可补充
last-kmsg、符号还原记录与相关区段反汇编。
- 主要语言
- C
- 星标
- 1.6k
- 派生
- 393
- 平均合并
- 3 天 23 小时
- 30 天内合并 PR
- 7
环境准备
这个项目没有提供开发容器、Dockerfile 或贡献指南,环境需要你自己搭建:先看它的 README,通用步骤见我们的新手贡献指南。
从这里开始
- 先读完整个 Issue,再读项目的贡献指南。
- 在 Issue 下留言说明你要接手 —— 这能避免两个人做同样的事。
- Fork 仓库,在一个分支上完成修改。
- 提交 Pull Request,并在描述里引用这个 Issue 编号。
bmax121/KernelPatch 的其他 Issue
-
official LineageOS on nicepool: APpatch patching fails but only if done via recovery sideload可能已有人在做 @bmax121 于 10 天前认领。 未关闭
bmax121/KernelPatch#332 · 已指派 1 人 ·
维护者通常 3 天内回复
-
难度 4/5 3-5 天 新手友好度 35/100
bmax121/KernelPatch#329 · 1 条评论 ·
维护者通常 3 天内回复
-
难度 4/5 3-5 天 新手友好度 35/100
bmax121/KernelPatch#319 · 9 条评论 ·
维护者通常 3 天内回复
-
SUPERCALL_KSTORAGE_LIST_IDS writes to an unvalidated userspace pointer with a raw memcpy → kernel KE未关闭
难度 3/5 1-2 天 新手友好度 72/100
bmax121/KernelPatch#308 ·
维护者通常 3 天内回复
-
难度 4/5 3-5 天 新手友好度 35/100
bmax121/KernelPatch#306 ·
维护者通常 3 天内回复
查看 bmax121/KernelPatch 的全部 Issue
相似的 Issue
-
难度 1/5 1 小时以内 新手友好度 95/100
containers/crun#2415 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 78/100
zephyrproject-rtos/zephyr#123423 ·
维护者通常 2 天内回复
-
难度 2/5 1-3 小时 新手友好度 76/100
维护者通常 1 天内回复
-
bug
难度 2/5 1-3 小时 新手友好度 83/100
nextbsd/nextbsd-userland#434 ·
维护者通常 1 天内回复
-
难度 2/5 1-3 小时 新手友好度 77/100
维护者通常 1 天内回复