ImageMagick CLAHE漏洞分析:无符号下溢与除零错误导致内存越界和进程崩溃

本文详细分析了ImageMagick CLAHE实现中的安全漏洞,包括无符号整数下溢导致的内存越界访问和除零错误,攻击者可通过特制参数触发进程崩溃或资源耗尽,影响多个Magick.NET版本。

CVE-2025-62594:ImageMagick CLAHE漏洞技术分析

漏洞概述

ImageMagick的CLAHE(对比度限制自适应直方图均衡化)实现中存在单一根本原因导致的两种相关不安全行为。当tile宽度或高度变为零时,会触发以下问题:

  • 无符号整数下溢 → 越界指针运算:当tile_info.height == 0时,表达式tile_info.height - 1(无符号)回绕到极大值,在指针运算中使用该值会导致巨大偏移和越界内存访问
  • 除零错误:代码在执行… / tile_info.width或… % tile_info.height时未重新检查零值,导致运行时除零崩溃

受影响版本

多个Magick.NET NuGet包版本<= 14.9.0受影响,包括:

  • Magick.NET-Q16-HDRI-OpenMP-arm64
  • Magick.NET-Q16-HDRI-OpenMP-x64
  • Magick.NET-Q16-HDRI-arm64
  • 及其他相关变体

技术细节

无符号下溢(可导致越界)

位置:MagickCore/enhance.c,约第609行

易受攻击代码

1
p += (ptrdiff_t) clahe_info->width * (tile.height - 1);

根本原因: 如果tile.height == 0,则(tile.height - 1)下溢为UINT_MAX,与clahe_info->width相乘产生接近SIZE_MAX的巨大值,添加到p导致指针算术下溢。

除零错误

位置:MagickCore/enhance.c,约第669-673行

易受攻击代码

1
2
3
4
5
if ((image->columns % tile_info.width) != 0)
  tile_info.x=(ssize_t) (tile_info.width-(image->columns % tile_info.width));
tile_info.y=0;
if ((image->rows % tile_info.height) != 0)
  tile_info.y=(ssize_t) (tile_info.height-(image->rows % tile_info.height));

触发条件

  • 精确tile设置:CLI命令-clahe 0x0!(!强制使用零值)
  • 小图像自动tile计算:当图像尺寸dim < 8时,dim » 3结果为0

复现步骤

无符号下溢复现

1
2
3
export UBSAN_OPTIONS=print_stacktrace=1:halt_on_error=1
export ASAN_OPTIONS=abort_on_error=1:allocator_may_return_null=1:detect_leaks=0
./magick xc:black -clahe 0x0 null:

除零错误复现

1
./magick -size 16x2 gradient: -type TrueColor -depth 8 -clahe 0x0! null:

影响评估

  • 主要影响:拒绝服务 - 进程崩溃或持续资源耗尽(内存/缓存抖动)
  • 攻击向量:通过CLI或API处理特制参数或极小图像
  • 严重性:中等(CVSS评分4.7)

修复建议

在CLAHEImage()中计算tile_info后,在进行任何除法/模运算/指针算术之前添加验证:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
if (exact_tiles_requested && (tile_info.width == 0 || tile_info.height == 0)) {
  ThrowMagickException(exception, GetMagickModule(), OptionError,
                       "CLAHEInvalidTile", "%lux%lu",
                       (unsigned long) tile_info.width,
                       (unsigned long) tile_info.height);
  return (Image *) NULL;
}

if (!exact_tiles_requested) {
  tile_info.width  = (tile_info.width  == 0) ? MagickMax((size_t)1, image->columns >> 3) : tile_info.width;
  tile_info.height = (tile_info.height == 0) ? MagickMax((size_t)1, image->rows    >> 3) : tile_info.height;
}

相关CWE

  • CWE-119:内存缓冲区操作限制不当
  • CWE-191:整数下溢
  • CWE-369:除零错误

参考链接

comments powered by Disqus
使用 Hugo 构建
主题 StackJimmy 设计