# libpng png_combine_row 堆缓冲区溢出漏洞
## 概述
libpng 是用于处理 PNG 图像文件的参考库,广泛应用于读取、创建和操作 PNG 格式的程序中。在版本 1.6.0 至 1.6.51 之前,存在一个堆缓冲区溢出漏洞。
## 影响版本
受影响版本:1.6.0 ≤ version < 1.6.51
## 漏洞细节
漏洞存在于简化 API 函数 `png_image_finish_read` 中。当处理 16 位交错(interlaced)PNG 文件并将其转换为 8 位输出格式时,该函数未正确处理内存缓冲区,导致堆内存写越界。攻击者可以构造恶意的交错 PNG 文件,触发该漏洞。
## 影响
该漏洞可能导致应用程序崩溃或执行任意代码,具体取决于溢出内容和运行环境。对使用受影响版本处理 PNG 文件的应用程序构成严重安全风险。
## 修复情况
该问题已在版本 1.6.51 中修复。建议用户升级至该版本或更高版本以消除漏洞影响。
是否为 Web 类漏洞: 未知
判断理由:
标题: Fix a heap buffer overflow in `png_image_finish_read` by ctruta · Pull Request #757 · pnggroup/libpng · GitHub -- 🔗来源链接
标签:x_refsource_MISC
神龙速读:
- **漏洞类型**: 堆缓冲区溢出 (Heap Buffer Overflow)。
- **漏洞位置**: 在 `png_image_finish_read` 函数中。
- **根本原因**: 当处理 PNG 图像时,存在位深度不匹配问题,导致 `png_combine_row` 函数在转换前写入了错误的位深度,从而造成了缓冲区溢出。
- **影响范围**: 特定于 16 位 PNG 图像被请求以 8 位输出格式处理的情况。
- **示例计算**: 以 32x32 像素大小的 16 位 RGB 图像转换为 8 位 RGBA 为例,输入格式需要 6144 字节,而输出缓冲区只有 4096 字节,导致 2048 字节的溢出。256x256 像素图像的溢出则是 131072 字节。
- **报告人**: 由 yosiimich 通过电子邮件 yosiimich@users.noreply.github.com 报告。
- **修复方案**: 提供了修复以确保在转换过程中 `PNG_IMAGE_SIZE(image)` 能够安全地覆盖整个转换过程,尽管具体的修复细节还需要进一步的讨论和调整。
标题: Vulnerability Report: Heap Buffer Overflow in png_combine_row (libpng16, triggered via png_image_finish_read) · Issue #755 · pnggroup/libpng -- 🔗来源链接
标签:x_refsource_MISC
神龙速读:
### 关键漏洞信息
#### 漏洞标题
Heap Buffer Overflow in png_combine_row (libpng16, triggered via png_image_finish_read)
#### 漏洞编号
#755
#### 漏洞类型
Heap-Based Buffer Overflow
#### 漏洞影响
- 在处理畸形的PNG输入文件时,`png_combine_row` 函数会导致堆缓冲区溢出。
- 即使在通过 `png_safe_execute` 包含的内部安全保护层中处理,漏洞仍然存在,表明 libpng 自身的保护机制失效。
- 问题源于对内部行大小计算的不充分验证,允许超出边界写入,当PNG文件头中指定的维度超过用户分配的输出缓冲区时发生。
#### 漏洞具体原因
- `row_width` 直接来源于 `png_ptr->width`(IHDR头),该值可能被攻击者通过构造可疑的PNG文件控制。
- 没有验证此宽度是否与在 `png_image` API中跟踪的安全输出尺寸匹配,即 `image->width` 和 `image->height`。
#### 影响API函数
- `png_image_finish_read`
- `png_safe_execute`
#### 漏洞状态
Closed
#### CWE编号
- CWE-122 — Heap-Based Buffer Overflow
#### 提交者
yiasiimich
#### 提交时间
两周前
#### 修复提交
16b5e38
#### 修复者
ctruta
标题: Heap buffer overflow in `png_combine_row` triggered via `png_image_finish_read` · Advisory · pnggroup/libpng · GitHub -- 🔗来源链接
标签:x_refsource_CONFIRM
神龙速读:
### 关键信息
**CVE**: CVE-2025-65018
**Severity**: High (7.1/10)
**Package**: libpng
#### Summary
Heap buffer overflow in the libpng simplified API function `png_image_finish_read` when processing 16-bit interlaced PNGs with 8-bit output format. Attacker-crafted interlaced PNG files cause heap writes beyond allocated buffer bounds.
#### Vulnerability Mechanism
1. PNG IHDR declares 16-bit color depth with interlacing.
2. Application requests 8-bit output in RGBA format.
3. Application allocates PNG_IMAGE_SIZE(image) bytes (sized for 8-bit output).
4. `png_combine_row` writes using 16-bit IHDR depth before transformation.
5. Buffer overflow occurs because the function writes 16-bit data to an 8-bit sized buffer.
#### Fix
Using two commits:
- Initial: Rejects all 16-to-8 bit transformations via validation; too restrictive.
- Final: Removes validation for interlaced images only; maintains full API compatibility.
#### Mitigation
**Immediate**:
- Use the provided workaround before upgrading to libpng 1.6.51+.
- Upgrade to libpng 1.6.51+ where 16-to-8 bit transformations are fully supported and safe.
**Distribution Maintainers**: Apply to all supported versions. Notify downstream packages.
标题: Rearchitect the fix to the buffer overflow in `png_image_finish_read` · pnggroup/libpng@218612d · GitHub -- 🔗来源链接
标签:x_refsource_MISC
神龙速读:
### 关键漏洞信息
#### 漏洞类型
- 缓冲区溢出
#### 漏洞影响范围
- 仅影响交错(interlaced)的PNG图像,其中`png_combine_row`在转换完成之前使用IHDR位深度写入。
#### 原因分析
- 原修复方案(commit `16b5e38`)过于限制,拒绝了所有的16位到8位的转换。
- 新的解决方案是添加一个中间`local_row`缓冲区,专门用于慢但必要的16位到8位转换步骤。
#### 修复措施
- 添加`local_row`缓冲区处理交错图像的16位到8位转换。
- 增加`do_local_scale`标志和`png_image_read_direct_scaled`函数,遵循`do_local_compose`的模式。
#### 结果
- 交错图像的16位到8位转换现在是安全的,因为使用了中间缓冲区。
- 非交错图像的16位到8位转换保持安全,因为快速路径未更改。
- 所有回归测试现在都通过。
#### 相关文件
- `pngread.c`
#### 关键代码段更改
```c
+static int
+png_image_read_direct_scaled(png_voidp argument)
+{
+ png_image_read_control *display =
+ png_voidcast(png_image_read_control*, argument);
+ png_imagep image = display->image;
+ png_structrp png_ptr = image->opaque->png_ptr;
+ png_bytelp local_row =
+ png_voidcast(png_bytep, display->local_row);
+ png_bytelp first_row =
+ png_voidcast(png_bytep, display->first_row);
+ ptrdiff_t row_bytes = display->row_bytes;
+ int passes;
+
+ /* Handle interlacing. */
+ switch (png_ptr->interlaced)
+ {
+ case PNG_INTERLACE_NONE:
passes = 1;
break;
+ case PNG_INTERLACE_ADAM7:
passes = PNG_INTERLACE_ADAM7_PASSES;
break;
+ default:
png_error(png_ptr, "unknown interlace type");
}
+
+ /* Read each pass using local_row as intermediate buffer. */
+ while (--passes >= 0)
+ {
+ png_uint_32 y = image->height;
+ png_bytelp output_row = first_row;
+ while (y > 0)
+ {
+ /* Read into local_row (gets transformed 8-bit data). */
+ png_read_row(png_ptr, local_row, NULL);
+ /* Copy from local_row to user buffer. */
+ memcpy(output_row, local_row, (size_t)row_bytes);
+ output_row += row_bytes;
+ --y;
+ }
+ }
+ return 1;
}
```
标题: Fix a buffer overflow in `png_image_finish_read` · pnggroup/libpng@16b5e38 · GitHub -- 🔗来源链接
标签:x_refsource_MISC
神龙速读:
## 关键漏洞信息总结
### 漏洞描述
- **类型**: 缓冲区溢出
- **位置**: `png_image_finish_read` 函数
- **原因**: 在处理 PNG 图像时, 如果图像的位深度(在 IHDR 块中指定)与输出格式的位深度不匹配,导致缓冲区溢出。
- **示例**: 当 16 位 PNG 图像使用 8 位输出格式请求处理时,`png_combine_row` 函数在写入数据前使用 IHDR 块中的位深度,结果写入量超过通过 `PNG_IMAGE_SIZE(image)` 分配的缓存大小。
### 影响范围
- 对于 32x32 像素的 16 位 RGB 图像转为 8 位 RGBA 输出,将产生 2048 字节的溢出。
- 更大的图像将产生更大比例的溢出,例如 256x256 像素图像,将有 131072 字节的缓存溢出。
### 触发条件
- 输入图像的位深度与请求的输出格式位深度不匹配。
### 解决方案
- 代码修改 `pngread.c` 文件,添加判断逻辑,拒绝位深度不匹配的情况。
- 在 `png_image_finish_read` 函数中,添加检查以验证输入位深度是否符合要求:
```c
/* Reject bit depth mismatches to avoid buffer overflows. */
if (ihdr_bit_depth == 16 && !requested_linear)
return png_image_error(image, "16-bit PNG必须使用16位输出格式");
if (ihdr_bit_depth < 16 && requested_linear)
return png_image_error(image, "8-bit PNG不能使用16位输出格式");
```
- 报告者: yosiimich <yosiimich@users.noreply.github.com>
暂无评论