IPBUF安全漏洞报告
English
CVE-2026-31533 CVSS 9.8 严重

CVE-2026-31533 Linux内核TLS加密释放后利用漏洞

披露日期: 2026-04-23
来源: 416baaa9-dc9f-4396-8d5f-8c081fb06d67

漏洞信息

漏洞编号
CVE-2026-31533
漏洞类型
释放后重用
CVSS评分
9.8 严重
攻击向量
网络 (AV:N)
认证要求
无需认证 (PR:N)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel

相关标签

UAFLinux Kernelnet/tls释放后重用权限提升CVSS:9.8

漏洞概述

Linux内核net/tls模块在 tls_do_encryption 函数的 -EBUSY 错误处理路径中存在一个严重的释放后重用漏洞。该漏洞由双重清理操作引起,具体涉及 encrypt_pending 和 scatterlist 条目。当加密请求因设备繁忙返回 -EBUSY 时,请求被排队,异步回调 tls_encrypt_done 会处理后续清理。然而,若 tls_encrypt_async_wait 返回错误,同步错误路径会重复执行相同的清理逻辑。这种双重递减会破坏 encrypt_pending 哨兵值,导致异步等待被永久跳过。随后的 sendmsg 操作可能在加密回调仍在待处理时释放 tls_rec,从而触发释放后重用,攻击者可利用此漏洞执行任意代码或导致内核崩溃。

技术细节

该漏洞的核心在于Linux内核TLS子系统处理异步加密请求时的竞态条件和状态管理错误。漏洞触发点位于 tls_do_encryption 函数。当 crypto_aead_encrypt 返回 -EBUSY 时,内核将请求加入 cryptd 积压队列,并依赖 tls_encrypt_done 回调在完成时恢复 scatterlist 并递减 ctx->encrypt_pending。问题在于,如果 tls_encrypt_async_wait() 发生错误,代码会进入同步错误路径,此时错误地认为需要手动清理,于是再次恢复 scatterlist 并递减 encrypt_pending。由于 encrypt_pending 初始为1,双重递减使其变为非预期值。一旦 encrypt_pending 被破坏,后续调用 tls_encrypt_async_wait 时会错误地认为没有待处理的异步操作,从而直接跳过等待。此时,如果应用程序调用 sendmsg,内核会通过 bpf_exec_tx_verdict() 释放 tls_rec 内存。然而,之前积压的加密请求的回调 tls_encrypt_done 可能随后在另一个上下文中被触发,尝试访问已被释放的 tls_rec,导致内核内存破坏。利用此漏洞需要通过特定的网络数据包发送时序来触发竞态条件,进而实现本地提权或拒绝服务攻击。

攻击链分析

STEP 1
步骤1
攻击者建立使用内核TLS(KTLS)加密的网络连接。
STEP 2
步骤2
攻击者通过sendmsg系统调用发送大量数据,使底层加密设备处于繁忙状态。
STEP 3
步骤3
加密请求返回-EBUSY,请求被加入cryptd积压队列,同时异步等待过程出现错误。
STEP 4
步骤4
同步错误路径错误地执行双重清理,导致encrypt_pending计数器损坏。
STEP 5
步骤5
攻击者再次操作触发sendmsg,内核误判认为无待处理操作,释放tls_rec内存。
STEP 6
步骤6
待处理的加密回调触发,访问已释放的内存,导致UAF并可能实现代码执行。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
/* * PoC for CVE-2026-31533: Linux Kernel TLS Use-After-Free * This PoC attempts to trigger the -EBUSY path in tls_do_encryption * by flooding the TLS socket with data to backlog the crypto engine. * NOTE: This is a conceptual PoC for demonstration purposes. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <linux/tls.h> int main() { int sock; struct tls12_crypto_info_aes_gcm_128 crypto_info; // Create a TCP socket sock = socket(AF_INET, SOCK_STREAM, 0); if (sock < 0) { perror("socket"); return 1; } // Setup TLS (Kernel TLS) // In a real scenario, this requires setting up keys and ciphers // memset(&crypto_info, 0, sizeof(crypto_info)); // setsockopt(sock, SOL_TLS, TLS_TX, &crypto_info, sizeof(crypto_info)); printf("Attempting to trigger UAF in TLS encryption path...\n"); // Loop to send data, aiming to hit the crypto backlog limit // causing crypto_aead_encrypt to return -EBUSY for (int i = 0; i < 10000; i++) { char buf[1024] = "A"; // sendmsg or send is used here // If the device is busy, this triggers the vulnerable path // send(sock, buf, sizeof(buf), 0); } // If successful, the kernel may crash or exhibit instability // due to the double-free/corrupt pending counter. printf("Payload sent. Check kernel logs for Oops.\n"); close(sock); return 0; }

影响范围

Linux Kernel (具体受影响版本请参考Git提交记录)
Linux Kernel stable branches

防御指南

临时缓解措施
禁用内核TLS功能(KTLS)作为临时的缓解措施,直到内核升级完成。可以通过在内核启动参数中禁用相关模块或限制系统调用权限来降低风险。

参考链接

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