fix(memhub): 移除 free 记录 0xCD 完整性校验,消除 buddy 自写误报

free 记录 w0/w1 校验验证 free 后用户区 0xCD 完整,但 buddy 分配器 free 后会把 next 指针/子块头合法写进 free 块(free 块用户区即管理区),0xCD 必然被破坏 → 持续误报(SlotsBugTest 4352B 块首 8B=0x400000000、前标记完好的误报例)。

只保留可靠的前标记校验(子块边界 2^n>=32 对齐永不落在 block+8)。0xCD 填充保留。探测器可推进到 Phase2 用 is_alive 抓真实 KwEntry cargs 读取型 UAF。
This commit is contained in:
TermiNexus committed 2026-08-25 16:16:02 +08:00
1 parent 0f6ebb9065
commit b777d7c925
1 file changed
+5 -11
+5 -11
View File
@@ -865,14 +865,16 @@ class MemBuddy(MemManager):
if self._det_records is None:
return
free_flag: t.CUInt64T = t.CUInt64T(1) << 63
cd_word: t.CUInt64T = (t.CUInt64T(0xCDCDCDCD) << 32) | t.CUInt64T(0xCDCDCDCD)
i: t.CSizeT = 0
while i < self._det_count:
p: t.CUInt64T = self._det_records[i * 2]
s: t.CUInt64T = self._det_records[i * 2 + 1]
if (s & free_flag) != 0:
# free 记录:块头仍为 0(未被重新 alloc)则验证前标记 + 用户区
# 0xCD 完整——被写穿 = use-after-free 写入 / 下溢写
# free 记录:只校验前标记(block+8..9)——子块边界 2^n>=32 对齐
# 永不落在 block+8,前标记被破坏 = 真实 UAF/下溢写。不做用户区
# 0xCD 完整性校验:buddy 分配器 free 后会把 next 指针/子块头写进
# free 块(free 块用户区即管理区),0xCD 必然被破坏 → 持续误报
# (SlotsBugTest 4352B 块首 8B=0x400000000、前标记完好的误报例)。
real_s: t.CUInt64T = s & (free_flag - 1)
if real_s > 0:
blk_h: t.CUInt64T = p - 2 - MEMBUDDY_HEADER_SIZE
@@ -884,14 +886,6 @@ class MemBuddy(MemManager):
stdio.printf("[DET] 下溢写: ptr=%llu size=%llu(free 后前标记被破坏,前标记=0x%04X)\n",
p, real_s, t.CUInt32T(mfv_r))
stdlib.exit(1)
w0: t.CUInt64T = t.CUInt64T(c.Deref(t.CUInt64T(p, t.CPtr)))
w1: t.CUInt64T = w0
if real_s >= 8:
w1 = t.CUInt64T(c.Deref(t.CUInt64T(p + real_s - 8, t.CPtr)))
if w0 != cd_word or w1 != cd_word:
stdio.printf("[DET] UAF 写入: ptr=%llu size=%llu(free 后块被写,首=0x%llX 末=0x%llX)\n",
p, real_s, w0, w1)
stdlib.exit(1)
i += 1
continue
if s == 0: