From b777d7c9257593e3803d147cbdb6ed394dd1d425 Mon Sep 17 00:00:00 2001 From: TermiNexus Date: Tue, 25 Aug 2026 16:16:02 +0800 Subject: [PATCH] =?UTF-8?q?fix(memhub):=20=E7=A7=BB=E9=99=A4=20free=20?= =?UTF-8?q?=E8=AE=B0=E5=BD=95=200xCD=20=E5=AE=8C=E6=95=B4=E6=80=A7?= =?UTF-8?q?=E6=A0=A1=E9=AA=8C=EF=BC=8C=E6=B6=88=E9=99=A4=20buddy=20?= =?UTF-8?q?=E8=87=AA=E5=86=99=E8=AF=AF=E6=8A=A5?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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。 --- includes/memhub.vp | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/includes/memhub.vp b/includes/memhub.vp index cdd28b4..db701ce 100644 --- a/includes/memhub.vp +++ b/includes/memhub.vp @@ -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: