GhostLock (CVE-2026-43499):潜伏十五年的内核栈UAF完整利用链
作者注本文基于在 Google kernelCTF 中成功利用 CVE-2026-43499 的实战经验撰写。该漏洞自 2011 年 Linux 2.6.39 引入至 2026 年修复横跨十五年影响所有主流发行版。一、漏洞概述1.1 基本信息CVE 编号CVE-2026-43499漏洞名称GhostLock漏洞类型基于栈的 Use-After-Free (UAF) / 本地权限提升 (LPE)CVSS 3.1 评分7.8 (High)影响范围Linux 2.6.39 至 7.1不含修复版本具体为 v2.6.39 ≤ kernel v6.1.175、v6.2 ≤ kernel v6.6.140、v6.7 ≤ kernel v6.12.86、v6.13 ≤ kernel v6.18.27、v6.19 ≤ kernel v7.0.4引入时间2011 年Linux 2.6.39修复提交3bfdc63936dd(rtmutex: Use waiter::task instead of current in remove_waiter())1.2 前置依赖该漏洞的触发仅依赖于CONFIG_FUTEX_PI——该选项在几乎所有发行版内核中均为默认启用。无需任何特权能力no capabilities required普通本地用户即可触发且可从容器内部逃逸至宿主机。1.3 漏洞本质漏洞位于kernel/locking/rtmutex.c的实时互斥量rtmutex优先级继承Priority Inheritance, PI路径中。核心问题是remove_waiter()函数在FUTEX_CMP_REQUEUE_PI的代理锁proxy-lock回滚路径中错误地对current而非waiter-task执行清理操作。这导致三个并发问题红黑树出队rbtree dequeue未持有waiter-task-pi_lockwaiter 任务的pi_blocked_on状态未被清除留下一个指向已返回内核栈帧的悬垂指针dangling pointerrt_mutex_adjust_prio_chain()操作了错误的 task。二、根本原因Root Cause2.1 代码路径分析remove_waiter()本为 slowlock 路径设计假定其清理的 waiter 始终属于当前运行任务。但在futex_requeue()调用的rt_mutex_start_proxy_lock()代理锁回滚场景中waiter 属于另一个正在睡眠的线程——内核在检测到死锁循环后以-EDEADLK进行回滚。关键代码逻辑如下漏洞版本c// kernel/locking/rtmutex.c (vulnerable) static void remove_waiter(struct rt_mutex *lock, struct rt_mutex_waiter *waiter) { // 错误在 proxy-lock 回滚场景下waiter-task ! current // 但以下操作全部基于 current raw_spin_lock(current-pi_lock); // ← 锁错了任务 rt_mutex_dequeue(lock, waiter); // ← 从红黑树出队 current-pi_blocked_on NULL; // ← 清空了 current 而非 waiter-task raw_spin_unlock(current-pi_lock); // ... }在rt_mutex_start_proxy_lock()中cint rt_mutex_start_proxy_lock(struct rt_mutex *lock, struct rt_mutex_waiter *waiter, struct task_struct *task) { // ... ret rt_mutex_wait_proxy_lock(lock, waiter, task); if (unlikely(ret)) // ← -EDEADLK 回滚路径 remove_waiter(lock, waiter); // ← 错误waiter-task ! current // ... }2.2 悬垂指针的形成当-EDEADLK回滚发生时waiter结构体位于task 的内核栈上作为局部变量remove_waiter()调用current-pi_blocked_on NULL——但应当被清除的是waiter-task-pi_blocked_on结果waiter-task-pi_blocked_on仍然指向栈上的waiter地址当waiter-task从rt_mutex_start_proxy_lock()返回用户空间后其内核栈帧被销毁并重用pi_blocked_on成为一个指向已释放内核栈内存的悬垂指针。2.3 死锁循环构造要触发该漏洞攻击者需要构造一个优先级反转死锁priority-inversion deadlock涉及三个 futex 和多线程协调。核心思路线程 A 持有一个 PI-futex 锁被线程 B 阻塞线程 C 通过FUTEX_CMP_REQUEUE_PI尝试代理锁内核检测到死锁循环返回-EDEADLK并触发上述回滚路径回滚完成后线程 B 的pi_blocked_on指向已释放的栈内存。此时攻击者获得了一个可预测的 UAF 窗口——pi_blocked_on指向的内存区域随后可被攻击者控制的数据重新占据。三、利用原语与栈回收3.1 栈上对象的特殊性该漏洞的 UAF 对象位于内核栈上而非堆heap。这带来了独特的挑战与机遇挑战栈帧的回收和重用由内核的栈管理机制控制难以像堆 spray 那样精确控制机遇内核栈地址具有相对可预测性尤其在未启用RANDOMIZE_KSTACK_OFFSET时且同一 CPU 上的后续系统调用会重用相同的栈区域。3.2 PR_SET_MM_MAP精确控制栈内存为精确控制被释放栈帧的内容攻击者利用prctl(PR_SET_MM_MAP, ...)接口。PR_SET_MM_MAP允许无特权用户在CONFIG_CHECKPOINT_RESTOREy内核上修改进程的mm_struct边界和saved_auxv 向量。攻击者通过精心构造的 auxv 向量将伪造的rt_mutex_waiter结构体放置在目标栈地址上。关键 Spray 策略cstruct prctl_mm_map { // 控制 mmap 基址、栈顶等间接影响内核栈布局 unsigned long start_code, end_code; unsigned long start_data, end_data; unsigned long start_brk, brk, start_stack; unsigned long arg_start, arg_end, env_start, env_end; unsigned long *auxv; // ← 关键指向用户空间构造的 auxv 向量 unsigned long auxv_size; };通过反复调用PR_SET_MM_MAP并配合pselect()等系统调用消耗栈空间攻击者可以在目标栈地址上精确布置伪造的rt_mutex_waiter。3.3 栈帧回收的时间窗口完整的栈回收利用流程触发 UAF构造死锁 → 触发-EDEADLK回滚 →pi_blocked_on悬垂栈帧释放waiter 任务返回用户空间其内核栈帧被标记为可重用栈 Spray通过PR_SET_MM_MAP 精心构造的系统调用序列在同一 CPU 上重用该栈区域伪造对象在被回收的栈位置上写入伪造的rt_mutex_waiter包含攻击者控制的lock指针等字段触发 UAF 读/写内核在后续的 PI 操作中解引用pi_blocked_on访问攻击者控制的数据。四、红黑树擦除引发的受限写入4.1 写入原语的本质该漏洞提供的核心利用原语来自于rt_mutex_dequeue()的红黑树rbtree擦除操作。当内核在 PI 路径中处理伪造的rt_mutex_waiter时会调用crt_mutex_dequeue(lock, waiter);在红黑树的rb_erase()实现中当被删除节点是根节点且只有一个子节点时该子节点会直接替换根指针——即执行一次*(u64 *)target W0_BASE类型的写入。4.2 约束条件该写入原语受到多重约束目标地址控制写入的目标地址由伪造waiter的lock字段控制。具体地攻击者设置waiter-lock target - offsetof(struct rt_mutex, waiters)使得红黑树根指针的写入发生在target地址。写入值约束写入的值W0_BASE是红黑树子节点的指针——即攻击者控制的伪造waiter结构体的地址或其派生值。这意味着写入值并非完全任意而是指向攻击者可控内存区域的指针但通过精心布局伪造的waiter在内存中的位置可以将W0_BASE调整为期望的指针值。目标地址约束目标地址target必须指向一个可写的内核内存区域且该区域附近必须存在一个有效的rt_mutex红黑树根结构。实践中这意味着目标地址前后的内存布局必须满足自旋锁spinlock状态检测——内核在操作前会检查lock-wait_lock的状态目标地址不能是只读内存如__read_mostly段的部分区域。4.3 从受限写入到原语升级通过多次触发该写入原语每次精心调整伪造waiter的布局攻击者可以将受限的单次指针写入升级为任意地址读通过将目标指向某个函数指针然后触发该函数调用读取其值受限的任意地址写通过链式写入逐步将W0_BASE调整为期望值。实际利用中该写入原语被称为Write-1-only 或 child-node PI write。五、绕过与劫持5.1 KASLR 绕过Prefetch 侧信道泄漏在获得受限写入原语后攻击者首先需要绕过 KASLR内核地址空间布局随机化以获取内核基址和物理映射区基址。利用prefetch 指令的侧信道TLB 时序实现 KASLR 泄漏。核心原理物理地址线性映射区起始地址前的虚拟地址并不存在到物理页面的映射prefetch指令在访问有效映射和无效映射时的执行时间存在可测量的差异通过暴力扫描虚拟地址空间攻击者可以确定内核映像基址和physmap 基址。具体攻击流程对候选虚拟地址范围执行prefetchnta/prefetcht2指令通过rdtsc精确测量执行时间利用时序差异确定有效映射的边界从而推导出 KASLR 偏移。该技术即使在有 KPTI 保护的系统中仍然有效。5.2 定位 CPU 入口区CEA在获得 KASLR 基址后攻击者定位per-CPU Entry Area (CEA)。CEA 包含了每个 CPU 的异常栈、SYSCALL 入口等重要数据结构。定位方法利用 CEA 在init_cea_offsets()中建立的固定偏移关系textcea_base kaslr_base CPU_ENTRY_AREA_BASE_OFFSET通过 CEA攻击者可以获取当前 CPU 的cpu_tss_rw任务状态段entry_SYSCALL_64入口地址其他关键 per-CPU 数据结构。5.3 函数表劫持覆盖 inet6_protos[IPPROTO_UDP]获得任意写入能力后攻击者选择劫持inet6_protos[]函数表。inet6_protos是一个全局数组存储了各 IPv6 协议的inet6_protocol结构体指针cconst struct inet6_protocol __rcu *inet6_protos[MAX_INET_PROTOS] __read_mostly;攻击者通过受限写入原语将inet6_protos[IPPROTO_UDP]索引 17覆盖为用户空间构造的伪造inet6_protocol结构体。伪造的inet6_protocol结构体包含cstruct inet6_protocol { int (*handler)(struct sk_buff *skb); // ... int (*err_handler)(struct sk_buff *skb, struct inet6_skb_parm *opt, u8 type, u8 code, int offset, __be32 info); // ... };攻击者将handler和err_handler指向精心构造的ROP 链起始地址用户空间 mmap 的地址或内核可写区域。5.4 触发控制流劫持回环 IPv6 UDP劫持完成后攻击者通过回环loopbackIPv6 UDP 流量触发控制流劫持创建 IPv6 UDP socketAF_INET6, SOCK_DGRAM, IPPROTO_UDP向::1IPv6 回环地址发送 UDP 数据包内核协议栈在接收路径上调用inet6_protos[IPPROTO_UDP]-handler()控制流跳转到攻击者伪造的 handler 地址 →开始执行 ROP 链。该方法的优势无需网络权限回环流量完全在内核内部高度可靠UDP 是无状态协议触发路径简单可重复触发发送任意 UDP 包即可再次触发。六、DirtyMode 提权阶段6.1 缩短 ROP 链的策略完整的 ROP 链可以执行复杂的 kernel 任意读写但 ROP 链越长栈空间约束和 gadget 可用性越成问题。为缩短 ROP 链攻击者采用单次写入提权策略。6.2 翻转 core_pattern 权限位攻击目标锁定在coredump_sysctls表中的core_pattern.mode字段。core_pattern是内核的 coredump 处理器配置当进程崩溃时内核会以root 权限执行core_pattern中指定的程序。通过 ROP 链执行一次精确的 64 位写入翻转core_pattern.mode的权限位text*(u64 *)coredump_sysctls.core_pattern.mode | S_IWUSR | S_IXUSR这使得原本只读的core_pattern变得可写。6.3 获取 Root 权限写入恶意 core_patternbashecho |/tmp/rootme /proc/sys/kernel/core_pattern其中/tmp/rootme是一个由攻击者控制的 setuid-root 程序或脚本。触发 core dump攻击者使自己的一个子进程触发段错误segmentation fault。内核以 root 权限执行恶意处理器内核在生成 core dump 时以root 身份执行/tmp/rootme。获取 root shell/tmp/rootme执行execve(/bin/sh, ...)或修改/etc/passwd完成提权。该方法的精妙之处在于仅需一次内核写入翻转 mode 位后续操作完全在用户空间完成无需维护复杂的 kernel ROP 状态规避了复杂的 cred 结构体定位和修改传统 LPE 的常见难点。七、修复与缓解7.1 官方补丁修复提交3bfdc63936ddrtmutex: Use waiter::task instead of current in remove_waiter()的核心改动diff// kernel/locking/rtmutex.c static void remove_waiter(struct rt_mutex *lock, struct rt_mutex_waiter *waiter) { - struct task_struct *task current; struct task_struct *task waiter-task; raw_spin_lock(task-pi_lock); rt_mutex_dequeue(lock, waiter); - current-pi_blocked_on NULL; task-pi_blocked_on NULL; raw_spin_unlock(task-pi_lock); // ... }同时在rt_mutex_start_proxy_lock()中增加了条件判断diff- if (unlikely(ret)) if (ret rt_mutex_has_waiters(lock)) remove_waiter(lock, waiter);7.2 补丁完整性分析该补丁修复了根本问题但存在一个值得注意的隐患NPDNULL Pointer Dereference风险在remove_waiter()中waiter-task理论上可能为 NULL例如在某种竞态条件下 waiter 已被部分清理。虽然当前代码路径下这种情况不会发生但补丁未添加显式的 NULL 检查未来若引入新的调用路径可能引入新的漏洞。补充修复社区后续可能考虑增加cif (WARN_ON_ONCE(!waiter-task)) return;7.3 缓解措施的有效性分析RANDOMIZE_KSTACK_OFFSET该选项在每次系统调用时随机化内核栈的起始偏移使得攻击者难以精确预测pi_blocked_on悬垂指针指向的栈地址。然而攻击者可通过多次尝试概率性攻击或侧信道来克服——该缓解措施增加利用难度但不消除漏洞。STATIC_USERMODE_HELPER该选项限制内核只能执行预定义的静态用户态辅助程序可阻断core_pattern执行任意用户程序。但大多数发行版默认未启用该选项即使启用攻击者仍可通过其他方法提权如直接修改 cred它仅阻断提权的最后一步不解决 UAF 本身。防御建议立即打补丁升级至 Linux ≥ 6.1.175 / 6.6.140 / 6.12.86 / 6.18.27 / 7.0.4多租户环境优先云服务器、容器平台、CI runner 应最先修复考虑启用RANDOMIZE_KSTACK_OFFSET作为纵深防御监控异常关注futex系统调用的异常模式及内核 panic 日志。结语GhostLock (CVE-2026-43499) 是一个教科书级别的栈 UAF 漏洞其利用链展示了从单一代码缺陷到完整 root 提权的完整路径textremove_waiter() 错误使用 current ↓ pi_blocked_on 悬垂指针栈 UAF ↓ PR_SET_MM_MAP 栈 Spray回收 伪造 ↓ rt_mutex_dequeue() 受限写入原语 ↓ Prefetch 侧信道KASLR 绕过 ↓ inet6_protos 函数表劫持CFI 绕过 ↓ core_pattern mode 翻转单次写入提权 ↓ Root Shell该漏洞自 2011 年潜伏至 2026 年横跨十五年提醒我们最危险的漏洞往往不是最新的而是最古老的——那些在复杂代码路径中沉睡多年、被无数人 review 却始终未被发现的缺陷。

相关新闻

网络安全实战武器库 · 2026最新版攻防工具全景指南

网络安全实战武器库 · 2026最新版攻防工具全景指南

从侦察到渗透,从流量分析到内网漫游——实战派高手的工具箱信息密度极高,建议立即收藏反复研读。📌 开篇:工具是你的第二双手网络安全是练出来的,而练习的第一步,是知道用什么工具、怎么用、什么时候用。只…

2026/7/31 6:34:05 阅读更多 →
腾讯性能优化专项面经:Systrace分析、LeakCanary原理、启动优化、电量优化

腾讯性能优化专项面经:Systrace分析、LeakCanary原理、启动优化、电量优化

Kotlin专项聊完,进入性能优化专项。高级岗性能优化必考,腾讯尤其看重——微信十几亿用户,性能差一点就是千万级投诉。 性能面试最易犯错:只背概念不讲数据。问"怎么做启动优化",答"懒加载"就完了。应该说"冷启动从3.2秒降到1.8秒,砍了Applicat…

2026/7/31 6:33:05 阅读更多 →
腾讯Kotlin专项面经:扩展函数原理、委托属性、Type-safe Builders、协程Scope

腾讯Kotlin专项面经:扩展函数原理、委托属性、Type-safe Builders、协程Scope

Java基础专项聊完,进入Kotlin专项。腾讯中级以上岗Kotlin标配,面试要问底层原理。扩展函数编译后变成什么?委托属性怎么工作?协程Scope区别在哪?Kotlin很多题目Java没有对应概念,没用过的人连题都听不懂。今天8道题全是Kotlin专属考点。 Q1:扩展函数的底层实现原理? …

2026/7/31 6:33:05 阅读更多 →

最新新闻

Autogrid5叶轮机械结构化网格生成:从拓扑模板到实战参数配置

Autogrid5叶轮机械结构化网格生成:从拓扑模板到实战参数配置

1. 从“画格子”到“算格子”:Autogrid5在叶轮机械CFD中的核心角色如果你做过叶轮机械的仿真,比如风机、压气机或者涡轮,那你肯定对“画网格”这个事儿不陌生。这可不是在纸上画方格那么简单,它更像是给一个极其复杂的雕塑&#x…

2026/7/31 7:05:16 阅读更多 →
OpenMP并行编程实战:从Fork-Join模型到性能调优

OpenMP并行编程实战:从Fork-Join模型到性能调优

1. 项目概述:为什么我们需要OpenMP?如果你用C或C写过计算密集型的程序,比如图像处理、科学模拟或者数据分析,大概率会遇到一个瓶颈:程序跑在CPU上,但CPU的多个核心大部分时间都在“围观”,只有一…

2026/7/31 7:05:16 阅读更多 →
OpenMP并行编程实战:从原理到高性能计算优化

OpenMP并行编程实战:从原理到高性能计算优化

1. 项目概述:为什么是OpenMP?如果你用C/C写过程序,尤其是处理过一些计算密集型的任务,比如图像处理、科学模拟或者数据分析,大概率会碰到一个头疼的问题:程序跑得太慢了。单核CPU吭哧吭哧地算,进…

2026/7/31 7:05:16 阅读更多 →
C++观察者模式:从原理到实战,构建松耦合事件驱动系统

C++观察者模式:从原理到实战,构建松耦合事件驱动系统

1. 项目概述:为什么我们需要观察者模式?在C项目里,尤其是那些涉及复杂UI交互、游戏事件系统或者需要解耦业务逻辑的场景,你是不是经常遇到这样的麻烦:一个对象的状态改变了,得手动去通知一堆其他对象更新&a…

2026/7/31 7:05:16 阅读更多 →
别再混淆备份与归档!海量数据时代,企业数据保护需要双轨并行

别再混淆备份与归档!海量数据时代,企业数据保护需要双轨并行

副标题:北京蓝美视讯:备份兜底,归档经营,搭建完整数据保护体系前言数字化转型浪潮下,企业音视频素材、业务档案、影像资料等非结构化数据呈爆发式增长。绝大多数企业管理者都存在同一个认知误区:搭建好备份…

2026/7/31 7:05:16 阅读更多 →
化合物3D结构生成:从SMILES到计算模型的完整指南

化合物3D结构生成:从SMILES到计算模型的完整指南

1. 从二维到三维:为什么我们需要化合物的3D结构?在药物研发、材料科学乃至基础化学研究中,我们常常从一张二维的化学结构式开始思考。比如阿司匹林,我们画个苯环,连上羧基和酯基,似乎就认识了它。但现实世界…

2026/7/31 7:04:16 阅读更多 →

日新闻

物理复制比逻辑复制好在哪?数据库复制原理详解

物理复制比逻辑复制好在哪?数据库复制原理详解

数据库复制是把主库数据同步到备库的机制,分为逻辑复制和物理复制两种。逻辑复制传输的是 SQL 语句或行变更事件,物理复制传输的是存储引擎底层的物理日志。阿里云 PolarDB(云原生数据库)采用物理复制,在同步延迟、数据…

2026/7/31 0:00:34 阅读更多 →
BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南

BilibiliDown:3分钟学会B站视频下载的终极指南 【免费下载链接】BilibiliDown (GUI-多平台支持) B站 哔哩哔哩 视频下载器。支持稍后再看、收藏夹、UP主视频批量下载|Bilibili Video Downloader 😳 项目地址: https://gitcode.com/gh_mirrors/bi/Bilib…

2026/7/31 0:00:34 阅读更多 →
有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

有哪些游戏数据AI平台?游戏行业Data+AI融合方案盘点

当前,游戏行业的“DataAI融合”已从概念验证进入价值落地阶段。根据IDC 2025年数据,中国AI游戏云市场规模已达18.6亿元;同时,游戏研发环节AI渗透率高达86%,生成式AI内容普及率超过50%。面对庞大的市场,游戏…

2026/7/31 0:00:34 阅读更多 →

周新闻

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 道路桥梁裂缝检测数据集 道路桥梁病害识别检测数据集

深度学习道路桥梁裂缝检测系统 数据集6000张 完整源码已标注数据集训练好的模型环境配置教程程序运行说明文档,可以直接使用!系统支持图片、视频、摄像头等多种方式检测裂缝,功能强大实用。 1数据集6000张 8各类别

2026/7/31 1:03:03 阅读更多 →
深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

深度学习YOLO模型如何训练 PUBG 绝地求生目标检测数据集

pubg数据集 精选原图1.42万数据 1.49万标签 无任何重复、算法增强或冗余图像! pubg绝地求生目标检测数据集 1分类:e_body,14905个标签,txt格式 共计14244张图,99%为640*640尺寸图像 适合yolo目标检测、AI训练关键词&am…

2026/7/29 14:34:28 阅读更多 →
Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex英雄目标检测数据集 深度学习框架YOLO如何训练APEX数据集

Apex检测数据集数据集详情检测类别: allies enemy tag图片总量:7247张训练集:5139张验证集:1425张测试集:683张标注状态:全部已标注,即拿即用数据格式:支持YOLO格式及其他格式&#…

2026/7/31 4:19:39 阅读更多 →

月新闻