ImageMagick CLAHE漏洞分析:无符号下溢与除零错误导致内存越界和拒绝服务

本文详细分析了ImageMagick CLAHE实现中的安全漏洞,包括无符号整数下溢导致的指针越界算术运算和除零错误,这些漏洞可导致进程崩溃和拒绝服务攻击。

ImageMagick CLAHE漏洞分析

漏洞概述

ImageMagick的CLAHE(对比度限制自适应直方图均衡化)实现中存在单一根本原因漏洞——当分块宽度/高度变为零时,会产生两种不同但相关的不安全行为。

漏洞存在于ImageMagick的MagickCore/enhance.c文件中的CLAHEImage()函数。

漏洞详情

无符号整数下溢 → 越界指针算术运算(OOB)

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

漏洞代码

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

根本原因

  • 当tile.height == 0时,表达式(tile.height - 1)(无符号)下溢为一个非常大的值
  • 在指针算术中使用该值会产生巨大的偏移量和OOB内存访问
  • 导致内存损坏、SIGSEGV或资源耗尽

除零错误

位置: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_info.width或tile_info.height为0时触发除零错误
  • 零值可通过以下方式到达此点:
    • 精确分块:CLI命令clahe 0x0!(!强制使用零值)
    • 小图像上的自动分块:当请求的分块为0时,代码从图像尺寸派生默认值

复现步骤

无符号下溢复现

环境: 启用AddressSanitizer和UndefinedBehaviorSanitizer构建

命令

1
./magick xc:black -clahe 0x0 null:

输出

1
2
MagickCore/enhance.c:609:6: runtime error: addition of unsigned offset overflowed
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior MagickCore/enhance.c:609:6 in CLAHEImage

除零错误复现

命令

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

影响分析

主要影响:拒绝服务——在处理 crafted 参数或小图像时导致崩溃或持续的资源耗尽(内存/缓存抖动)

次要影响:OOB内存访问和内存损坏可能与其他漏洞结合实现更严重后果

修复建议

在CLAHEImage()中计算tile_info后,但在任何除法/模运算/指针算术之前应用:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
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;
}

if (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;
}

受影响版本

多个Magick.NET NuGet包版本 <= 14.9.0

严重程度

CVSS评分:4.7(中等)

基础指标:AV:L/AC:H/PR:N/UI:R/S:U/C:N/I:N/A:H

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