From 15714741b21810a9b768361a4ae24cf89084b84d Mon Sep 17 00:00:00 2001 From: hjkim Date: Tue, 14 Jan 2025 12:11:43 +0900 Subject: [PATCH] Check image size before assigning memory [Issue] A crash occurred while allocating big-size memory due to incorrect size. Fix fuzzying issues Change-Id: Ia65dbea977544afe5cf4e802bf659596ef84310b --- common/include/mm_util_private.h | 4 +++- common/mm_util_private.c | 9 +++++++++ gif/mm_util_gif.c | 17 ++++++++++++++--- imgp/mm_util_imgp.c | 3 +++ jpeg/mm_util_jpeg.c | 5 +++++ jxl/mm_util_jxl.c | 13 +++++++++---- 6 files changed, 43 insertions(+), 8 deletions(-) diff --git a/common/include/mm_util_private.h b/common/include/mm_util_private.h index 5a5f87a..b49daec 100644 --- a/common/include/mm_util_private.h +++ b/common/include/mm_util_private.h @@ -30,7 +30,7 @@ extern "C" { #endif -#define MMUTIL_STRING_VALID(str) (str != NULL && strlen(str) > 0) +#define MMUTIL_STRING_VALID(str) (str != NULL && strlen(str) > 0) /* for alignment */ #define MM_UTIL_ROUND_UP_2(num) (((num)+1)&~1) @@ -79,6 +79,8 @@ int mm_util_file_write(const char *path, void *data, size_t size); // for reading ini int mm_util_ini_get_int(const char *category, const char *item, int default_value); +bool mm_util_is_proper_image_size(size_t size); + #ifdef __cplusplus } #endif diff --git a/common/mm_util_private.c b/common/mm_util_private.c index 2f9eb42..229810c 100644 --- a/common/mm_util_private.c +++ b/common/mm_util_private.c @@ -24,6 +24,7 @@ #include "mm_util_private.h" #define IMAGE_UTIL_INI_PATH SYSCONFDIR"/multimedia/mmfw_image_util.ini" +#define MAX_RAW_IMG_SIZE (512 * 1024 * 1024) int mm_util_safe_fopen(const char *path, const char *mode, FILE **fp) { @@ -171,3 +172,11 @@ bool mm_util_safe_str_to_valid_uint(const char *str, unsigned int min, unsigned *value = converted; return true; } + +bool mm_util_is_proper_image_size(size_t size) +{ + mm_util_retvm_if(size == 0, false, "size is 0"); + mm_util_retvm_if(size >= MAX_RAW_IMG_SIZE, false, "size is too large"); + + return true; +} diff --git a/gif/mm_util_gif.c b/gif/mm_util_gif.c index 13f388a..67a098b 100644 --- a/gif/mm_util_gif.c +++ b/gif/mm_util_gif.c @@ -184,16 +184,21 @@ static int __gif_get_extension(GifFileType *gif_image) return MM_UTIL_ERROR_NONE; } -static void __gif_convert_to_rgba(void **data, ColorMapObject *color_map, GifRowType *frame_buffer, unsigned int width, unsigned int height) +static int __gif_convert_to_rgba(void **data, ColorMapObject *color_map, GifRowType *frame_buffer, unsigned int width, unsigned int height) { unsigned int i, j; GifRowType gif_row; GifColorType *color_map_entry; GifByteType *buffer; + size_t data_size = 0; mm_util_fenter(); - *data = g_malloc0(width * height * 4); + data_size = width * height * 4; + if (!mm_util_is_proper_image_size(data_size)) + return MM_UTIL_ERROR_OUT_OF_MEMORY; + + *data = g_malloc0(data_size); buffer = (GifByteType *) *data; for (i = 0; i < height; i++) { @@ -206,6 +211,8 @@ static void __gif_convert_to_rgba(void **data, ColorMapObject *color_map, GifRow *buffer++ = 255; } } + + return MM_UTIL_ERROR_NONE; } static int __read_gif(const char *file_path, void *memory, const size_t src_size, mm_util_image_h *decoded) @@ -287,7 +294,11 @@ static int __read_gif(const char *file_path, void *memory, const size_t src_size } /* decompress image with colormap(256) */ - __gif_convert_to_rgba(&image_buffer, ColorMap, frame_buffer, GifFile->SWidth, GifFile->SHeight); + ret = __gif_convert_to_rgba(&image_buffer, ColorMap, frame_buffer, GifFile->SWidth, GifFile->SHeight); + if (ret != MM_UTIL_ERROR_NONE) { + mm_util_error("__gif_convert_to_rgba failed"); + goto error; + } ret = mm_image_create_image(GifFile->SWidth, GifFile->SHeight, MM_UTIL_COLOR_RGBA, image_buffer, GifFile->SWidth * GifFile->SHeight * 4, decoded); g_free(image_buffer); diff --git a/imgp/mm_util_imgp.c b/imgp/mm_util_imgp.c index 7967d56..3368283 100644 --- a/imgp/mm_util_imgp.c +++ b/imgp/mm_util_imgp.c @@ -616,6 +616,9 @@ int mm_util_crop_image(mm_util_image_h src, unsigned int start_x, unsigned int s __mm_util_get_image_size(_src->color, _width, _height, true, &_buffer_size); mm_util_retvm_if(!_buffer_size, MM_UTIL_ERROR_INVALID_OPERATION, "fail to get dst_buf_size"); + if (!mm_util_is_proper_image_size(_buffer_size)) + return MM_UTIL_ERROR_OUT_OF_MEMORY; + _buffer = g_malloc0(_buffer_size); switch (_src->color) { diff --git a/jpeg/mm_util_jpeg.c b/jpeg/mm_util_jpeg.c index f69c469..7e91378 100644 --- a/jpeg/mm_util_jpeg.c +++ b/jpeg/mm_util_jpeg.c @@ -429,6 +429,11 @@ static int __mm_util_jpeg_decode(mm_util_jpeg_ctrl_format_e control_format, FILE goto END; } + if (!mm_util_is_proper_image_size(image_buffer_size)) { + ret = MM_UTIL_ERROR_OUT_OF_MEMORY; + goto END; + } + image_buffer = g_malloc0(image_buffer_size); mm_util_debug("decoded_data->data"); diff --git a/jxl/mm_util_jxl.c b/jxl/mm_util_jxl.c index 6c428ac..ccda906 100644 --- a/jxl/mm_util_jxl.c +++ b/jxl/mm_util_jxl.c @@ -221,14 +221,19 @@ static int __mm_util_decode_jpegxl(const void *buf, size_t buf_size, mm_util_col status = JxlDecoderImageOutBufferSize(jxl_dec, jxl_format, &pixels_size); if (status != JXL_DEC_SUCCESS) { - mm_util_error("failed to JxlDecoderImageOutBufferSize(%d)", status); - goto Exit; + mm_util_error("failed to JxlDecoderImageOutBufferSize(%d)", status); + goto Exit; + } + + if (!mm_util_is_proper_image_size(pixels_size)) { + status = JXL_DEC_JPEG_NEED_MORE_OUTPUT; + goto Exit; } status = JxlDecoderGetBasicInfo(jxl_dec, &info); if (status != JXL_DEC_SUCCESS) { - mm_util_error("failed to JxlDecoderGetBasicInfo(%d)", status); - goto Exit; + mm_util_error("failed to JxlDecoderGetBasicInfo(%d)", status); + goto Exit; } // calculate the size of output buffer -- 2.34.1