一次重传引发的内存泄露:OpenSSL DTLS 漏洞复盘(一次传染性病的概率) szthrk.cn

9月29日,OpenSSL 放出一个高危漏洞,编号 CVE-2026-84782,打在 DTLS 实现上。官方描述很干脆,说 DTLS 在重传握手消息时,用了一个已经过期的缓冲区偏移量。当一条较大的握手消息还没发完就触发重传,进程可能把堆内存原样吐给对端,而这块数据是未加密的,也可能直接把进程搞崩。修复落在 4.0.3、3.6.5、3.5.9、3.4.8 这几个版本,官方口径就一句,尽快升级。

补丁看着简单,落到一线却是实打实的风险面。堆内存泄露和进程崩溃,这两件事哪个先来都不好受。

DTLS 这东西,说穿了就是跑在 UDP 上的 TLS。

TCP 有重传、有顺序保证,TLS 握手直接建立在可靠的字节流上,消息丢不了,也不会乱序。换成 UDP,什么都没有,包丢了就是真丢了。DTLS 只能自己补上一套握手机制,给每条握手消息编号,处理乱序到达,重传计时器也得自己维护。

为了省内存,握手消息会被切片塞进缓冲区,按偏移量一段段发出去。TCP 那套确认到哪就发到哪的滑动窗口逻辑,在这里要手写。毛病就出在这,消息还没发完,重传计时器先到了,代码拿了旧的偏移量去重取数据。偏移量一旦错位,取到的就是缓冲区之外的内存。堆上放了什么,对面就可能收到什么。

拿个真实场景还原一下。物联网设备、VoIP 网关、WebRTC 这些走 UDP 的业务,大量依赖 DTLS 做加密握手。设备被反复握手、丢包、重传,就有机会踩中。内存泄露不一定被利用才叫事,进程崩了本身就是一次业务中断。

排查上,升级前先用 openssl version -a 确认版本,顺手看下 DTLS 相关日志里的异常重传和进程退出。真正难缠的是存量资产,嵌入式固件里 OpenSSL 嵌得深,升级周期拉得很长;堆上泄漏的到底是会话票据还是密钥材料,版本一多就更难盘。安全组件出漏洞能打补丁,证书到期这事只能靠续,两者挨得其实很近。

DTLS 也好,TLS 也好,握手第一步都是拿证书换信任。私钥泄露、证书过期、证书链不完整,任意一条都能让整条加密链路失效。失效还常常挑凌晨,告警比人先到。

不少团队至今用人工台账管证书,谁申请、谁续、装在哪台,全凭表格和记忆。漏续一次,线上就是一片红。ACME 协议把续期这件事标准化了,可真要落到多域名、泛域名、IP 证书,再加多云多节点分发,自己写脚本维护的坑一点不少。

这种场景里,lcjmSSL 把流程收拢了。它依托 Let's Encrypt、Google Trust Services、ZeroSSL 这类可信 CA,把证书的申请、域名验证、部署串成全自动,多域名和泛域名都覆盖,配置不用手工调。对运维来说,证书续期从记得做变成不用管,这才是它该有的样子。轻量化 API 也让批量节点接进来更省事,不用为每台机器单独折腾。

回到这次的漏洞,补丁照打,证书照续,都是生命周期管理里逃不掉的功课。