fix: 脏重建方法 wrapper/构造器/global 槽跨轮复用迁移——FnWrapperKey 四分件键(加 label 消解同名原型 next/return/throw 碰撞)登记表继承止 S2 每轮 wrapper 无界累积,global 槽原位更新堵住旧构造器滞留 UAF 与每轮 +3 槽无界增长

This commit is contained in:
2026-09-11 18:06:19 +00:00
parent 4095ad2c1d
commit b17119ce16
12 changed files with 805 additions and 329 deletions
+28 -2
View File
@@ -231,8 +231,12 @@ pub fn run_mem_vm_creation_leak(kernel: &Arc<KernelCore>) -> ExitCode {
/// 路径的每轮内存增量(斜率 + 窗口总增量)。
///
/// # 注意事项
/// 键名逐轮递增保证走新键写入路径(既有槽位写不 bump 世代、不脏家族);
/// 修复释放路径后期望走平,残留本体钉在页粒度噪声级。
/// 键名逐轮递增保证走新键写入路径(既有槽位写不 bump 世代、不脏家族)。
/// 跨轮继承锚点(登记表对象数 / global 属性槽数)采样自每轮 full_reset
/// 后:wrapper 复用与槽位原位更新生效时两者应持平,增长即泄漏签名。
/// RSS 残差模型(post-91.1 裁定):object/function 家族脏重建每轮钉住 4
/// 件本体(重指遗漏兜底,不进门)+ 逐轮唯一键在共享内核 shape/perm 缓存
/// 的追加式增长(append-only 缓存,非 session 数据泄漏)。
pub fn run_mem_dirty_rebuild_leak(kernel: &Arc<KernelCore>) -> ExitCode {
const ROUNDS: usize = 3000;
const SAMPLE_EVERY: usize = 10;
@@ -242,6 +246,10 @@ pub fn run_mem_dirty_rebuild_leak(kernel: &Arc<KernelCore>) -> ExitCode {
let mut sampler = LeakSampler::new(20);
let mut series: Vec<(usize, f64)> = Vec::new();
// 跨轮继承锚点(登记表对象数 / global 属性槽数):wrapper 复用与槽位
// 原位更新生效时两者应跨轮持平,增长即泄漏的直接签名(无页粒度噪音)。
let mut first_anchor: Option<(usize, usize)> = None;
let mut last_anchor: (usize, usize) = (0, 0);
for round in 0..ROUNDS {
// 键名逐轮递增:新键写才 bump 原型世代,重建才有脏家族可换。
let source = format!(
@@ -265,6 +273,12 @@ pub fn run_mem_dirty_rebuild_leak(kernel: &Arc<KernelCore>) -> ExitCode {
}
vm.full_reset();
if round % SAMPLE_EVERY == 0 {
let registry = vm.session().builtin_world().leaked_object_count();
let global_slots = unsafe { (*vm.session().global_object().as_ptr()).prop_vec_len() };
if first_anchor.is_none() {
first_anchor = Some((registry, global_slots));
}
last_anchor = (registry, global_slots);
if let Some(kb) = read_vmrss_kb() {
let v = kb as f64;
series.push((round, v));
@@ -277,6 +291,18 @@ pub fn run_mem_dirty_rebuild_leak(kernel: &Arc<KernelCore>) -> ExitCode {
}
}
}
if let Some((r0, g0)) = first_anchor {
let (r1, g1) = last_anchor;
eprintln!(
"[dirty_rebuild] anchors: registry {} -> {} ({:+}) global_slots {} -> {} ({:+})",
r0,
r1,
r1 as i64 - r0 as i64,
g0,
g1,
g1 as i64 - g0 as i64
);
}
report_series("dirty_rebuild", "round", &series)
}