导语:PostgreSQL UAF 漏洞 CVE-2026-116304 是 2026 年度数据库内核层面最值得警惕的内存安全缺陷之一——它把「并行查询」这一性能特性变成了攻击面:普通数据库用户只需构造匿名 RECORD 类型在并行 worker 间的协调场景,即可让一个进程释放共享元组描述符,而另一个进程继续持有并解引用其地址,最终在数据库服务进程的操作系统用户权限下执行任意代码。
作为长期负责数据基础设施的架构师,我对数据库内核 CVE 的判断标准从来不是「CVSS 分数高不高」,而是「攻击前置条件是否廉价」与「爆炸半径是否覆盖宿主机」。CVE-2026-116304 同时踩中两条红线:攻击者只需要一个普通数据库账号(PR:L),无需 UI 交互(UI:N),而后果是 OS 级代码执行(C:H/I:H/A:H)。这意味着一个原本只应读写自己 schema 的业务账号,可能直接跃迁为宿主机上的 postgres 系统用户。本文从内存生命周期、并行执行器架构、补丁差异与生产应急四个维度做完整拆解。
企业级架构规范
flowchart TD
subgraph 接入层 ["表现层与接入网关 (Client & Gateway Tier)"]
A["普通数据库用户连接 (低权限账号)"] --> B["构造含匿名 RECORD 类型的并行查询"]
end
subgraph 规则层 ["查询规划与并行调度层 (Planner & Parallel Scheduler Tier)"]
B --> C["生成并行计划 (Gather / Parallel Worker)"]
C --> D["匿名 RECORD 类型标识符在 worker 间共享注册"]
end
subgraph 领域层 ["核心执行与内存生命周期层 (Executor & Memory Tier)"]
D --> E["Worker A 释放共享 tuple descriptor"]
E --> F["Worker B 仍持有旧地址并解引用 (Use After Free)"]
F --> G["堆内存布局被可控数据覆盖"]
end
subgraph 存储层 ["基础设施与宿主层 (Host & OS Tier)"]
G --> H["控制流劫持 / 任意代码执行"]
H --> I[("以 postgres 系统用户权限落地")]
end
一、漏洞速览:PostgreSQL UAF 漏洞的官方定级与影响边界
根据 OSV 与 Ubuntu 安全公告,CVE-2026-116304 的 CVSS v3.1 向量为 AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H,综合评分 8.8(High)。Ubuntu 侧将其标记为 medium,这种评级差异恰恰反映了发行版视角与上游视角的分歧:Ubuntu 认为需要数据库账号作为前置条件,而上游更关注「一旦获得任意低权限账号即可提权至 OS」的严重性。
| 评估维度 | 官方取值 | 架构师解读 | 风险判定 |
|---|---|---|---|
| 攻击向量 AV | Network | 通过标准 SQL 连接即可触发,无需本地文件系统访问 | 远程可达 |
| 攻击复杂度 AC | Low | 无需复杂竞态窗口调优,并行计划本身即提供调度机会 | 易复现 |
| 所需权限 PR | Low | 任意可登录的数据库账号,业务只读账号亦满足 | 门槛极低 |
| 用户交互 UI | None | 无需管理员点击或配置变更 | 静默触发 |
| 机密/完整/可用性 | H/H/H | 可读取宿主文件、篡改数据、破坏服务 | 爆炸半径大 |
不要因为 Ubuntu 标注为 medium 就降低处置优先级。在多租户 SaaS、PaaS 数据库服务或存在弱口令/共享账号的环境中,PR:L 几乎等价于 PR:N,实际风险应以上游 CVSS 8.8 为准。
二、受影响版本矩阵与升级目标版本
漏洞影响 PostgreSQL 14 至 18 的全部主线版本,修复版本已随 2026 年 11 月的小版本发布同步上线。架构师在制定升级窗口时,需要同时核对上游版本号与发行版包版本号,避免出现「以为升了其实没升」的经典事故。
| 主线版本 | 受影响范围 | 修复版本 | Ubuntu 20.04 包示例 |
|---|---|---|---|
| PostgreSQL 18 | < 18.7 | 18.7 | — |
| PostgreSQL 17 | < 17.12 | 17.12 | — |
| PostgreSQL 16 | < 16.16 | 16.16 | — |
| PostgreSQL 15 | < 15.20 | 15.20 | — |
| PostgreSQL 14 | < 14.25 | 14.25 | — |
| PostgreSQL 12 (Focal) | 12.0-1 至 12.22-0ubuntu0.20.04.4 | 发行版修复包 | postgresql-12 |
需要特别注意的是,Ubuntu 20.04 LTS 上的 postgresql-12 属于社区已停止主线支持的版本,其修复依赖 Canonical 的扩展安全维护。若你的生产环境仍停留在 12.x,这本身就是一次架构层面的技术债清算信号——建议借此次应急窗口直接规划到 16 或 17 的跨大版本迁移。
三、根因剖析:匿名 RECORD 类型标识符在并行 Worker 间的协调缺陷
3.1 什么是匿名 RECORD 类型
在 PostgreSQL 中,RECORD 是一种伪类型,用于表示「运行时才确定结构」的行值。当查询中出现 ROW(1, 'a')、子查询返回多列、或 SELECT * FROM (VALUES ...) 这类结构时,执行器会为结果构造匿名的 tuple descriptor(元组描述符)。这些描述符在并行查询场景下需要被多个 worker 进程共享,因此其标识符与内存地址需要在共享内存或 DSM(Dynamic Shared Memory)段中协调。
3.2 UAF 的精确触发时序
漏洞的本质是「所有权语义缺失」:当多个并行 worker 引用同一个匿名 RECORD 类型标识符时,系统没有明确的引用计数或生命周期仲裁机制。攻击者可以构造一个查询,使得 Worker A 在完成自己的分片后释放共享 tuple descriptor,而 Worker B 仍持有该描述符的地址指针并在后续元组处理中解引用。此时该内存块可能已被重新分配并填充攻击者可控的数据,从而形成典型的释放后使用(Use After Free)。
- 释放阶段:Worker A 认为匿名 RECORD 描述符仅属于自己,调用释放逻辑归还共享内存。
- 悬垂阶段:Worker B 的本地缓存仍保存旧地址,未感知释放事件。
- 重用阶段:攻击者通过并行查询的其他内存分配路径,将可控数据布局到同一地址。
- 劫持阶段:Worker B 解引用被污染的描述符,函数指针或长度字段被篡改,控制流偏移。
这类缺陷无法通过 SQL 层权限模型防御,因为它发生在执行器内存管理层,位于所有行级安全(RLS)与列级权限之下。唯一可靠的防线是版本升级,任何「加权限、改配置」的思路都只是降低触发概率而非消除。
四、补丁逻辑与上游修复思路
上游在 18.7 / 17.12 / 16.16 / 15.20 / 14.25 中同步修复了该问题。从公开的发布说明与安全页面推断,修复方向集中在为匿名 RECORD 类型标识符引入明确的生命周期仲裁:要么在并行 worker 间建立引用计数,要么将描述符的所有权收敛到 leader 进程统一管理,worker 仅持有不可释放的只读引用。
# 1. 核验当前运行版本 psql -c "SELECT version();" # 2. Ubuntu/Debian 系升级(以 PostgreSQL 16 为例) sudo apt update sudo apt install --only-upgrade postgresql-16 postgresql-client-16 # 3. 核验包版本是否达到修复线 apt-cache policy postgresql-16 | grep Installed # 4. 重启服务使新二进制生效(小版本升级通常无需 initdb) sudo systemctl restart postgresql # 5. 升级后健康检查 psql -c "SELECT count(*) FROM pg_stat_activity;"
上述参数是临时缓解手段之一:关闭 leader 参与并行执行可以改变 worker 调度拓扑,降低特定竞态窗口的可利用性,但它不能替代升级,仅适用于无法立即重启的紧急窗口期。
点击展开:无法立即升级时的临时缓解脚本与回滚预案
# 临时缓解:全局关闭并行查询(性能有损,仅应急) psql -c "ALTER SYSTEM SET max_parallel_workers_per_gather = 0;" psql -c "SELECT pg_reload_conf();" # 收紧账号权限:回收非必要账号的 LOGIN 与查询权限 psql -c "REVOKE CREATE ON SCHEMA public FROM PUBLIC;" # 审计近期异常并行查询(需开启 pg_stat_statements) psql -c "SELECT query, calls FROM pg_stat_statements WHERE query ILIKE '%RECORD%' ORDER BY calls DESC LIMIT 20;" # 回滚:恢复并行配置 psql -c "ALTER SYSTEM RESET max_parallel_workers_per_gather;" psql -c "SELECT pg_reload_conf();"
五、生产环境应急响应 SOP
针对 PostgreSQL UAF 漏洞,我建议按「资产盘点 → 风险分级 → 升级执行 → 验证闭环」四步推进,并在每个阶段留下可审计的证据链。
- 资产盘点:扫描所有实例的
version()输出,建立版本与业务归属映射,重点标记多租户与对外暴露的实例。 - 风险分级:存在弱口令、共享账号、PaaS 自助开通能力的实例列为 P0,24 小时内完成升级。
- 升级执行:优先采用滚动升级,主备切换验证后再升级原主库,避免单点中断。
- 验证闭环:升级后复核包版本、执行并行查询冒烟测试、检查错误日志中是否有异常崩溃或段错误。
若实例日志中出现 segmentation fault、server process was terminated by signal 11 且伴随并行查询,需高度怀疑已被尝试利用。此时应立即隔离实例、保全内存转储与日志,并按入侵事件而非普通故障处置。
六、长期架构启示:把数据库内核 CVE 纳入 SLO 治理
这次 PostgreSQL UAF 漏洞再次提醒我们:数据库不是「装好就不动」的基础设施,而是持续演进、持续暴露攻击面的核心组件。成熟的团队应当把内核安全补丁纳入与业务服务同等级的 SLO 治理——设定高危 CVE 的修复时限(如 P0 24 小时、P1 7 天),并通过自动化流水线把版本核验、灰度升级、回滚演练固化为可重复执行的工程能力,而不是每次靠人工救火。
本文核心技术背景源自海外一线安全情报与上游公告:
OSV – UBUNTU-CVE-2026-116304 (Open Source Vulnerabilities)
PostgreSQL 官方安全页面 CVE-2026-116304
