Security

LMCache v0.5.6:安全修复、更广泛的硬件支持,以及 SGLang 集成

2026-11-02

LLMCache Team
以蓝色线条绘制在浅色纸面上的技术图纸。一个以粗线勾勒、标注为 root 的 LMCache MP 服务器位于主机边界之内。端口 5555 是穿过左侧墙壁的一条敞开通道,标注为 --host。通道中段立着一块金属板,板上只有一道窄缝。一个细长的类型化描述符穿过窄缝进入服务器。一条来自网络的橙色、形状不规则的消息撞在金属板上被挡住,因为它的形状与窄缝不符。通道依然敞开。标题栏写着 LMCACHE,v0.5.6 版本发布,图纸 1。
在 0.5.6 中,MP 服务器会在使用每个描述符之前先进行校验,因此精心构造的描述符再也无法通过 pickle 执行代码。当 host 设置为可路由地址时,该端口仍然可以被访问;官方镜像也仍然以 root 身份运行该进程。

LMCache 贡献者团队和社区很高兴地宣布,LMCache v0.5.6 已于 10 月 14 日发布。本版本包含一项严重安全漏洞修复、更广泛的硬件支持,以及 SGLang 集成,同时还带来了其他安全修复、bug 修复和新功能。

LMCache 0.5.6 修复了 CVE-2026-105192,这是多进程(multiprocess,MP)模式中的一个严重漏洞。在 0.3.9 至 0.5.5 版本中,只需向 MP 服务器端口(默认为 5555)发送一条未经身份验证的网络消息,就能以 LMCache 进程用户的身份执行任意代码。

官方容器镜像以 root 身份运行该进程。安全公告在通用漏洞评分系统(CVSS)中将该漏洞评为 9.8 分。攻击者只需具备网络访问权限,无需身份验证,也无需任何用户交互。

CVE-2026-105192 的修复

此次修复将 MP 设备进程间通信(IPC)描述符中的 pickle,替换为带版本号的类型化 MessagePack 描述符,同时覆盖 ZeroMQ 和 gRPC 两种传输方式。

由于传输格式(wire format)发生了变化,0.5.6 无法与更早的版本通信。

重要提示:请同时升级所有MP工作进程和服务器。

只有 MP 模式受影响。在 vLLM 进程内部使用 LMCache 不会开放该端口。

MP 端口默认绑定到 localhost。当 --host 设置为可路由地址时,该端口就会暴露。

示例 Kubernetes 部署会绑定到所有网络接口,因此基于该示例的部署都处于暴露状态。在 0.5.7 中,该示例将改为绑定到 localhost。在此之前,请将 MP 传输限制在 localhost 或受信任的集群网络内,并通过防火墙规则或网络策略限制对端口 5555 的访问。

候选版本 0.5.6rc1 至 rc3 同样受影响。

该问题由 JFrog Security Research 的 Yuval Moravchick 报告,并于 10 月 7 日在修复版本发布之前被公开披露。

我们 10 月 13 日发布的文章和安全公告介绍了该漏洞的原理、事件时间线,以及如何检查部署是否已被入侵。

修复覆盖的范围

现在,每个描述符在使用前都会经过校验,设备包装器类型来自一份固定的本地允许列表(allowlist),且不再回退到 pickle。修复详情见 PR #5644。

在此之后,仍有部分工作尚未完成。此次修复仅覆盖 MP 设备 IPC 描述符。默认关闭的引擎驱动(engine-driven)路径仍在使用 pickle,我们计划在 0.5.8 之前将其从该路径中移除。

MP 模式目前还不会对服务器、MP 协调器(coordinator)和前端之间的远程过程调用(RPC)进行身份验证。RPC 身份验证计划在 0.5.7 中推出。

运维人员升级须知

0.5.6 版本还更改了两项管理接口的默认设置。这两项更改(#5129,作者 Aleksander Pejcic)已于 9 月 22 日、即漏洞披露之前合并,因此与 CVE 修复无关。

在 0.5.6 之前,POST /run_script 在所有网络接口上提供服务,且没有任何身份验证。该端点会在 LMCache 进程内运行调用方提供的 Python 代码。

现在,除非设置了 run_script_api_enabled 或 --run-script-api-enabled,否则 /run_script 将返回 404。即使启用,它仍然没有身份验证。文档中提醒:“应将其视为完整的远程代码执行(remote code execution)能力。”

管理 HTTP 服务器现在绑定到 127.0.0.1,而不再是 0.0.0.0。相关设置为 internal_api_server_host 和 --http-host。

LMCache 在 0.5.6 之前与 0.5.6 中的默认设置对照表。每个取值单元格都有彩色边框:橙色表示暴露在网络上或会执行代码的默认值,青绿色表示经过加固的默认值。/run_script 从“开启”变为“关闭”,除非设置了 run_script_api_enabled,否则返回 404。由 internal_api_server_host 和 --http-host 控制的管理 HTTP 绑定地址,从 0.0.0.0 变为 127.0.0.1。MP 设备描述符从 pickle 变为类型化 MessagePack,并附注需同时升级 worker 和服务器。官方镜像用户在两列中均为 root,标注为未变更。
升级到 0.5.6 会改变上述默认设置和 MP 描述符格式。官方镜像仍以 root 身份运行。

升级前,请检查以下几点:

  • 由于传输格式已变更,请同时升级所有 MP 工作进程 和服务器。
  • 如果你在使用 /run_script,请设置 run_script_api_enabled 或 --run-script-api-enabled。
  • 管理 HTTP 现在绑定到 127.0.0.1。如需跨节点访问管理接口,请显式设置绑定地址。
  • 在 0.5.6 中,官方镜像仍以 root 身份运行。如需立即以非 root 用户运行,请基于 Dockerfile 自行构建镜像,或等待 0.5.7。
  • RPC 身份验证计划在 0.5.7 中推出。在此之前,请将 MP 服务器、协调器和前端部署在受信任的网络中。

SGLang 集成

LMCache 0.5.6 新增了 SGLang 集成,它基于 SGLang 的统一 radix cache 构建(#4828,作者 chunxiaozheng)。SGLang 会连接到一个独立的 LMCache MP 服务器。

SGLang 将其 radix tree 和 KV cache 保存在 GPU 上,LMCache 则在 SGLang 之外管理 CPU 和远程缓存层级。当某个前缀不在 GPU 上时,SGLang 会请求 LMCache 服务器查找并取回它;同时,SGLang 会把新的 KV cache 发送给服务器进行存储。

查找和预取并不是同步的。如果某个张量并行(TP)或流水线并行(PP)rank 失败,所有 rank 都会做出相同的选择,从而保持各 rank 之间的一致性。

该集成使用与 vLLM connector 相同的传输模式。在 CUDA 上,默认采用 LMCache 驱动(LMCache-driven)的传输。引擎驱动(engine-driven)传输(#5549)是本版本中 SGLang 新增的功能。它仅支持一个传输组,因此混合(hybrid)模型必须使用 auto 或 lmcache_driven。

#5379 新增了对 DeepSeek-V4.1-Flash 的支持。对于混合模型,请使用 --separate-object-groups 启动 LMCache 服务器。否则,LMCache 可能会恢复不兼容的 KV 或状态数据,导致精度问题。

该集成要求所用的 SGLang 版本包含 SGLang PR #38652。它只能在 MP 模式下运行,因此上文的 CVE-2026-105192 修复和升级须知同样适用于 SGLang 部署。

最小化部署包括一个配置文件、一个 LMCache 服务器和一个 SGLang 服务器:

cat > lmcache_config.yaml <<'EOF'
mp_host: 127.0.0.1
mp_port: 5555
EOF
lmcache server --host 127.0.0.1 --port 5555 \
--l1-size-gb 10 --eviction-policy LRU --supported-transfer-mode auto
python -m sglang.launch_server --model-path Qwen/Qwen3-8B \
--enable-lmcache --lmcache-config-file "$PWD/lmcache_config.yaml"

新的 lmcache/sglang 镜像(#5590,作者 aeon-x)基于官方 SGLang 发布镜像,并预装了与之匹配的 LMCache wheel。运行时请加上 --enable-lmcache,并连接到一个单独的 LMCache 服务器,例如 lmcache/standalone。如果 SGLang 和 LMCache 需要不同的 torch 版本,或者 SGLang connector 无法加载,镜像构建将会失败。

本版本的硬件与软件支持

0.5.6 中的许多更改新增或改进了对特定硬件、存储系统和推理引擎的支持。下面两张表列出了这些更改及其对应的 pull request。

硬件0.5.6 中的新增或改进Pull request
NVIDIA GPU(CUDA)借助 cudaMemcpyBatchAsync 加速 LMCache 驱动的传输;面向 arm64 的 CUDA 12.9 构建#5308, #5365
AMD GPU(ROCm)直接通过 copy engine 传输;在注册主机内存后清除待处理的 HIP 错误#5358, #5565
Intel GPU(XPU)原生 SYCL 块传输;锁页内存(pinned memory)后端#5408, #5311
昇腾(Ascend)NPU用于 LMCache 驱动传输的 NPU 平台后端;面向 vLLM-Ascend MLA 的 KV 格式#5341, #5138
MUSA GPU用于 MP GDS L1 的 SmartIO muFile 后端#5027
RBLN NPUMLA 的块传输;CI 中的 MP 冒烟测试#4726, #5543
沐曦(MetaX)MACA基于 MACA 硬件的 CI 流水线#4949
arm64 主机Docker 镜像,以及 CUDA 12.9 wheel 和镜像#5337, #5365
引擎、存储与平台0.5.6 中的新增或改进Pull request
vLLM由 connector 自动启动 MP 服务器;按请求设置卸载上限;MP 查找延迟指标;支持 vLLM 0.26.0 的融合 KV cache 布局#3476, #5029,
#5024, #4253
SGLang统一的 LMCache radix cache;引擎驱动传输;DeepSeek-V4.1-Flash 支持;新的 lmcache/sglang 镜像#4828, #5549,
#5379, #5590
3FS原生 L2 存储后端#5131
NIXL原生 connector;支持 IBM_SCALE 后端#4865, #5170
DRAM、Device-DAX、GDS跨 DRAM、Device-DAX 和 GPUDirect Storage(GDS)的多 L1 服务;运行时重新配置 Device-DAX#5416, #5461,
#5077
RawBlock(io_uring)MP L1 内存的固定缓冲区(fixed-buffer)I/O;批量恢复读取#4413, #4164
Kafka协调器的缓存事件 sink 与 source#5285, #5286
Kubernetes operatorruntimeClassName 覆盖;NRI 与 CDI 文档#5057
NVIDIA Dynamo本地与 Kubernetes 集成指南#5257

失败即关闭(fail-closed)的会话锁

#5457 让 free_lookup_locks 在失败时保持关闭(fail closed)。发布说明将其列在安全加固类更改中,因为它能保护共享引擎免受单个请求可能引发的故障影响。

在此修复之前,会话可能在其请求仍在 vLLM 队列中等待时过期。随后,free_lookup_locks 会释放其他请求仍持有的读锁。

这些其他请求因此无法取回数据。在具有多个 KV cache 组的混合模型上,这种失败会导致引擎停止。单个过期的会话就可能让该引擎上的所有请求都无法得到服务。

在报告的案例中,一个在 8 张 MI355X GPU 上运行的 Kimi-K3 部署,以 70 的并发度运行 agentic 任务 trace。它记录了约 1,000 条锁警告,引擎在运行约 25 分钟后停止。

现在,当会话已过期时,free_lookup_locks 不会释放它的任何读锁,这些锁随后由 L1 读取的存活时间(TTL)机制释放。

新的 --session-ttl-seconds 参数用于设置会话的存活时间,此前该值固定为 600 秒。默认值仍为 600 秒。如果请求在查找和取回之间的等待时间可能超过该值,例如 vLLM 队列很深时,请调高此参数。

感谢 Hyukjoon Lee 贡献此修复。

构建与镜像

LMCache 现在会发布 arm64 Docker 镜像,以及面向 arm64 的 CUDA 12.9 wheel 和镜像。0.5.5 版本已经发布了 aarch64(arm64)wheel。

lmcache/vllm-openai:v0.5.6 镜像同时支持 amd64 和 arm64。新的 lmcache/sglang 镜像也已可用。

安装或升级 Python 包:

pip install -U lmcache

其他更改

平台层(platform layer)经过了重构。设备相关代码现在位于 platform/devices 下,旧版 CUDA 包已被移除。

GDS、IPC 和指针操作现在都经由平台层完成。旧版 vLLM MP connector 快照已被移除。

其他亮点:

  • 预取控制器 v2。
  • MP 模式:抢占(preemption)、感知驱逐的惰性卸载(eviction-aware lazy offload)、ARC 驱逐策略、gRPC 传输、可插拔的服务器模块,以及 2 MiB 大页(hugepage)。
  • 协调器:事件 trace 的录制与回放。
  • CacheBlend:fp8(e4m3 和 e5m2)下的 Re-RoPE、重排序逻辑调整,以及整 chunk 的 L2 加载。
  • 得益于批量恢复校验和更快的 CLI,启动速度更快。

发布说明列出了每项更改及其对应的 pull request。其中的“Coming in v0.5.7”部分列出了在 v0.5.6 标签创建之后才合并的更改。这些更改现已包含在 nightly 构建中,并将随 0.5.7 发布。

感谢新贡献者

本版本包含了 48 位新贡献者的工作,他们的名字都列在发布说明中。许多首次贡献来自将日志调用改为惰性 % 格式化(lazy %-format logging)的工作。

约 25 个 commit 转换了日志调用,其中 12 个来自标记为“good first issue”的 issue。欢迎你们的加入,感谢你们的贡献。

问题与反馈

如果你对本版本有任何问题、想法或顾虑,请在 GitHub 上发起新的 Discussion 或 Issue。

如需报告安全漏洞,请勿使用公开的 Discussion 或 Issue,而应按照安全策略私下报告。

目录

分享方式:

发表回复

这个站点使用 Akismet 来减少垃圾评论。了解你的评论数据如何被处理。

博客更多内容