首页 网络安全 正文
  • 本文约3677字,阅读需18分钟
  • 7
  • 0

llama.cpp 越界写入漏洞CVE-2026-21869

摘要

栋科技漏洞库关注到 llama.cpp在提交 55d4206c8 及之前的版本中存在的安全漏洞,追踪为CVE-2026-21869,漏洞CVSS 3.1评分为8.8。

llama.cpp是Georgi Gerganov主导的C++开源 LLM 推理框架,以纯 C++ 无外部依赖、CPU 优先 + 多硬件加速、GGUF 量化生态为核心。

一、基本情况

llama.cpp是在 C/C++ 中实现多个大型语言模型(LLM)代码文件,通过 GGUF 量化与分层加速让大模型在低资源设备本地运行成为可能。

llama.cpp 越界写入漏洞CVE-2026-21869

llama.cpp实现资源受限设备(PC/边缘/嵌入式)的本地高效推理,支持 2–8bit 多精度量化与多模型热切换,适配个人到企业服务全场景。

栋科技漏洞库关注到 llama.cpp在提交 55d4206c8 及之前的版本中存在的安全漏洞,追踪为CVE-2026-21869,漏洞CVSS 3.1评分为8.8。

二、漏洞分析CVE-2026-21869 漏洞是存在于 llama.cpp 在 llama-server 中存在的越界写入漏洞,

该漏洞源于 llama.cpp 服务器在解析完成端点的 JSON 输入时,直接从输入中解析 n_discard 参数,但没有进行验证以确保其值非负。

当提供负值时,上下文会填满,导致 `llama_memory_seq_rm/add` 函数接收到反向范围和负偏移量。

这会在令牌评估循环中导致越界内存写入。这种确定的内存损坏可能会使进程崩溃或允许远程代码执行(RCE)。

上下文转移信任客户端的n_discard(注:n_discard可能为特定上下文中的变量或参数)。

远程攻击者可通过公共补全功能提供负值 端点,在切换过程中损坏KV缓存/文本缓冲区,并导致进程崩溃或转向远程代码执行(RCE)。

入口点:/completions/chat/completions/slots/(resume)

——任何通过 server_task::params_from_json_cmpl() 函数处理的入口点。

tools/server/server.cpp:326:n_discard直接从JSON解析到slot_params::n_discard中,没有进行非负数检查。

当上下文已满时,

server_context::update_slots()会消耗slot.task->params.n_discard来移位标记(tools/server/server.cpp:3613 ff.)。

负值会导致:

llama_memory_seq_rm/add 接收一个反向范围和负偏移量,使键值(KV)缓存不同步。

tools/server/server.cpp:3626-3630的循环中,

new_tokens[i - n_discard]评估为new_tokens[i + |n_discard|],并写入 超出std::vector的末尾。

使用ASan或内置保护机制时,会出现异常终止(pos_min == -1),

但移除这些保护机制后,会出现确定性的越界写入—— 攻击者执行代码所需的确切条件。

三、POC概念验证

先决条件:启动服务器时启用上下文切换(--context-shift)。适用于CPU和GPU构建;以下使用 CUDA+ASan二进制文件。

1、按照标准说明,使用CUDA和ASan构建llama-server。

2、启动它:

CUDA_LAUNCH_BLOCKING=1
ASAN_OPTIONS=abort_on_error=1:detect_leaks=0
LSAN_OPTIONS=detect_leaks=0
LD_LIpARY_PATH=/usr/local/cuda/lib64:$LD_LIpARY_PATH
build-cuda-asan/bin/llama-server
--model /models/DeepSeek-R1-Distill-Qwen-32B-Q2_K.gguf
--ctx-size 128
--port 8080
--context-shift

3、发出恶意请求(无需授权):

管理员已设置登录后刷新可查看

4、服务器日志显示插槽上下文发生偏移... n_discard = -32,随后出现KV不一致或ASan OOB报告。在未进行清理的情况下

构建相同的路径会导致内存无声崩溃,并为远程代码执行(RCE)敞开大门。

5、影响

远程未经身份验证的越界写入会导致崩溃或任意代码执行。

每个运行带有--context-shift(CPU或GPU)的HTTP服务器的llama.cpp部署都会受到影响。

攻击者仅需网络访问权限;无需凭证或用户交互。

输出:

This GDB supports auto-downloading debuginfo from the following URLs:
  <https://debuginfod.ubuntu.com>
Enable debuginfod for this session? (y or [n]) [answered N; input not from terminal]
Debuginfod has been disabled.
To make this setting permanent, add 'set debuginfod enabled off' to .gdbinit.
warning: could not find '.gnu_debugaltlink' file for /lib/x86_64-linux-gnu/liblber.so.2
warning: could not find '.gnu_debugaltlink' file for /lib/x86_64-linux-gnu/libpotlidec.so.1
warning: could not find '.gnu_debugaltlink' file for /lib/x86_64-linux-gnu/libpotlicommon.so.1
[Thread debugging using libthread_db enabled]
Using host libthread_db lipary "/lib/x86_64-linux-gnu/libthread_db.so.1".
0x00007f0c1219d813 in wait4 () from /lib/x86_64-linux-gnu/libc.so.6
#0  0x00007f0c1219d813 in wait4 () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x0000556d78816cd6 in __interceptor_waitpid ()
#2  0x00007f0c12670177 in ggml_print_backtrace () at /workspace/ggml/src/ggml.c:196
196             waitpid(child_pid, NULL, 0);
#3  0x00007f0c1267067a in ggml_abort (file=<optimized out>, line=<optimized out>, fmt=<optimized out>) at /workspace/ggml/src/ggml.c:230
230             ggml_print_backtrace();
#4  0x0000556d78a71d73 in server_context::update_slots (this=0x7f0c0fa01900) at /workspace/tools/server/server.cpp:3835
3835                                        GGML_ABORT("pos_min == -1, but n_past > 0 - should not happen: https://github.com/ggml-org/llama.cpp/pull/13833#discussion_r2116181237");
#5  0x0000556d7891c8ca in std::function<void ()>::operator()() const (this=0x7f0c0fa03078) at /usr/bin/../lib/gcc/x86_64-linux-gnu/13/../../../../include/c++/13/bits/std_function.h:591
591             return _M_invoker(_M_functor, std::forward<_ArgTypes>(__args)...);
#6  server_queue::start_loop (this=0x7f0c0fa02f58) at /workspace/tools/server/server.cpp:2152
2152                callback_update_slots();
#7  0x0000556d788c97c4 in main (argc=<optimized out>, argv=<optimized out>) at /workspace/tools/server/server.cpp:5753
5753        ctx_server.queue_tasks.start_loop();
[Inferior 1 (process 32778) detached]
[1]    32778 IOT instruction (core dumped)  ASAN_OPTIONS=abort_on_error=1:detect_leaks=0 LSAN_OPTIONS=detect_leaks=0  

四、影响范围

未知

五、修复建议

未知

六、参考链接

管理员已设置登录后刷新可查看



扫描二维码,在手机上阅读
评论
更换验证码
友情链接