已合并
PixelMap 代码安全检视风险问题修复 #5793
PixelMap 代码安全检视风险问题修复 #5793
已合并
多面体创建于 8月18日
共 3 个文件变更+63-20
@@ -15,6 +15,7 @@
15 15 
16#include "image_source.h"16#include "image_source.h"
17 17 
18+#include <algorithm>
18#include <cstdlib>19#include <cstdlib>
19#include <cstring>20#include <cstring>
20#include <limits>21#include <limits>
@@ -302,7 +303,8 @@ static size_t GetAstcSizeBytes(const uint8_t *fileBuf, size_t fileSize)
302 303 
303static void FreeAllExtMemSut(AstcOutInfo &astcInfo)304static void FreeAllExtMemSut(AstcOutInfo &astcInfo)
304{305{
305- for (uint8_t idx = 0; idx < astcInfo.expandNums; idx++) {306+ uint8_t maxIdx = std::min(static_cast<uint8_t>(EXPAND_ASTC_INFO_MAX_DEC), astcInfo.expandNums);
307+ for (uint8_t idx = 0; idx < maxIdx; idx++) {
306 if (astcInfo.expandInfoBuf[idx] != nullptr) {308 if (astcInfo.expandInfoBuf[idx] != nullptr) {
307 free(astcInfo.expandInfoBuf[idx]);309 free(astcInfo.expandInfoBuf[idx]);
308 }310 }
@@ -315,9 +317,18 @@ static bool FillAstcSutExtInfo(AstcOutInfo &astcInfo, SutInInfo &sutInfo)
315 CHECK_ERROR_RETURN_RET_LOG(cond, false, "[ImageSource] SUT dec getExpandInfoFromSutFunc_ is nullptr!");317 CHECK_ERROR_RETURN_RET_LOG(cond, false, "[ImageSource] SUT dec getExpandInfoFromSutFunc_ is nullptr!");
316 cond = !g_sutDecSoManager.getExpandInfoFromSutFunc_(sutInfo, astcInfo, false);318 cond = !g_sutDecSoManager.getExpandInfoFromSutFunc_(sutInfo, astcInfo, false);
317 CHECK_ERROR_RETURN_RET_LOG(cond, false, "[ImageSource] GetExpandInfoFromSut failed!");319 CHECK_ERROR_RETURN_RET_LOG(cond, false, "[ImageSource] GetExpandInfoFromSut failed!");
320+ if (astcInfo.expandNums > EXPAND_ASTC_INFO_MAX_DEC) {
321+ IMAGE_LOGE("[ImageSource] expandNums %{public}d exceeds max %{public}d",
322+ astcInfo.expandNums, EXPAND_ASTC_INFO_MAX_DEC);
323+ return false;
324+ }
318 int32_t expandTotalBytes = 0;325 int32_t expandTotalBytes = 0;
319 for (uint8_t idx = 0; idx < astcInfo.expandNums; idx++) {326 for (uint8_t idx = 0; idx < astcInfo.expandNums; idx++) {
320 astcInfo.expandInfoCapacity[idx] = astcInfo.expandInfoBytes[idx];327 astcInfo.expandInfoCapacity[idx] = astcInfo.expandInfoBytes[idx];
328+ if (astcInfo.expandInfoBytes[idx] <= 0) {
329+ IMAGE_LOGE("[ImageSource] expandInfoBytes[%{public}d] is invalid", idx);
330+ return false;
331+ }
321 astcInfo.expandInfoBuf[idx] = static_cast<uint8_t *>(malloc(astcInfo.expandInfoCapacity[idx]));332 astcInfo.expandInfoBuf[idx] = static_cast<uint8_t *>(malloc(astcInfo.expandInfoCapacity[idx]));
322 if (astcInfo.expandInfoBuf[idx] == nullptr) {333 if (astcInfo.expandInfoBuf[idx] == nullptr) {
323 IMAGE_LOGE("[ImageSource] astcInfo.expandInfoBuf malloc failed!");334 IMAGE_LOGE("[ImageSource] astcInfo.expandInfoBuf malloc failed!");
@@ -331,15 +342,24 @@ static bool FillAstcSutExtInfo(AstcOutInfo &astcInfo, SutInInfo &sutInfo)
331static bool CheckExtInfoForPixelmap(AstcOutInfo &astcInfo, unique_ptr<PixelAstc> &pixelAstc)342static bool CheckExtInfoForPixelmap(AstcOutInfo &astcInfo, unique_ptr<PixelAstc> &pixelAstc)
332{343{
333 uint8_t colorSpace = 0;344 uint8_t colorSpace = 0;
345+ if (astcInfo.expandNums > EXPAND_ASTC_INFO_MAX_DEC) {
346+ IMAGE_LOGE("CheckExtInfoForPixelmap expandNums %{public}d exceeds max", astcInfo.expandNums);
347+ return false;
348+ }
334 for (uint8_t idx = 0; idx < astcInfo.expandNums; idx++) {349 for (uint8_t idx = 0; idx < astcInfo.expandNums; idx++) {
335- if (astcInfo.expandInfoBuf[idx] != nullptr) {350+ if (astcInfo.expandInfoBuf[idx] == nullptr) {
336- switch (static_cast<AstcExtendInfoType>(astcInfo.expandInfoType[idx])) {351+ continue;
337- case AstcExtendInfoType::COLOR_SPACE:352+ }
338- colorSpace = *astcInfo.expandInfoBuf[idx];353+ switch (static_cast<AstcExtendInfoType>(astcInfo.expandInfoType[idx])) {
339- break;354+ case AstcExtendInfoType::COLOR_SPACE:
340- default:355+ if (astcInfo.expandInfoBytes[idx] < 1) {
356+ IMAGE_LOGE("CheckExtInfoForPixelmap COLOR_SPACE expandInfoBytes is invalid");
341 return false;357 return false;
342- }358+ }
359+ colorSpace = *astcInfo.expandInfoBuf[idx];
360+ break;
361+ default:
362+ return false;
343 }363 }
344 }364 }
345#ifdef IMAGE_COLORSPACE_FLAG365#ifdef IMAGE_COLORSPACE_FLAG
@@ -425,6 +445,10 @@ void ReleaseExtendInfoMemory(AstcExtendInfo &extendInfo)
425 445 
426bool HandleMetadataCopy(std::vector<uint8_t>& dest, const uint8_t *src, size_t length)446bool HandleMetadataCopy(std::vector<uint8_t>& dest, const uint8_t *src, size_t length)
427{447{
448+ if (length > MAX_TLV_METADATA_SIZE) {
449+ IMAGE_LOGE("[AstcCodec] HandleMetadataCopy length too large: %{public}zu", length);
450+ return false;
451+ }
428 dest.resize(length);452 dest.resize(length);
429 if (memcpy_s(dest.data(), length, src, length) != 0) {453 if (memcpy_s(dest.data(), length, src, length) != 0) {
430 IMAGE_LOGE("[AstcCodec] WriteAstcExtendInfo memcpy failed!");454 IMAGE_LOGE("[AstcCodec] WriteAstcExtendInfo memcpy failed!");
@@ -491,9 +515,17 @@ static bool GetExtInfoForPixelAstc(AstcExtendInfo &extInfo, unique_ptr<PixelAstc
491 515 
492 switch (infoType) {516 switch (infoType) {
493 case AstcExtendInfoType::COLOR_SPACE:517 case AstcExtendInfoType::COLOR_SPACE:
518+ if (infoLength < 1) {
519+ IMAGE_LOGE("GetExtInfoForPixelAstc COLOR_SPACE infoLength is 0");
520+ return false;
521+ }
494 colorSpace = *infoValue;522 colorSpace = *infoValue;
495 break;523 break;
496 case AstcExtendInfoType::PIXEL_FORMAT:524 case AstcExtendInfoType::PIXEL_FORMAT:
525+ if (infoLength < 1) {
526+ IMAGE_LOGE("GetExtInfoForPixelAstc PIXEL_FORMAT infoLength is 0");
527+ return false;
528+ }
497 pixelFmt = *infoValue;529 pixelFmt = *infoValue;
498 break;530 break;
499 case AstcExtendInfoType::HDR_METADATA_TYPE:531 case AstcExtendInfoType::HDR_METADATA_TYPE:
@@ -1773,7 +1773,7 @@ bool PixelMap::ARGB8888ToARGB(const uint8_t *in, uint32_t inCount, uint32_t *out
1773 IMAGE_LOGE("ARGB8888ToARGB invalid input parameter: in or out is null");1773 IMAGE_LOGE("ARGB8888ToARGB invalid input parameter: in or out is null");
1774 return false;1774 return false;
1775 }1775 }
1776- if (((inCount / ARGB_8888_BYTES) != outCount) && ((inCount % ARGB_8888_BYTES) != 0)) {1776+ if (((inCount / ARGB_8888_BYTES) != outCount) || ((inCount % ARGB_8888_BYTES) != 0)) {
1777 IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);1777 IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);
1778 return false;1778 return false;
1779 }1779 }
@@ -1792,7 +1792,7 @@ bool PixelMap::RGBA8888ToARGB(const uint8_t *in, uint32_t inCount, uint32_t *out
1792 IMAGE_LOGE("RGBA8888ToARGB invalid input parameter: in or out is null");1792 IMAGE_LOGE("RGBA8888ToARGB invalid input parameter: in or out is null");
1793 return false;1793 return false;
1794 }1794 }
1795- if (((inCount / ARGB_8888_BYTES) != outCount) && ((inCount % ARGB_8888_BYTES) != 0)) {1795+ if (((inCount / ARGB_8888_BYTES) != outCount) || ((inCount % ARGB_8888_BYTES) != 0)) {
1796 IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);1796 IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);
1797 return false;1797 return false;
1798 }1798 }
@@ -1811,7 +1811,7 @@ bool PixelMap::BGRA8888ToARGB(const uint8_t *in, uint32_t inCount, uint32_t *out
1811 IMAGE_LOGE("BGRA8888ToARGB invalid input parameter: in or out is null");1811 IMAGE_LOGE("BGRA8888ToARGB invalid input parameter: in or out is null");
1812 return false;1812 return false;
1813 }1813 }
1814- if (((inCount / ARGB_8888_BYTES) != outCount) && ((inCount % ARGB_8888_BYTES) != 0)) {1814+ if (((inCount / ARGB_8888_BYTES) != outCount) || ((inCount % ARGB_8888_BYTES) != 0)) {
1815 IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);1815 IMAGE_LOGE("input count:%{public}u is not match to output count:%{public}u.", inCount, outCount);
1816 return false;1816 return false;
1817 }1817 }
@@ -2043,10 +2043,10 @@ uint32_t PixelMap::ReadPixels(const uint64_t &bufferSize, uint8_t *dst)
2043 uint64_t tmpSize = 0;2043 uint64_t tmpSize = 0;
2044 uint64_t readSize = MAX_READ_COUNT;2044 uint64_t readSize = MAX_READ_COUNT;
2045 while (tmpSize < bufferSize && tmpSize < pixelsSize_) {2045 while (tmpSize < bufferSize && tmpSize < pixelsSize_) {
2046- if (tmpSize + MAX_READ_COUNT > bufferSize) {2046+ if (tmpSize + MAX_READ_COUNT > pixelsSize_) {
2047- readSize = bufferSize - tmpSize;
2048- } else if (tmpSize + MAX_READ_COUNT > pixelsSize_) {
2049 readSize = pixelsSize_ - tmpSize;2047 readSize = pixelsSize_ - tmpSize;
2048+ } else if (tmpSize + MAX_READ_COUNT > bufferSize) {
2049+ readSize = bufferSize - tmpSize;
2050 }2050 }
2051 errno_t ret = memcpy_s(dst + tmpSize, readSize, data_ + tmpSize, readSize);2051 errno_t ret = memcpy_s(dst + tmpSize, readSize, data_ + tmpSize, readSize);
2052 if (ret != 0) {2052 if (ret != 0) {
@@ -2381,8 +2381,7 @@ uint32_t PixelMap::WritePixels(const RWPixelsOptions &opts)
2381 return ERR_IMAGE_WRITE_PIXELMAP_FAILED;2381 return ERR_IMAGE_WRITE_PIXELMAP_FAILED;
2382 }2382 }
2383 void *colors = tempPixels.get();2383 void *colors = tempPixels.get();
2384- ImageInfo tempInfo = MakeImageInfo(2384+ ImageInfo tempInfo = MakeImageInfo(opts.region.width, opts.region.height, PixelFormat::ARGB_8888,
2385- opts.region.width, opts.region.height, PixelFormat::ARGB_8888,
2386 AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);2385 AlphaType::IMAGE_ALPHA_TYPE_UNPREMUL);
2387 BufferInfo dstInfo = {colors, 0, tempInfo};2386 BufferInfo dstInfo = {colors, 0, tempInfo};
2388 const void *pixels = opts.pixels;2387 const void *pixels = opts.pixels;
@@ -3220,9 +3219,13 @@ bool ReadDmaMemInfoFromParcel(Parcel &parcel, const ImageInfo &imgInfo, PixelMem
3220 return false;3219 return false;
3221 }3220 }
3222 if (!pixelMemInfo.displayOnly) {3221 if (!pixelMemInfo.displayOnly) {
3223- pixelMemInfo.base = surfaceBuffer->GetVirAddr() == nullptr3222+ pixelMemInfo.base = static_cast<uint8_t *>(surfaceBuffer->GetVirAddr());
3224- ? nullptr3223+ if (pixelMemInfo.base == nullptr) {
3225- : static_cast<uint8_t *>(surfaceBuffer->GetVirAddr());3224+ IMAGE_LOGE("ReadDmaMemInfoFromParcel GetVirAddr is nullptr for non-displayOnly");
3225+ ImageUtils::SurfaceBuffer_Unreference(nativeBuffer);
3226+ pixelMemInfo.context = nullptr;
3227+ return false;
3228+ }
3226 }3229 }
3227 pixelMemInfo.context = nativeBuffer;3230 pixelMemInfo.context = nativeBuffer;
3228 return true;3231 return true;
@@ -4331,7 +4334,7 @@ uint32_t PixelMap::ConvertAlphaFormat(PixelMap &wPixelMap, const bool isPremul)
4331 int8_t srcAlphaIndex = GetAlphaIndex(srcPixelFormat);4334 int8_t srcAlphaIndex = GetAlphaIndex(srcPixelFormat);
4332 int32_t index = 0;4335 int32_t index = 0;
4333 for (int32_t i = 0; i < imageInfo_.size.height; ++i) {4336 for (int32_t i = 0; i < imageInfo_.size.height; ++i) {
4334- for (int32_t j = 0; j < stride; j+=pixelBytes_) {4337+ for (int32_t j = 0; j < stride; j += pixelBytes_) {
4335 index = i * stride + j;4338 index = i * stride + j;
4336 ConvertUintPixelAlpha(data_ + index, pixelBytes_, srcAlphaIndex, isPremul,4339 ConvertUintPixelAlpha(data_ + index, pixelBytes_, srcAlphaIndex, isPremul,
4337 static_cast<uint8_t*>(dstData) + index);4340 static_cast<uint8_t*>(dstData) + index);
@@ -750,6 +750,10 @@ static void FillAstcEncCheckInfo(AstcEncCheckInfo &checkInfo, Media::PixelMap* a
750 750 
751static bool CheckAstcEncInput(TextureEncodeOptions &param, AstcEncCheckInfo checkInfo)751static bool CheckAstcEncInput(TextureEncodeOptions &param, AstcEncCheckInfo checkInfo)
752{752{
753+ if (static_cast<uint32_t>(param.stride_) > (std::numeric_limits<uint32_t>::max() >> RGBA_BYTES_PIXEL_LOG2)) {
754+ IMAGE_LOGE("CheckAstcEncInput stride %{public}d too large!", param.stride_);
755+ return false;
756+ }
753 uint32_t pixmapStride = static_cast<uint32_t>(param.stride_) << RGBA_BYTES_PIXEL_LOG2;757 uint32_t pixmapStride = static_cast<uint32_t>(param.stride_) << RGBA_BYTES_PIXEL_LOG2;
754 if ((param.width_ <= 0) || (param.height_ <= 0) || (param.stride_ < param.width_)) {758 if ((param.width_ <= 0) || (param.height_ <= 0) || (param.stride_ < param.width_)) {
755 IMAGE_LOGE("CheckAstcEncInput width <= 0 or height <= 0 or stride < width!");759 IMAGE_LOGE("CheckAstcEncInput width <= 0 or height <= 0 or stride < width!");
@@ -813,6 +817,10 @@ uint32_t AstcCodec::AstcSoftwareEncode(TextureEncodeOptions &param, bool enableQ
813 IMAGE_LOGE("CheckAstcEncInput failed");817 IMAGE_LOGE("CheckAstcEncInput failed");
814 return ERROR;818 return ERROR;
815 }819 }
820+ if (outBuffer == nullptr || outSize <= 0 || outSize < param.astcBytes) {
821+ IMAGE_LOGE("AstcSoftwareEncode invalid outBuffer or outSize %{public}d < astcBytes", outSize);
822+ return ERROR;
823+ }
816 if (!AstcSoftwareEncodeCore(param, pixmapIn, outBuffer)) {824 if (!AstcSoftwareEncodeCore(param, pixmapIn, outBuffer)) {
817 IMAGE_LOGE("AstcSoftwareEncodeCore failed");825 IMAGE_LOGE("AstcSoftwareEncodeCore failed");
818 return ERROR;826 return ERROR;