fix(memhub): 移除 free 记录前标记校验——合并重分配误报(与 w0/w1 同类)
下溢写误报实锤:1024B free 块 hdr=0x0、同 ptr 仅一条 F 记录、前标记被写零——块合并进更大块后新分配用户区覆盖旧记录前标记区而旧块头仍为 0,前标记校验原理性不可靠(SlotsBugTest 1024B 块误报例)。 移除 free 记录全部校验,只保留 active 记录前/后标记校验(存活块独占,header LSB=1 不会合并,可靠)。
This commit is contained in:
1 parent
c9ccea4014
commit
e376b949c9
1 file changed
+6
-39
+6
-39
@@ -881,45 +881,12 @@ class MemBuddy(MemManager):
|
||||
p: t.CUInt64T = self._det_records[i * 2]
|
||||
s: t.CUInt64T = self._det_records[i * 2 + 1]
|
||||
if (s & free_flag) != 0:
|
||||
# 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
|
||||
hdr_v: t.CUInt64T = t.CUInt64T(c.Deref(t.CUInt64T(blk_h, t.CPtr)))
|
||||
if (hdr_v & 1) == 0:
|
||||
m_fr: t.CUInt16T | t.CPtr = (t.CUInt16T | t.CPtr)(t.CVoid(p - 2, t.CPtr))
|
||||
mfv_r: t.CUInt16T = m_fr[0]
|
||||
if mfv_r != t.CUInt16T(MEMBUDDY_DET_MARKER):
|
||||
stdio.printf("[DET] 下溢写: ptr=%llu size=%llu(free 后前标记被破坏,前标记=0x%04X)hdr=0x%llX 记录[%zu]\n",
|
||||
p, real_s, t.CUInt32T(mfv_r), hdr_v, i)
|
||||
# 记录上下文 ±3(同越界写打印,定位 free 块分配/释放阶段)
|
||||
stdio.printf("记录上下文: ")
|
||||
ci_r: t.CInt = -3
|
||||
while ci_r <= 3:
|
||||
idx_r: t.CSizeT = t.CSizeT(t.CInt(i) + ci_r)
|
||||
if idx_r < self._det_count:
|
||||
cip_r: t.CUInt64T = self._det_records[idx_r * 2]
|
||||
cis_r: t.CUInt64T = self._det_records[idx_r * 2 + 1]
|
||||
stdio.printf("[%d]ptr=%llu sz=%llu ", ci_r, cip_r, cis_r & (free_flag - 1))
|
||||
ci_r += 1
|
||||
# 同 ptr 记录(free/active 复用链,判断块是否被二次分配/释放)
|
||||
stdio.printf("\n同ptr记录: ")
|
||||
ci3_r: t.CSizeT = 0
|
||||
while ci3_r < self._det_count:
|
||||
cp3_r: t.CUInt64T = self._det_records[ci3_r * 2]
|
||||
cs3_r: t.CUInt64T = self._det_records[ci3_r * 2 + 1]
|
||||
if cp3_r == p:
|
||||
st_r: str = "A"
|
||||
if (cs3_r & free_flag) != 0:
|
||||
st_r = "F"
|
||||
stdio.printf("[%zu]sz=%llu%s ", ci3_r, cs3_r & (free_flag - 1), st_r)
|
||||
ci3_r += 1
|
||||
stdio.printf("\n")
|
||||
stdlib.exit(1)
|
||||
# free 记录:跳过——buddy 分配器合并/重分配使 free 块内存不排他
|
||||
# (块合并进更大块后,新分配的用户区可覆盖旧记录的前标记区而旧块
|
||||
# 头仍为 0),前标记校验会误报(SlotsBugTest 1024B 块 hdr=0x0、
|
||||
# 前标记被 2048 合并分配数据写零的误报例,与 w0/w1 0xCD 校验同类)。
|
||||
# 只校验 active 记录(存活块独占,header LSB=1 不会合并,
|
||||
# 前/后标记可靠)。
|
||||
i += 1
|
||||
continue
|
||||
if s == 0:
|
||||
|
||||
Reference in new issue
Block a user