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:
1 parent
12b15958c6
commit
f3628a797a
1 file changed
+12
-8
@@ -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)
|
||||
|
||||
Reference in new issue
Block a user