CVE-2020-35511¶
Abstract
- CVE ID: CVE-2020-35511
- CWE ID: CWE-126 (Buffer Over-read)
- Description: A global buffer overflow was discovered in pngcheck function in pngcheck-2.4.0(5 patches applied) via a crafted png file.
- CVSS: 7.8
- Published: 2022-08-23
- Affected: pngcheck 2.4.0
漏洞概要 ¶
pngcheck 是一个用于验证 PNG / JNG / MNG 文件格式的命令行工具。
官方消息中没有说明漏洞的确切位置,但根据漏洞发现者的博客的描述,它很可能位于 printf_buffer()
函数。该函数对参数 size
的大小校验不足,当 size
小于 1 时,循环不会终止,从而导致全局缓冲区的越界读取。
漏洞原理 ¶
源码地址:http://www.libpng.org/pub/png/src/pngcheck-2.4.0.zip
pngcheck.c | |
---|---|
888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 |
|
在 2.4.0 版本中,print_buffer
函数在处理七个不同 PNG 块时使用:
iCCP Chunk¶
print_buffer(&prbuf_state, buffer, name_len, 0);
name_len
来自 check_keyword
,不可为负值。
iTXt Chunk¶
print_buffer(&prbuf_state, buffer, keylen, 0);
print_buffer(&prbuf_state, buffer+keylen+3, taglen, 0);
keylen
和 taglen
都来自 keywordlen
,不可为负值。
pCAL Chunk¶
print_buffer(&prbuf_state, buffer, name_len, 0);
name_len
来自 check_keyowrd
,不可为负值。
sPLT Chunk¶
print_buffer(&prbuf_state, buffer, name_len, 0);
name_len
来自 check_keyword
,不可为负值。
tEXt / zTXt Chunks¶
print_buffer(&prbuf_state, buffer, keylen, 0);
print_buffer(&prbuf_state, buffer + keylen + 1, toread - keylen - 1, 1);
keylen
来自check_keyword
,不可为负值toread - keylen - 1
最小值为 0
SEEK Chunk¶
print_buffer(&prbuf_state, buffer, sz, 1);
sz
在每次函数调用前都进行了 if (sz > 0)
检查。
结论 ¶
所以从设计上看 print_buffer
函数可能有漏洞,但实现和使用上是安全的,因为:
- 所有
size
参数都在传入print_buffer
前经过验证 - 当
size == 0
时,while (size--)
循环立即终止
漏洞修复 ¶
官方在 v3.0.0 版本中在循环前添加 size
大小校验来修复这个问题:
@@ -887,6 +886,8 @@
/* GRR EBCDIC WARNING */
void print_buffer(printbuf_state *prbuf, uch *buf, int size, int indent)
{
+ if (size < 1)
+ return;
if (indent)
printf(" ");
while (size--) {