
Heap corruption in WhatsApp's media picker
堆损坏影响 Android 版 WhatsApp(版本 2.19.291 之前)的媒体选择器
GIF 文件被分割为多个段,由特定字节标记:
根据源代码,renderFrame 调用 DDGifSlurp 解析 GIF,并调用 getBitmap 显示 GIF。函数分配了一个 rasterBits 缓冲区,其大小通过将当前处理图像的宽度乘以高度来计算。也许是为了节省内存空间和时间,同一个 rasterBits 缓冲区将用于 GIF 中的所有帧/图像。因此,要求该缓冲区能够容纳文件中描述的最大图像。因此,如果同一 GIF 中的另一个图像段描述了更大的图像(需要更多空间),则会重新分配缓冲区。
DDGifSlurp 在循环中解析 GIF 文件,处理每个图像/帧,并在遇到终止记录时终止。当 DGifGetImageDesc 返回 GIF_ERROR (a) 时,会导致提前终止(在 switch case 中),从而跳过重新分配 rasterBits 缓冲区的代码。DDGifSlurp 的代码片段如下所示:
void DDGifSlurp(GifInfo *info, bool decode, bool exitAfterFrame) {
...
do {
...
switch (RecordType) {
case IMAGE_DESC_RECORD_TYPE:
if (DGifGetImageDesc(gifFilePtr, isInitialPass) == GIF_ERROR) { <-- [a]
break;
}
...
if (decode) {
...
const uint_fast32_t newRasterSize = gifFilePtr->Image.Width * gifFilePtr->Image.Height;
if (newRasterSize > info->rasterSize || widthOverflow > 0 || heightOverflow > 0) {
void *tmpRasterBits = reallocarray(info->rasterBits, newRasterSize, sizeof(GifPixelType));
...
}
}while (RecordType != TERMINATE_RECORD_TYPE);
}
具有以下格式的 GIF 图像会导致崩溃: