已合并
PixelMap 代码安全检视风险问题修复 #5793
多面体创建于 8月18日
PixelMap 代码安全检视风险问题修复 #5793
已合并
共 3 个文件变更+63-20
| @@ -15,6 +15,7 @@ | |||
| 15 | 15 | ||
| 16 | 16 | ||
| 17 | 17 | ||
| 18 | + | ||
| 18 | 19 | ||
| 19 | 20 | ||
| 20 | 21 | ||
| @@ -302,7 +303,8 @@ static size_t GetAstcSizeBytes(const uint8_t *fileBuf, size_t fileSize) | |||
| 302 | 303 | ||
| 303 | static void FreeAllExtMemSut(AstcOutInfo &astcInfo) | 304 | static 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) | |||
| 331 | static bool CheckExtInfoForPixelmap(AstcOutInfo &astcInfo, unique_ptr<PixelAstc> &pixelAstc) | 342 | static 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 | 365 | ||
| @@ -425,6 +445,10 @@ void ReleaseExtendInfoMemory(AstcExtendInfo &extendInfo) | |||
| 425 | 445 | ||
| 426 | bool HandleMetadataCopy(std::vector<uint8_t>& dest, const uint8_t *src, size_t length) | 446 | bool 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() == nullptr | 3222 | + pixelMemInfo.base = static_cast<uint8_t *>(surfaceBuffer->GetVirAddr()); |
| 3224 | - ? nullptr | 3223 | + 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 | ||
| 751 | static bool CheckAstcEncInput(TextureEncodeOptions ¶m, AstcEncCheckInfo checkInfo) | 751 | static bool CheckAstcEncInput(TextureEncodeOptions ¶m, 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 ¶m, 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; |