[kernel/memheap] fix: stop invalid frees from corrupting heap - #11721
Conversation
RT_ASSERT() does not stop execution when RT_DEBUGING_ASSERT is disabled. Return after the existing block validation so a sequential duplicate free cannot update heap accounting or the free list in release builds. Before fix: memheap double-free used: before=64 alloc=224 free=64 after=4294959232 Validation: scons -C bsp/qemu-vexpress-a9 -j$(nproc) Signed-off-by: Hui Su <3164683437@qq.com>
|
我另外检查了一下这段代码的历史。 f8c171d 在 2015 年加入了 block overwrite 检查;随后 2d3b2f1 加入 USED bit 检查,commit message 明确说明是为了帮助定位 double-free 问题。这两次修改都只增加了 RT_ASSERT()。 2021 年 memheap 重构 d724eed 仍然保留了这种 validation + assert-only 的行为。我没有找到任何历史记录表明 validation 失败后仍应继续进入正常 free 路径。 当 RT_DEBUGING_ASSERT 关闭时,RT_ASSERT() 不会阻止后续代码继续执行,因此非法或已经释放的 block 会继续修改 available_size 和 free list。 本 PR 增加的 return 只是补上 Release 构建下缺失的控制流保护,同时保留现有 Debug 构建中的 assertion 诊断行为。 |
📌 Code Review Assignment🏷️ Tag: kernelReviewers: @GorrayLi @ReviewSun @hamburger-os @lianux-mm @wdfk-prog @xu18838022837 Changed Files (Click to expand)
📊 Current Review Status (Last Updated: 2026-08-19 17:55 CST)
📝 Review Instructions
|
|
👋 感谢您对 RT-Thread 的贡献!Thank you for your contribution to RT-Thread! 为确保代码符合 RT-Thread 的编码规范,请在你的仓库中执行以下步骤运行代码格式化工作流(如果格式化CI运行失败)。 🛠 操作步骤 | Steps
完成后,提交将自动更新至 如有问题欢迎联系我们,再次感谢您的贡献!💐 |
RT_ASSERT() does not stop execution when RT_DEBUGING_ASSERT is disabled. Return after the existing block validation so a sequential duplicate free cannot update heap accounting or the free list in release builds.
Before fix:
memheap double-free used: before=64 alloc=224 free=64 after=4294959232
Validation:
scons -C bsp/qemu-vexpress-a9 -j$(nproc)
拉取/合并请求描述:(PR description)
为什么提交这份PR (why to submit this PR)
rt_memheap_free()在释放内存块前会检查 block magic 和 USED 状态。当
RT_DEBUGING_ASSERT开启时,非法 free 或重复 free 会触发RT_ASSERT()。但是当RT_DEBUGING_ASSERT关闭时,RT_ASSERT()不会阻止后续代码继续执行,因此一个已经释放的 block 再次进入rt_memheap_free()后,仍会继续修改available_size和 free list,导致 memheap 元数据损坏。实际复现中,连续释放同一个 memheap block 两次后,修复前 heap used 统计出现异常:
memheap double-free used: before=64 alloc=224 free=64 after=4294959232
你的解决方案是什么 (what is your solution)
在现有 block validation 失败路径中的两个
RT_ASSERT()后增加return。这样:
rt_memheap_free()正常释放路径。修改仅增加一行控制流保护:
请提供验证的bsp和config (provide the config and bsp)
BSP:
bsp/qemu-vexpress-a9
.config:
用于复现 Release 构建下的问题:
CONFIG_RT_DEBUGING_ASSERT is not set
并完成 BSP 编译验证:
scons -C bsp/qemu-vexpress-a9 -j$(nproc)
待 push 分支并触发 GitHub Action 后补充链接
当前拉取/合并请求的状态 Intent for your PR
必须选择一项 Choose one (Mandatory):
代码质量 Code Quality:
我在这个拉取/合并请求中已经考虑了 As part of this pull request, I've considered the following:
#if 0代码,不包含已经被注释了的代码 All redundant code is removed and cleaned up