PostgreSQL CVE-2026-116304,并行查询 RECORD 用后释放

11 月 12 日,PostgreSQL 发布安全更新:18.7、17.12、16.16、15.20、14.25,一次修了 52 个安全漏洞 [1],其中 32 个是 8.8 分 [2]。这是本专栏同批的第三篇:前两篇是 6460(类型混淆打崩进程)和 18447(any 输出参数类型混淆),这篇是 CVE-2026-116304,CVSS 3.1 8.8 分,CWE-416 用后释放 [3]。它和前两篇的区别在门槛:一个能登录、能跑并行查询的普通账号就够,不需要 CREATE 权限,不需要超级用户,就能以运行数据库的操作系统用户身份执行任意代码 [3]。

原语:两个进程抢着管同一份描述符

PostgreSQL 的并行查询会把工作分给多个 worker 进程;查询用到匿名 RECORD 类型时,各进程要通过一张共享表解析类型的 typmod,拿到对应的元组描述符(TupleDesc)。

修复提交把竞态写成了四步 [5]:(1)一个进程把新的匿名 RECORD typmod 登记进共享表;(2)另一个进程解析这个 typmod,存下指向 TupleDesc 的指针;(3)第一个进程发现这个 TupleDesc 与另一个已有 typmod 的重复,把它释放了;(4)第二个进程稍后访问这块已释放的内存,把它当 TupleDesc 用,去解析元组。

释放后的内存内容,攻击者很可能控制到足以执行任意代码的程度,所以这是一个安全漏洞 [5]。修复是给这段共享描述符的管理加锁,提交是 find_or_make_matching_shared_tupledesc: Fix possible use-after-free,作者 Robert Haas,报告人 Peter Geoghegan,Andrew Dunstan 复核 [5]。

这里错的不是查询逻辑,是并发时序:两个进程各做各的都没错,错在中间没有同步。

和前两篇比:门槛一档比一档低

6460 要改复合类型定义,四条 SQL(建类型、PREPARE、ALTER TYPE、EXECUTE);18447 要建一个 SQL 函数、声明一个 any 输出参数;116304 只需要登录、跑并行查询。

匿名 RECORD 类型由查询本身产生,比如 ROW() 表达式、返回 RECORD 的函数,不需要建表,不需要建函数。并行查询默认开启(max_parallel_workers_per_gather 默认 2),触发路径里没有任何非默认配置。

三个都是 8.8 分,最终都是以数据库的操作系统用户身份执行代码。门槛最低的这篇,反而最难防:收 CREATE 权限挡不住它。

影响范围:五个分支全在内

受影响的是 18.7 之前、17.12 之前、16.16 之前、15.20 之前、14.25 之前的全部版本,修复版就是这次发布的五个小版本 [3]。14.25 是 PG 14 的最后一个版本,之后不再有安全与缺陷修复。

时间线与利用状态

2026 年 11 月 9 日,修复提交落地 [5]。2026 年 11 月 12 日,公开通告发布,52 个 CVE 一次公开;NVD 当天收录,尚未给出自己的评分,CNA PostgreSQL 给出的向量为 CVSS:3.1,8.8 分 [4]。

截至 2026 年 11 月 15 日发稿:CISA KEV 未收录 CVE-2026-116304(当前目录共 1781 条)[9];EPSS 0.0059,未来 30 天被利用的预测概率约 0.59% [8];未确认在野利用与公开 PoC [7]。修复提交是公开的,机制描述完整,窗口期不宜久留。

一句提醒:目前还没有公开 PoC,「只登录」这个判断来自官方描述与修复提交的机制,不是已验证的触发结论;但触发路径不需要任何非默认配置,并行查询默认就是开着的。

先做什么

第一,升级:升到 18.7 / 17.12 / 16.16 / 15.20 / 14.25。小版本升级不用 dump/reload,停库换二进制再启动就行。

第二,查账号:这次只登录的账号也在影响面里,收一遍不必要的登录账号和默认权限,尤其关注那些只有 SELECT 的账号;收 CREATE 权限挡不住这篇。

第三,升不上去的过渡:把 max_parallel_workers_per_gather 设为 0 能关掉并行执行、堵住这条触发路径。但这个参数任何角色都能在会话里用 SET 改回去,只能算升级前的过渡,不能当修复。

第四,扩展重编:虽然 116304 本身不破坏扩展兼容性,但同批补丁包含 6460 的 ABI 变动,用了第三方 C 扩展的实例升级后仍需重新编译扩展。

第五,PG 14 的用户:14.25 是最后一版,之后再有漏洞也不会修,排期迁到 15 或更新的分支。

参考资料

[1] PostgreSQL 官方通告:PostgreSQL 18.7, 17.12, 16.16, 15.20, 14.25, and 19 RC 2 Released!:https://www.postgresql.org/about/news/postgresql-187-1712-1616-1520-1425-and-19-rc-2-released-3442/

[2] ComputingForGeeks:PostgreSQL 18.7 Security Update: 52 CVEs and Patch Steps:https://computingforgeeks.com/postgresql-18-7-security-update-cves/

[3] PostgreSQL 安全页 CVE-2026-116304:https://www.postgresql.org/support/security/CVE-2026-116304/

[4] NVD:CVE-2026-116304:https://nvd.nist.gov/vuln/detail/CVE-2026-116304

[5] PostgreSQL 修复提交(find_or_make_matching_shared_tupledesc: Fix possible use-after-free):https://git.postgresql.org/gitweb/?p=postgresql.git;a=commitdiff;h=3bb99318e56c7048044fcf5e3e0f269fe00c9b54

[6] PostgreSQL 16.16 发布说明(E.1. Release 16.16):https://www.postgresql.org/docs/16/release-16-16.html

[7] cve.now:CVE-2026-116304:https://cve.now/CVE-2026-116304

[8] FIRST EPSS(CVE-2026-116304,2026-11-14 数据):https://api.first.org/data/v1/epss?cve=CVE-2026-116304

[9] CISA 已知被利用漏洞目录(KEV,2026-11-15 版):https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json

原文作者: liups.com

原文链接: https://liups.com/posts/9bd2562e/

许可协议: 知识共享署名-非商业性使用 4.0 国际许可协议