diff --git a/frameworks/innerkitsimpl/common/src/native_image.cpp b/frameworks/innerkitsimpl/common/src/native_image.cpp index eee8fe05889a4c4673fa33a4e38972f6a8950ca7..fb384d417ed0dbd656b266a50573b16746fe3c0c 100644 --- a/frameworks/innerkitsimpl/common/src/native_image.cpp +++ b/frameworks/innerkitsimpl/common/src/native_image.cpp @@ -15,6 +15,7 @@ #include #include "image_log.h" +#include "image_utils.h" #include "media_errors.h" #include "native_image.h" @@ -122,8 +123,12 @@ int32_t NativeImage::SplitYUV422SPComponent() struct YUVData yuv; uint64_t uvStride = static_cast((width + NUM_1) / NUM_2); - yuv.ySize = static_cast(width * height); - yuv.uvSize = static_cast(height * uvStride); + if (ImageUtils::CheckMulOverflow(width, height)) { + IMAGE_LOGE("Invalid width %{public}" PRId32 " height %{public}" PRId32, width, height); + return ERR_MEDIA_DATA_UNSUPPORT; + } + yuv.ySize = static_cast(width) * static_cast(height); + yuv.uvSize = static_cast(height) * uvStride; if (surfaceSize < (yuv.ySize + yuv.uvSize * NUM_2)) { IMAGE_LOGE("S size %{public}" PRIu64 " < y plane %{public}" PRIu64 " + uv plane %{public}" PRIu64, surfaceSize, yuv.ySize, yuv.uvSize * NUM_2); diff --git a/frameworks/innerkitsimpl/common/src/pixel_map.cpp b/frameworks/innerkitsimpl/common/src/pixel_map.cpp index f980100400a5de402433326163b8d795645eb530..46cd80d50bbc4a8617d021c7ab41a05c7d4e2fb4 100644 --- a/frameworks/innerkitsimpl/common/src/pixel_map.cpp +++ b/frameworks/innerkitsimpl/common/src/pixel_map.cpp @@ -1486,7 +1486,11 @@ bool PixelMap::IsSameImage(const PixelMap &other) IMAGE_LOGI("IsSameImage imageInfo is not same"); return false; } - uint64_t size = static_cast(rowDataSize_) * imageInfo_.size.height; + if (ImageUtils::CheckMulOverflow(rowDataSize_, imageInfo_.size.height)) { + IMAGE_LOGI("IsSameImage imageInfo is invalid"); + return false; + } + uint64_t size = static_cast(rowDataSize_) * static_cast(imageInfo_.size.height); if (memcmp(data_, other.data_, size) != 0) { IMAGE_LOGI("IsSameImage memcmp is not same"); return false; @@ -1695,7 +1699,12 @@ uint32_t PixelMap::ResetConfig(const Size &size, const PixelFormat &format) IMAGE_LOGE("ResetConfig get bytes by per pixel fail."); return ERR_IMAGE_INVALID_PARAMETER; } - uint64_t dstSize = static_cast(size.width) * size.height * bytesPerPixel; + if (ImageUtils::CheckMulOverflow(size.width, size.height, bytesPerPixel)) { + IMAGE_LOGE("ResetConfig reset input width(%{public}d) or height(%{public}d) is invalid.", size.width, + size.height); + return ERR_IMAGE_INVALID_PARAMETER; + } + uint64_t dstSize = static_cast(size.width) * static_cast(size.height) * bytesPerPixel; if (dstSize > static_cast(pixelsSize_)) { IMAGE_LOGE("ResetConfig reset dstSize(%{public}llu) > current(%{public}u).", static_cast(dstSize), pixelsSize_); diff --git a/frameworks/innerkitsimpl/converter/src/basic_transformer.cpp b/frameworks/innerkitsimpl/converter/src/basic_transformer.cpp index d22b6555db1caed0ce2d9a254cc537abfd7d2a61..e68e95c6bc5f9a28b7b5913e7a0bb723d688d224 100644 --- a/frameworks/innerkitsimpl/converter/src/basic_transformer.cpp +++ b/frameworks/innerkitsimpl/converter/src/basic_transformer.cpp @@ -174,12 +174,15 @@ uint32_t BasicTransformer::TransformPixmap(const PixmapInfo &inPixmap, PixmapInf Size dstSize = inPixmap.imageInfo.size; GetDstDimension(inPixmap.imageInfo.size, dstSize); outPixmap.imageInfo.size = dstSize; - if (dstSize.width <= 0 || dstSize.height <= 0) { + if (dstSize.width <= 0 || dstSize.height <= 0 || + ImageUtils::CheckMulOverflow(dstSize.width, dstSize.height, pixelBytes)) { IMAGE_LOGE("[BasicTransformer]buffer size is invalid."); return ERR_IMAGE_ALLOC_MEMORY_FAILED; } - uint64_t bufferSize = static_cast(dstSize.width) * dstSize.height * pixelBytes; + uint64_t bufferSize = static_cast(dstSize.width) * + static_cast(dstSize.height) * + static_cast(pixelBytes); if (bufferSize > PIXEL_MAP_MAX_RAM_SIZE) { IMAGE_LOGE("[BasicTransformer] buffer size:%{public}llu out of range.", static_cast(bufferSize)); diff --git a/frameworks/innerkitsimpl/converter/src/post_proc.cpp b/frameworks/innerkitsimpl/converter/src/post_proc.cpp index 3ba78f2cc31ce072fc1ec009b4110f82164ce9ce..a33d656a925afd8d8b90b51fe5b76f05e2b4402b 100644 --- a/frameworks/innerkitsimpl/converter/src/post_proc.cpp +++ b/frameworks/innerkitsimpl/converter/src/post_proc.cpp @@ -305,7 +305,14 @@ bool PostProc::ProcessScanlineFilter(ScanlineFilter &scanlineFilter, const Rect uint32_t PostProc::CheckScanlineFilter(const Rect &cropRect, ImageInfo &dstImageInfo, PixelMap &pixelMap, int32_t pixelBytes, ScanlineFilter &scanlineFilter) { - uint64_t bufferSize = static_cast(dstImageInfo.size.width) * dstImageInfo.size.height * pixelBytes; + if (ImageUtils::CheckMulOverflow(dstImageInfo.size.width, dstImageInfo.size.height, pixelBytes)) { + IMAGE_LOGE("[PostProc]size is too large, width:%{public}d, height:%{public}d", + dstImageInfo.size.width, dstImageInfo.size.height); + return ERR_IMAGE_CROP; + } + uint64_t bufferSize = static_cast(dstImageInfo.size.width) * + static_cast(dstImageInfo.size.height) * + static_cast(pixelBytes); uint8_t *resultData = nullptr; int fd = 0; if (decodeOpts_.allocatorType == AllocatorType::SHARE_MEM_ALLOC) { @@ -428,7 +435,9 @@ uint32_t PostProc::AllocBuffer(ImageInfo imageInfo, uint8_t **resultData, uint64 imageInfo.size.width, imageInfo.size.height); return ERR_IMAGE_CROP; } - bufferSize = static_cast(imageInfo.size.width) * imageInfo.size.height * pixelBytes; + bufferSize = static_cast(imageInfo.size.width) * + static_cast(imageInfo.size.height) * + static_cast(pixelBytes); IMAGE_LOGD("[PostProc]size.width:%{public}d, size.height:%{public}d, bufferSize:%{public}lld", imageInfo.size.width, imageInfo.size.height, static_cast(bufferSize)); if (decodeOpts_.allocatorType == AllocatorType::SHARE_MEM_ALLOC) { diff --git a/frameworks/innerkitsimpl/utils/src/image_utils.cpp b/frameworks/innerkitsimpl/utils/src/image_utils.cpp index 1e221b1399b3294ed009cfd5d12df93ecbf25066..17546e0dc759ba7c8587bfceb766f7223bba78e4 100644 --- a/frameworks/innerkitsimpl/utils/src/image_utils.cpp +++ b/frameworks/innerkitsimpl/utils/src/image_utils.cpp @@ -383,7 +383,7 @@ bool ImageUtils::CheckMulOverflow(int32_t width, int32_t bytesPerPixel) IMAGE_LOGE("param is 0"); return true; } - int64_t rowSize = static_cast(width) * bytesPerPixel; + int32_t rowSize = width * bytesPerPixel; if ((rowSize / width) != bytesPerPixel) { IMAGE_LOGE("width * bytesPerPixel overflow!"); return true; @@ -397,12 +397,12 @@ bool ImageUtils::CheckMulOverflow(int32_t width, int32_t height, int32_t bytesPe IMAGE_LOGE("param is 0"); return true; } - int64_t rectSize = static_cast(width) * height; + int32_t rectSize = width * height; if ((rectSize / width) != height) { IMAGE_LOGE("width * height overflow!"); return true; } - int64_t bufferSize = rectSize * bytesPerPixel; + int32_t bufferSize = rectSize * bytesPerPixel; if ((bufferSize / bytesPerPixel) != rectSize) { IMAGE_LOGE("bytesPerPixel overflow!"); return true; diff --git a/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp b/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp index a3596ce092eec3d661f7c2cf19c0751456baf8a5..3a130f4cbb3b7cb4a2d9f0050f50dd261c1675dc 100644 --- a/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp +++ b/plugins/common/libs/image/libextplugin/src/ext_decoder.cpp @@ -1085,7 +1085,13 @@ uint32_t ExtDecoder::AllocOutputBuffer(DecodeContext &context, OHOS::HDI::Codec::Image::V2_0::CodecImageBuffer& outputBuffer) { ImageTrace imageTrace("Ext AllocOutputBuffer"); - uint64_t byteCount = static_cast(hwDstInfo_.height() * hwDstInfo_.width() * hwDstInfo_.bytesPerPixel()); + if (ImageUtils::CheckMulOverflow(hwDstInfo_.height(), hwDstInfo_.width(), hwDstInfo_.bytesPerPixel())) { + IMAGE_LOGE("Invalid dstInfo height:%{public}d, width:%{public}d", hwDstInfo_.height(), hwDstInfo_.width()); + return ERR_IMAGE_DECODE_ABNORMAL; + } + uint64_t byteCount = static_cast(hwDstInfo_.height()) * + static_cast(hwDstInfo_.width()) * + static_cast(hwDstInfo_.bytesPerPixel()); uint32_t ret = DmaMemAlloc(context, byteCount, hwDstInfo_); if (ret != SUCCESS) { IMAGE_LOGE("Alloc OutputBuffer failed, ret=%{public}d", ret); diff --git a/plugins/common/libs/image/libgifplugin/src/gif_decoder.cpp b/plugins/common/libs/image/libgifplugin/src/gif_decoder.cpp index b3ff06e214bdfbf9e4d23f2466b8ed57c9a75ae1..495ade7891fbea7f9c65df735a45ffbe5af7a63a 100644 --- a/plugins/common/libs/image/libgifplugin/src/gif_decoder.cpp +++ b/plugins/common/libs/image/libgifplugin/src/gif_decoder.cpp @@ -348,7 +348,13 @@ uint32_t GifDecoder::AllocateLocalPixelMapBuffer() if (localPixelMapBuffer_ == nullptr) { int32_t bgWidth = gifPtr_->SWidth; int32_t bgHeight = gifPtr_->SHeight; - uint64_t pixelMapBufferSize = static_cast(bgWidth * bgHeight * sizeof(uint32_t)); + if (ImageUtils::CheckMulOverflow(bgWidth, bgHeight, sizeof(uint32_t))) { + IMAGE_LOGE("[AllocateLocalPixelMapBuffer]size is invalid, width:%{public}d, height:%{public}d", + bgWidth, bgHeight); + return ERR_IMAGE_TOO_LARGE; + } + uint64_t pixelMapBufferSize = static_cast(bgWidth) * + static_cast(bgHeight) * sizeof(uint32_t); // create local pixelmap buffer, next frame depends on the previous if (pixelMapBufferSize > PIXEL_MAP_MAX_RAM_SIZE) { IMAGE_LOGE("[AllocateLocalPixelMapBuffer]pixelmap buffer size %{public}llu out of max size", @@ -704,7 +710,13 @@ uint32_t GifDecoder::RedirectOutputBuffer(DecodeContext &context) } int32_t bgWidth = gifPtr_->SWidth; int32_t bgHeight = gifPtr_->SHeight; - uint64_t imageBufferSize = static_cast(bgWidth * bgHeight * sizeof(uint32_t)); + if (ImageUtils::CheckMulOverflow(bgWidth, bgHeight, sizeof(uint32_t))) { + IMAGE_LOGE("[RedirectOutputBuffer]size is invalid, width:%{public}d, height:%{public}d", + bgWidth, bgHeight); + return ERR_IMAGE_TOO_LARGE; + } + uint64_t imageBufferSize = static_cast(bgWidth) * + static_cast(bgHeight) * sizeof(uint32_t); uint32_t allocRes = SUCCESS; if (context.pixelsBuffer.buffer == nullptr) { context.pixelsBuffer.bufferSize = imageBufferSize; @@ -814,7 +826,14 @@ uint32_t GifDecoder::ParseFrameDetail() SavedImage *saveImagePtr = &gifPtr_->SavedImages[frameIndex]; int32_t imageWidth = saveImagePtr->ImageDesc.Width; int32_t imageHeight = saveImagePtr->ImageDesc.Height; - uint64_t imageSize = static_cast(imageWidth * imageHeight); + if (ImageUtils::CheckMulOverflow(imageWidth, imageHeight)) { + IMAGE_LOGE("[ParseFrameDetail]size is invalid, size: [%{public}d, %{public}d]", imageWidth, + imageHeight); + // if error, imageCount go back and next time DGifGetImageDesc will retry. + gifPtr_->ImageCount--; + return ERR_IMAGE_DECODE_ABNORMAL; + } + uint64_t imageSize = static_cast(imageWidth) * static_cast(imageHeight); if (imageWidth <= 0 || imageHeight <= 0 || imageSize > SIZE_MAX) { IMAGE_LOGE("[ParseFrameDetail]check frame size[%{public}d, %{public}d] failed", imageWidth, imageHeight); diff --git a/plugins/common/libs/image/libjpegplugin/src/jpeg_decoder.cpp b/plugins/common/libs/image/libjpegplugin/src/jpeg_decoder.cpp index 838702006a2ef33a0496c97e41044123bbfdff01..5cd5c8989449d0bdd5bec487126c3e6705f3a7fd 100644 --- a/plugins/common/libs/image/libjpegplugin/src/jpeg_decoder.cpp +++ b/plugins/common/libs/image/libjpegplugin/src/jpeg_decoder.cpp @@ -360,7 +360,11 @@ uint32_t JpegDecoder::DoSwDecode(DecodeContext &context) __attribute__((no_sanit } uint32_t rowStride = GetRowBytes(); if (context.pixelsBuffer.buffer == nullptr) { - uint64_t byteCount = static_cast(rowStride) * decodeInfo_.output_height; + if (ImageUtils::CheckMulOverflow(rowStride, decodeInfo_.output_height)) { + IMAGE_LOGE("invalid size."); + return ERR_IMAGE_DECODE_ABNORMAL; + } + uint64_t byteCount = static_cast(rowStride) * static_cast(decodeInfo_.output_height); #if !defined(_WIN32) && !defined(_APPLE) && !defined(ANDROID_PLATFORM) && !defined(IOS_PLATFORM) if (context.allocatorType == Media::AllocatorType::SHARE_MEM_ALLOC) { uint32_t id = context.pixelmapUniqueId_;