
Abraxas Labs · abraxaslabs.tech · github.com/abraxas · @abraxas_null
Linux 内核 BPF cgroup 本地存储通过尾调用导致的越界访问
| CVE | CVE-2025-38502 |
| CWE | CWE-125 — 越界读取 |
| 厂商 | Linux 内核 |
| 组件 | kernel/bpf/core.c、include/linux/bpf.h(cgroup 本地存储 + 尾调用) |
| 影响 | 本地内核内存破坏;在未打补丁的内核上,权限提升在影响范围内 |
| 攻击向量 | 本地(AV:L) |
| 所需权限 | 低(PR:L)— 能够加载 CGROUP_SKB 类型(或等效的 cgroup 附加程序)BPF 程序的进程 |
| 用户交互 | 无 |
| CVSS 3.1(kernel.org CNA) | 7.8 HIGH — CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H |
| CVSS 3.1(NVD) | 7.1 HIGH — CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:N/A:H |
| 公开日期 | 2025 年 8 月 16 日 |
| 上游修复 | 6.17-rc1 中的 abad3d0;已回合移植至 6.16.1、6.12.46、6.6.105、6.1.151、5.15.192 |
仅供研究 / 教育用途。 除非你同时获得托管此仓库的一方以及目标系统所有者的明确书面许可,否则请勿针对任何主机运行、部署或使用本仓库中的材料。已在野外发现。
源文件名 CVE-2025-3850-Linux-LPE-Abaraxas-Labs.c 截断了标识符。已发布的记录为 CVE-2025-38502。不存在 Linux CVE CVE-2025-3850。
Lonial 报告称,cgroup BPF 本地存储可以在尾调用过程中被越界访问。
eBPF 验证器会孤立地对每个程序进行类型检查。在运行时,bpf_get_local_storage() 不会查找当前正在执行的程序的 map。它从 current->bpf_ctx → bpf_cg_run_ctx → prog_item->cgroup_storage[] 中读取 cgroup 存储指针。该槽位由最初附加的程序填充,而不是由被尾调用进入的程序填充。
如果程序 A(较小的 BPF_MAP_TYPE_CGROUP_STORAGE 值大小)尾调用程序 B(较大的值大小),B 的 bpf_get_local_storage() 仍然返回 A 的较小缓冲区。验证器针对 B 的 map 所允许的访问随后就会越过 A 的分配边界。
该缺陷由 7d9c342(bpf: Make cgroup storages shared between programs on the same cgroup)在 Linux 5.9 中引入。修复方式是通过为 bpf_map_owner 扩展一个 storage_cookie[],使得只有当被调用者使用与调用者相同的 cgroup 存储 map,或完全不使用 cgroup 存储 map 时,尾调用组合才会被接受。
这是一个本地内核堆越界访问。严重性评分因厂商而异,因为他们对原语是“只读 DoS”还是完全内存破坏存在分歧:
实际含义如下:
struct bpf_array)可能被破坏。map->ops、劫持 helper、commit_creds / 命名空间切换)。这就是本仓库将该问题标记为 LPE 的原因。Red Hat 较低的评分反映的是其针对自身产品的评估,而非该漏洞不存在。该漏洞不需要面向网络的服务。它是本地的。它不需要 TTY、setuid helper 或用户交互。
两个 cgroup BPF 程序,各自拥有自己的 BPF_MAP_TYPE_CGROUP_STORAGE(共享风格,BPF_CGROUP_STORAGE_SHARED):
| 程序 | 角色 | 存储值大小 |
|---|---|---|
| A | 附加 / 尾调用调用者 | 小(例如适合给定的 kmalloc order) |
| B | 尾调用目标 | 大(验证器允许访问到该大小) |
验证器针对 A 的 map 检查 A,针对 B 的 map 检查 B。两者都通过。
在运行时,helper 执行:
ctx = container_of(current->bpf_ctx, struct bpf_cg_run_ctx, run_ctx);
storage = ctx->prog_item->cgroup_storage[stype];
if (stype == BPF_CGROUP_STORAGE_SHARED)
ptr = &READ_ONCE(storage->buf)->data[0];
else
ptr = this_cpu_ptr(storage->percpu_buf);
prog_item 是启动 cgroup 运行的程序的数组条目,而不是 bpf_tail_call 之后当前正在执行的程序。因此 B 操作的是 A 的存储对象。
bpf_cgroup_storage_alloc() 根据 map 的 value_size 确定后备缓冲区的大小。A 的缓冲区对于 B 经过验证的访问来说太小了。结果是典型的跨控制转移的 map 身份类型混淆——与其它 BPF “helper 看到的 map 与验证器看到的不同”问题属于同一类漏洞。
提交 7d9c342 使 cgroup 存储在附加到同一 cgroup 的程序之间共享。正是这种共享使得运行上下文槽位成为单个指针,而不是每个程序单独查找,这也是 5.9 之前的内核不受影响的原因。
对 BPF_PROG_TYPE_CGROUP_SKB 程序执行 BPF_PROG_TEST_RUN 会在测试期间分配 cgroup 存储。该分配位于内核堆上,紧邻同一大小类中最近释放的其它对象——包括 value_size 被选择为落入同一 kmalloc order 的 struct bpf_array map。因此,来自存储缓冲区的越界访问可以触及相邻 array map 的 bpf_map 字段(ops、RCU 链表、value[])。
正是这种堆布局细节,使得“仅仅是越界读取”的公告和 LPE 报告可以描述同一个 CVE。
引入: Linux 5.9(7d9c3427894fe70d1347b4820476bf37736d2ff0)
不受影响: 所有 5.9 之前的内核
单行说明:
/* CVE-2025-38502: affected 5.9–5.15.191, 5.16–6.1.150, 6.2–6.6.104, 6.7–6.12.45, 6.13–6.16.0; fixed in 5.15.192, 6.1.151, 6.6.105, 6.12.46, 6.16.1, 6.17-rc1 */
部分 stable 分支仍未修复: Debian 的内核跟踪器将 5.10 上游 stable / bullseye 5.10 列为 needed。不要假设每个 5.10.y 都已打补丁。
发行版 ABI 编号会误导人。 Ubuntu 5.15.0-163 是已打补丁的 5.15,尽管 5.15.0 看起来比上游 5.15.192 更旧。请比较软件包的 changelog / USN / DSA / ALAS / RHSA,而不是将 uname -r 与上表对照。
任何发布了上述范围内内核的发行版,在回合移植 abad3d0(或对应的 stable 提交)之前都处于影响范围内。这是通用 BPF 代码,不是发行版特定的补丁。
Ubuntu 26.04 / 25.10 被列为不受影响(它们在修复之后分支)。Ubuntu 25.04 在到达 EOL 时仍为 needed。
主机可能匹配受影响的版本,但仍然不可达。有用的检查:
unprivileged_bpf_disabled=1 不是完整的修复——拥有 BPF 能力的用户仍然可以触发该漏洞——但它移除了非特权路径。
上游提交 abad3d0bad72a52137e0c350c59542d75ae4f513(bpf: Fix oob access in cgroup local storage,Daniel Borkmann)。
struct bpf_map_owner 增加了一个 storage_cookie[] 数组。在更新尾调用目标时,内核现在会:
bpf_get_local_storage() — 要求被调用者的 cgroup 存储 map 完全是调用者的 map(相同的 cookie)。不匹配的值大小不再能在验证器背后被组合。每个程序仍然单独验证;新检查针对的是它们之间的边界。
不要在没有周围 BPF owner/cookie helper 的情况下将该提交 cherry-pick 到任意代码树上。请使用适用于你的系列的 stable 回合移植。
uname -r
# Compare against the table above, then against your distro advisory —
# Ubuntu/Debian ABI numbers are not upstream stable numbers.
grep -E 'CONFIG_BPF_SYSCALL|CONFIG_CGROUP_BPF' \
/boot/config-$(uname -r) /proc/config.gz 2>/dev/null
sysctl kernel.unprivileged_bpf_disabled
# 0 = unprivileged bpf allowed (widest exposure)
# 1 = disabled after first privileged use, or fully disabled depending on kernel
# 2 = disabled (admin can re-enable)
确认软件包,而不仅仅是版本字符串:
# Debian / Ubuntu
apt changelog linux-image-$(uname -r) 2>/dev/null | grep -i 38502
# RHEL family
rpm -q --changelog kernel | grep -i 38502
内核 ≥ 6.17,或“首个修复版本”列中列出的 stable,或来自公告表的发行版软件包,才是真正的收尾。
abad3d0 / stable 等效提交的发行版内核。这是唯一完整的修复。kernel.unprivileged_bpf_disabled=1(或 2)以阻止非特权加载器。CAP_BPF、CAP_PERFMON 和 CAP_SYS_ADMIN。seccomp、LSM,或在运行时中丢弃这些能力)。BPF_PROG_TEST_RUN 就足以触发该分配路径;本地攻击者会提供程序。CVE-2025-38502/
├── README.md
├── banner.png
├── CVE-2025-3850-Linux-LPE-Abaraxas-Labs.c
└── ebpf_lpe.h
| 文件 | 说明 |
|---|---|
banner.png | README 横幅(Abraxas Labs / CVE-2025-38502) |
CVE-2025-3850-Linux-LPE-Abaraxas-Labs.c | 在野外发现的研究源代码(文件名截断了 CVE id) |
ebpf_lpe.h | 该源代码使用的共享 BPF 指令构造器、map helper 和内核偏移宏 |
本目录记录了该漏洞并保存了相应的研究代码树。它不是开箱即用的漏洞利用工具包:内核 gadget 符号(ARRAY_MAP_OPS_OFF、COMMIT_CREDS 等)是针对特定 vmlinux 的编译期输入,而针对活动内核运行该程序超出了本 README 的范围。
CVE / NVD
上游
7d9c342 — bpf: Make cgroup storages shared between programs on the same cgroupabad3d0 — bpf: Fix oob access in cgroup local storageStable 回合移植
发行版
Abraxas Labs — 仅限研究 / 授权测试
本仓库用于研究和教育。
除非你同时获得托管此仓库的一方以及目标所有者的明确书面授权,否则请勿针对任何系统编译、运行、部署或以其它方式使用此处的代码。未经授权访问计算机系统是犯罪行为。
作者和 Abraxas Labs 按原样提供此材料,不保证其完整、正确或可安全执行。内核漏洞利用研究可能导致机器 panic、文件系统损坏和数据丢失。你需自行承担该风险。
已在野外发现。
| 来源 | 评分 | 完整性 | 备注 |
|---|
| kernel.org CNA / cve.org | 7.8 HIGH | 高 | C:H/I:H/A:H — 将该漏洞视为完全本地影响 |
| NVD | 7.1 HIGH | 无 | C:H/I:N/A:H — 机密性 + 可用性 |
| Ubuntu | 中(7.1) | — | USN-7909 |
| Red Hat | 4.0 LOW | 无 | C:N/I:N/A:L — 评为有限可用性影响 |
| Amazon Linux | 4.0 中 | 无 | 与 Red Hat 相同的向量 |
| SUSE | 6.1 中 | 无 | 部分 SLE 15 流标记为 WONTFIX |
| 系列 | 受影响 | 首个修复版本 |
|---|
| 5.9 – 5.15 | 5.9 至 5.15.191 | 5.15.192(c1c74584…) |
| 5.16 – 6.1 | 5.16 至 6.1.150 | 6.1.151(66da7cee…) |
| 6.2 – 6.6 | 6.2 至 6.6.104 | 6.6.105(7acfa07c…) |
| 6.7 – 6.12 | 6.7 至 6.12.45 | 6.12.46(41688d1f…) |
| 6.13 – 6.16 | 6.13 至 6.16.0 | 6.16.1(19341d5c…) |
| mainline | 直到修复落地 | 6.17-rc1(abad3d0b…) |
| 发行版 | 处于范围内的版本 / 内核 |
|---|
| Ubuntu | 22.04 LTS(5.15)、24.04 LTS(6.8)、25.04(EOL 仍为 needed)。20.04 HWE 5.15。 |
| Debian | 11 bullseye(5.10)、12 bookworm(6.1)、13 trixie(6.12) |
| RHEL 9 / 10、Rocky、Alma、Fedora | RHEL 9 ≈ 5.14;RHEL 10 ≈ 6.12;Fedora 滚动 5.9–6.16 |
| SUSE / openSUSE | SLE Micro 5.3/5.4;部分 SLE 15 流 WONTFIX |
| Amazon Linux 2023 | 默认内核和 kernel6.12 |
| Amazon Linux 2 extras | 5.10 extra(无修复计划)和 5.15 extra |
| Arch、Gentoo、Tumbleweed | 5.9 至 6.16.1 / 6.17-rc1 修复之间的滚动内核 |
| 发行版 | 修复软件包(指示性) | 公告 |
|---|
| Ubuntu 22.04 | linux 5.15.0-163.173 | USN-7909 |
| Ubuntu 24.04 | linux 6.8.0-106.106 | 同上 |
| Debian 12 | linux 6.1.153-1 | DSA-6009-1 |
| Debian 13 | linux 6.12.48-1 | DSA-6008-1 |
| Debian 11(6.1 回合移植) | linux-6.1 6.1.153-1~deb11u1 | DLA-4328-1 |
| Amazon Linux 2023 | kernel / kernel6.12,2025-09-29 | ALAS2023-2025-1210 / 1208 |
| Amazon Linux 2 5.15 extra | 2025-09-29 | ALAS2KERNEL-5.15-2025-091 |
| 条件 | 为什么重要 |
|---|
CONFIG_BPF_SYSCALL=y | bpf(2) 必须存在 |
CONFIG_CGROUP_BPF=y | cgroup 附加程序和 cgroup 本地存储 |
kernel.unprivileged_bpf_disabled | 0 允许非特权程序加载;1/2 需要 CAP_BPF / CAP_PERFMON / CAP_SYS_ADMIN |
| Lockdown / LSM / seccomp | 可能阻止 BPF_PROG_LOAD 或 BPF_PROG_TEST_RUN |
BPF_PROG_TYPE_CGROUP_SKB(或其它携带本地存储的 cgroup 程序类型) | 持有 cgroup_storage[] 的运行上下文 |