fix(global): 修复存储结构体字段零值文本的池缓冲溢出

_stg_field_zero_text 分配 160 字节,却用 snprintf(buf, 576, ...) 写出,长类型文本
(如 !llvm.array<8 x i8> zeroinitializer)可越界 415 字节,写穿相邻空闲块的元数据,
触发 [MEM] _fl_pop / [FREEFRAME] 空闲块被写穿(内核编译在 PhaseA 45/50 处中断)。
按实际类型文本长度分配(strlen+24),并把 snprintf 上限与分配对齐。

本文件同时含 3 处 DETSITE 插桩(elem_ty_str_n / ty_str / ty_buf_v)。
This commit is contained in:
TermiNexus committed 2026-10-07 15:16:47 +08:00
1 parent 12b15958c6
commit f3628a797a
1 file changed
+12 -8
+12 -8
View File
@@ -182,7 +182,7 @@ novirtual class TranslatorGenMixin:
pos_n: sizet = sizet(written_n)
# Sub-array type prefix (e.g. "[16 x i8]"): nested initializers must spell out the
# inner type, so serialize elem_ty via TypePrint for the [[16 x i8][...]] form.
elem_ty_str_n: str = pool.alloc(4096)
elem_ty_str_n: str = pool.alloc_tagged(4096, memhub.DETSITE_TRANSLATORGEN_185)
if elem_ty_str_n is None: return None
mlirlite.TypePrint(elem_ty_str_n, 4096, elem_ty, pool)
for i_n in range(cnt_total_n):
@@ -318,18 +318,22 @@ novirtual class TranslatorGenMixin:
def _stg_field_zero_text(self, pool: memhub.MemBuddy*, fty: mlirlite.LLVMType*, ty_str: str) -> str:
"""Build the zero initializer text for a storage struct field by LLVM type."""
if fty is None or ty_str is None: return None
buf: str = pool.alloc(160)
# Size by the actual type text: TypePrint inlines full struct bodies (up to 4096 bytes), and
# the historic fixed 160-byte buffer was written with a 576-byte snprintf limit, so a long
# type text overflowed the pool block and corrupted the neighbouring free block.
cap: sizet = string.strlen(ty_str) + 24
buf: str = pool.alloc(cap)
if buf is None: return None
match fty:
case mlirlite.LLVMType.Ptr(_):
viperlib.snprintf(buf, 576, "%s null", ty_str)
viperlib.snprintf(buf, cap, "%s null", ty_str)
case mlirlite.LLVMType.Int(_):
viperlib.snprintf(buf, 576, "%s 0", ty_str)
viperlib.snprintf(buf, cap, "%s 0", ty_str)
case mlirlite.LLVMType.Float(_):
viperlib.snprintf(buf, 576, "%s 0.0", ty_str)
viperlib.snprintf(buf, cap, "%s 0.0", ty_str)
case _:
# Aggregates such as Array / Struct -> zeroinitializer
viperlib.snprintf(buf, 576, "%s zeroinitializer", ty_str)
viperlib.snprintf(buf, cap, "%s zeroinitializer", ty_str)
return buf
# _default_val_const_text - field default value -> LLVM constant element text; only foldable
@@ -381,7 +385,7 @@ novirtual class TranslatorGenMixin:
fe: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(se, i)
i += 1
if fe is None or fe.Ty is None: continue
ty_str: str = pool.alloc(4096)
ty_str: str = pool.alloc_tagged(4096, memhub.DETSITE_TRANSLATORGEN_384)
if ty_str is None: continue
mlirlite.TypePrint(ty_str, 4096, fe.Ty, pool)
elem: str = self._default_val_const_text(pool, fe.Ty, ty_str, fe.DefaultVal)
@@ -829,7 +833,7 @@ novirtual class TranslatorGenMixin:
for fi_v in range(1, fc_v):
fe_v: GenTypes.FieldEntry* = self.Gen.StructGen._get_field_entry(resolved_stg_entry, fi_v)
if fe_v is None or fe_v.Ty is None: continue
ty_buf_v: str = pool.alloc(4096)
ty_buf_v: str = pool.alloc_tagged(4096, memhub.DETSITE_TRANSLATORGEN_832)
if ty_buf_v is None: continue
mlirlite.TypePrint(ty_buf_v, 4096, fe_v.Ty, pool)
zero_v: str = self._stg_field_zero_text(pool, fe_v.Ty, ty_buf_v)