
Seccomp-based mitigation for CVE-2026-31431, a Linux kernel LPE. Blocks AF_ALG socket via PAM module and standalone wrapper, with auto-detection of patched kernels.
基于 seccomp 的 CVE-2026-31431 轻量级可回退缓解方案。该漏洞是 Linux 内核 algif_aead / authencesn 加密子系统中的本地提权漏洞。
通过 PAM 模块 在会话建立时加载 seccomp 过滤器,覆盖所有会话类型:su、ssh、login 等。
类型: 本地提权 (LPE)
影响组件: Linux 内核 crypto/algif_aead.c - in-place AEAD 操作
攻击原理: 通过 authencesn AEAD 算法的 scratch-write 路径,可对任意可读文件的 page cache 进行 4 字节可控写入。攻击者修改 /etc/passwd 中的 UID 字段为 0(root),通过 su 获取 root shell。
影响内核: 已确认影响 6.12+、6.17+、6.18+ 内核,在 RHEL/CentOS 4.18/5.14 内核上也成功复现。
已验证环境: Rocky Linux 8(内核 4.18)和 Rocky Linux 9(内核 5.14)——漏洞利用完全阻断,安全移除已确认。
根本原因: 提交 72548b093ee3 引入了 in-place AEAD 操作,AAD 的 seqno_lo 字段在 AEAD 解密过程中被错误地写回 page-cache。
上游修复: 回退到 out-of-place AEAD 操作。
本方案包含 两个组件:
PAM 模块 (pam_block_afalg.so) - 主要防线。在 PAM 会话打开时(pam_sm_open_session)加载 seccomp BPF 过滤器,在任何用户代码运行前阻断 socket(AF_ALG, ...)。覆盖所有 PAM 认证的会话:su -c、su -、SSH、TTY 登录等。
独立二进制 (block_afalg) - 可选。用于非 PAM 场景(如 cron、systemd 服务、手动调用)。
seccomp 过滤器:
socket(AF_ALG, ...)(返回 EACCES)setuid、su、sudo)PAM 会话打开 (su, ssh, login 等)
|
v
pam_block_afalg.so (pam_sm_open_session)
|
+-- 检查:内核是否受影响?(尝试 socket(AF_ALG))
| |
| +-- 否 --> 返回 PAM_SUCCESS(不操作)
| |
| +-- 是 --> prctl(PR_SET_SECCOMP, BPF 过滤器)
| |
| +-- seccomp 过滤器在 sshd 子进程上生效
| +-- 被用户 shell 及所有子进程继承
| +-- socket(AF_ALG, ...) 返回 EACCES
v
用户 shell / 命令在 seccomp 保护下运行
|
+-- su、sudo 及所有其他系统调用正常工作
+-- 仅 AF_ALG socket 被阻断
| 文件 | 作用 |
|---|---|
pam_block_afalg.c | PAM 模块源码,在会话打开时加载 seccomp 过滤器 |
pam_minimal.h | 最小 PAM 类型定义(无需 pam-devel 即可编译) |
gcc(编译用)libpam(运行时,通常已预装)# 1. 编译 PAM 模块
gcc -Wall -O2 -fPIC -shared -o pam_block_afalg.so pam_block_afalg.c \
/usr/lib64/libpam.so.0
# 2. 安装(自动添加 PAM 配置到 su、sshd、login)
sudo ./deploy.sh install
# 3. 验证(必须是新会话)
cat /proc/self/status | grep Seccomp
# 应显示:Seccomp: 2
python3 -c "
import socket
try:
s = socket.socket(38,2,0); s.close()
print('VULNERABLE')
except OSError:
print('BLOCKED')
"
# 应显示:BLOCKED
# 4. 卸载
sudo ./deploy.sh remove
| 命令 | 说明 |
|---|---|
deploy.sh install | 编译 PAM 模块,安装到 /lib64/security/,自动添加 PAM 配置 |
deploy.sh remove | 完全卸载:删除模块、清理 PAM 配置、删除文件 |
deploy.sh status | 显示安装状态、PAM 配置、内核状态 |
非 PAM 场景可直接使用 block_afalg:
# 编译
gcc -Wall -O2 -o block_afalg block_afalg.c
# 阻断 AF_ALG 运行命令
./block_afalg python3 your_script.py
./block_afalg bash
python3 -c "
import socket
try:
s = socket.socket(38, socket.SOCK_SEQPACKET, 0)
s.close()
print('VULNERABLE: AF_ALG socket available')
except:
print('SAFE: AF_ALG socket blocked or unavailable')
"
# 检查 seccomp 状态
cat /proc/self/status | grep Seccomp
# Seccomp: 0 = 未保护
# Seccomp: 2 = 已保护
# 测试 AF_ALG socket
python3 -c "
import socket
try:
s = socket.socket(38,2,0)
s.close()
print('AF_ALG available - NOT protected')
except OSError:
print('AF_ALG blocked - PROTECTED')
"
# 检查 PAM 日志
grep pam_block_afalg /var/log/secure
# 应显示:seccomp filter applied, AF_ALG blocked
__NR_socket)。其他架构需修改系统调用号。exec() 调用不受保护(可用 block_afalg 覆盖)。yum update kernel 后删除模块。本工具仅供授权安全测试和防御用途。仅在您拥有或明确授权评估的系统上使用。
block_afalg.c |
| 独立 seccomp wrapper 二进制,用于非 PAM 场景 |
deploy.sh | 部署脚本,编译、安装和管理 PAM 模块 |