linux Copy Fail

Android普通应用用不了algif_aead,有个selinux的限制

https://cs.android.com/android/platform/superproject/+/android-latest-release:system/sepolicy/private/app_neverallows.te;l=141;drc=752d7278b477cf4578897c5b80c0006a9bae0164

漏洞是什么

1. 漏洞基本信息

  • CVE 编号:CVE-2026-31431
  • 代号:Copy Fail
  • 类型:本地权限提升(普通用户→root)、容器逃逸
  • 影响范围:2017 年之后主流 Linux 内核(Ubuntu、Debian、CentOS、Fedora 等)
  • 评级:严重(CVSS 7.8~9.8)
  • 披露时间:2026-04-29(韩国安全公司 Theori 公开)
  • 利用难度 :极低------732 字节 Python 脚本即可提权,无竞争、无复杂构造

2. 漏洞到底是什么

简单说:

内核里有个 AF_ALG(用户态加密接口)+ splice(零拷贝文件传输)+ authencesn(IPsec 用的加密模板) 的组合bug,导致普通用户可以向任意可读文件的内核页缓存写入 4 个受控字节

2.1 核心根源:页缓存进了"可写"链表

  • 用户用 splice() 把一个文件"零拷贝"到管道,再发给 AF_ALG 加密套接字。
  • 内核为了省内存,不复制文件内容,直接引用内核页缓存(page cache)的物理页
  • 2017 年内核加了个优化:AEAD 解密时"原地操作"------输入输出共用一个散列表(scatterlist)。
  • 结果:只读的页缓存页面,被放进了可写的输出链表

2.2 触发点:authencesn 越界写

  • authencesn 是给 IPsec 用的 AEAD 模板,为了处理 64 位序列号(ESN),会把输出缓冲区当临时草稿纸
  • 它在解密最后,会在合法输出区之外硬写 4 字节(序列号低 32 位)。
  • 别的加密算法都老老实实只写合法区域,只有 authencesn 越界写

2.3 结合 = 任意页缓存写

  • 当"原地优化"+"splice 页缓存引用"+"authencesn 越界写"三者凑一起:
  • 越界写直接落到内核页缓存的物理页上------也就是你 splice 的那个文件的内存镜像。
  • 攻击者能控制三件事
    1. 写哪个文件(只要你能读)
    2. 写文件内哪个偏移
    3. 写哪 4 个字节内容

3. 能干嘛?

最直接:

  • 普通用户篡改 /usr/bin/su、/bin/bash、sudosetuid 根程序的内存镜像(页缓存)
  • 不用改磁盘上的二进制(不触发校验),但系统运行时执行的是被篡改的内存版本,直接拿到 root 权限。
  • 容器里可以改宿主机页缓存,实现容器逃逸

和 Dirty Cow、Dirty Pipe 比:

  • 不用竞争条件(一次就成)
  • 不用找内核偏移
  • 不用编译,纯 Python 脚本
  • 成功率几乎 100%

4. 时间线

  • 2011:authencesn 加入内核,开始用输出区当草稿
  • 2015:AF_ALG 支持 AEAD,但当时是"非原地",输入输出分离,页缓存只读
  • 2017:原地优化合入(commit 72548b093ee3),页缓存进入可写输出链表------漏洞成型
  • 2026-04-29:公开披露,PoC 放出

漏洞细节

1. 修复前(漏洞状态)

c 复制代码
// 输入 = 输出(同一个链表)
req->src = req->dst

问题点:

  1. 输入和输出共用同一个 scatterlist
  2. 页缓存页面通过 sg_chain()链入了可写的输出链表
  3. authencesn 越界写 → 直接改写内核页缓存
  4. 这就是漏洞根源

2. 修复后(安全状态)

c 复制代码
// 输入 和 输出 完全分离
req->src  = TX SGL(来自用户 sendmsg 的数据,只读)
req->dst  = RX SGL(用户 recvmsg 缓冲区,只写)

关键修改(代码对照)

c 复制代码
// 漏洞代码(in‑place)
aead_request_set_crypt(..., rsgl_src, rx_sgl, ...);
// src 和 dst 都是 RX SGL → 同一个链表

// 修复代码(out‑of‑place)
aead_request_set_crypt(..., tsgl_src, rx_sgl, ...);
// src = TX SGL(输入)
// dst = RX SGL(输出)
// 完全分开

3. 修复具体做了什么?

官方补丁做了 3 件关键事

① 彻底取消 in‑place 原地操作

不再让输入输出共用链表,从设计上消灭页缓存进入可写链表的可能

② 移除 sg_chain() 链式拼接

不再把文件的页缓存标签页(tag pages) 拼接到输出缓冲区后面。

→ 页缓存页面永远不会进入可写 dst 链表

③ 只复制 AAD 数据,不再引用物理页

所有数据从 src → dst 都是真正复制,不再共享物理页。

4. 官方为什么这么修复?

"在 algif_aead 中使用原地操作没有任何好处,因为源和目标来自不同的映射。"

翻译成人话:那个 2017 年的优化本来就没性能收益,还带来了致命安全问题,所以直接删掉最安全。

5. 修复效果(100% 堵死漏洞)

修复后:

  • 页缓存页面永远只存在于只读的输入链表(src)
  • 不会进入可写输出链表(dst)
  • authencesn 就算越界写,也只会写到用户自己的缓冲区
  • 无法写内核页缓存 → 漏洞完全消失

6. 系统管理员如何修复?

方法1(推荐)

升级内核(最干净、最彻底)

方法2(临时缓解)

如果不能马上升级内核,可以禁用 algif_aead 模块:

bash 复制代码
echo "install algif_aead /bin/false" > /etc/modprobe.d/disable-algif-aead.conf
rmmod algif_aead 2>/dev/null
相关推荐
Gary Studio5 小时前
Selinux编写
linux·服务器·前端
Danileaf_Guo5 小时前
手搓KVM虚拟化!Ubuntu 26.04 + KVM 7.0.0,告别VMware的低成本玩法
linux·运维·服务器·ubuntu
中海德--陈顺真5 小时前
HONEYWELL 扫描架控制板 51000398
运维·服务器·人工智能
wuminyu5 小时前
专家视角看Java多态性的底层基石vtable(虚函数表)构建过程解析
java·linux·c语言·jvm·c++
lbb 小魔仙5 小时前
2026远程办公软件夏季深度横测:ToDesk、向日葵、网易UU远程全面对比,远控白皮书
android·服务器·网络协议·tcp/ip·postgresql
嵌入式×边缘AI:打怪升级日志5 小时前
全志T113 Tina-Linux开发环境搭建:从安装依赖到打包烧录完整教程
linux·运维·服务器
yugi9878385 小时前
Linux下58mm热敏打印机驱动安装与配置指南
linux·运维·服务器
遇见火星6 小时前
centos7和centos8设置本地镜像为yum安装源的方法
linux·运维·服务器
piaopiaolanghua6 小时前
[Ai问答] Docker是否支持跨架构镜像,譬如ARM/X86
linux·运维·服务器