Fix buffer-overflow issue when image was cropped 01/158301/3
authorJiyong Min <jiyong.min@samsung.com>
Tue, 31 Oct 2017 04:03:08 +0000 (13:03 +0900)
committerJiyong Min <jiyong.min@samsung.com>
Wed, 1 Nov 2017 00:25:37 +0000 (09:25 +0900)
Cause: Before image is cropped, the buffer in media packet is allocated.
At this case, the size of cropped image is changed to be multiple by 4.
The size of the buffer in media packet is smaller than the size of cropped image.
So It make buffer-overflow issue.

Solution: It is fixed to allocate the buffer in media_packet after image is cropped.

 - replace media_packet creation to after transform is done.
 - remove unused get_resolution function.
 - add to allocate and free 'handle->dst' buffer to use transform.

Change-Id: I127e7cd45035bd1c5c4277cff835a2e647c65765
Signed-off-by: Jiyong Min <jiyong.min@samsung.com>
imgp/mm_util_imgp.c
packaging/libmm-utility.spec

index f83bd67..0ad1b29 100755 (executable)
@@ -951,24 +951,6 @@ static int __mm_util_processing(mm_util_s *handle)
                return MM_UTIL_ERROR_INVALID_PARAMETER;
        }
 
-       if (handle->src_packet == NULL) {
-               mm_util_error("[src] media_packet_h");
-               return MM_UTIL_ERROR_INVALID_PARAMETER;
-       }
-
-       if (handle->dst_packet == NULL) {
-               mm_util_error("[dst] media_packet_h");
-               return MM_UTIL_ERROR_INVALID_PARAMETER;
-       }
-
-       if (handle->dst_buf_size) {
-               handle->dst = NULL;
-               if (media_packet_get_buffer_data_ptr(handle->dst_packet, &handle->dst) != MM_UTIL_ERROR_NONE) {
-                       mm_util_error("[dst] media_packet_get_extra");
-                       return MM_UTIL_ERROR_INVALID_PARAMETER;
-               }
-       }
-
        mm_util_debug("src: %p, dst: %p", handle->src, handle->dst);
 
        dst_buf[src_index] = g_malloc(handle->src_buf_size);
@@ -1072,6 +1054,12 @@ static int __mm_util_processing(mm_util_s *handle)
        }
 
        if (dst_buf[dst_index] != NULL && dst_buf_size != 0) {
+               handle->dst = calloc(1, dst_buf_size);
+               if (handle->dst == NULL) {
+                       __mm_destroy_temp_buffer(dst_buf);
+                       mm_util_error("memory allocation failed");
+                       return MM_UTIL_ERROR_OUT_OF_MEMORY;
+               }
                memcpy(handle->dst, dst_buf[dst_index], dst_buf_size);
                handle->dst_buf_size = dst_buf_size;
        }
@@ -1145,59 +1133,6 @@ static int __mm_get_info_from_media_packet(media_packet_h pkt, media_format_h *f
        return MM_UTIL_ERROR_NONE;
 }
 
-static int __mm_get_dst_resolution(mm_util_s *handle, unsigned int *width, unsigned int *height)
-{
-       if ((handle == NULL) || (width == NULL) || (height == NULL)) {
-               mm_util_error("Invalid parameter");
-               return MM_UTIL_ERROR_INVALID_PARAMETER;
-       }
-
-       if (handle->set_rotate) {
-               if ((handle->set_crop) || (handle->set_resize)) {
-                       switch (handle->dst_rotation) {
-                       case MM_UTIL_ROTATION_90:
-                       case MM_UTIL_ROTATION_270:
-                               *width = handle->dst_height;
-                               *height = handle->dst_width;
-                               break;
-                       default:
-                               *width = handle->dst_width;
-                               *height = handle->dst_height;
-                               break;
-                       }
-               } else {
-                       switch (handle->dst_rotation) {
-                       case MM_UTIL_ROTATION_90:
-                       case MM_UTIL_ROTATION_270:
-                               *width = handle->dst_width  = handle->src_height;
-                               *height = handle->dst_height = handle->src_width;
-                               break;
-                       case MM_UTIL_ROTATION_NONE:
-                       case MM_UTIL_ROTATION_180:
-                       case MM_UTIL_ROTATION_FLIP_HORZ:
-                       case MM_UTIL_ROTATION_FLIP_VERT:
-                               *width = handle->dst_width  = handle->src_width;
-                               *height = handle->dst_height = handle->src_height;
-                               break;
-                       default:
-                               mm_util_error("[Error] Wrong dst_rotation");
-                               break;
-                       }
-               }
-       } else {
-               if ((handle->set_crop) || (handle->set_resize)) {
-                       *width = handle->dst_width;
-                       *height = handle->dst_height;
-               } else {
-                       *width = handle->dst_width  = handle->src_width;
-                       *height = handle->dst_height = handle->src_height;
-               }
-       }
-       mm_util_debug("dst (%u X %u)", *width, *height);
-
-       return MM_UTIL_ERROR_NONE;
-}
-
 static int __mm_create_media_format(media_format_h fmt, media_format_mimetype_e mimetype, unsigned int width, unsigned int height, media_format_h *new_fmt)
 {
        int err = MEDIA_FORMAT_ERROR_NONE;
@@ -1237,12 +1172,13 @@ static int __mm_create_media_format(media_format_h fmt, media_format_mimetype_e
        return MM_UTIL_ERROR_NONE;
 }
 
-static int __mm_create_media_packet(media_format_h fmt, media_packet_h *pkt, guint *pkt_buf_size)
+static int __mm_create_media_packet_with_buffer(media_format_h fmt, void *buffer, guint buffer_size, media_packet_h *pkt)
 {
        int err = MEDIA_PACKET_ERROR_NONE;
        uint64_t size = 0;
+       void *ptr = NULL;
 
-       if ((fmt == NULL) || (pkt == NULL) || (pkt_buf_size == NULL)) {
+       if ((fmt == NULL) || (pkt == NULL) || (ptr == NULL) || (size == 0)) {
                mm_util_error("Invalid parameter");
                return MM_UTIL_ERROR_INVALID_PARAMETER;
        }
@@ -1250,18 +1186,32 @@ static int __mm_create_media_packet(media_format_h fmt, media_packet_h *pkt, gui
        err = media_packet_create_alloc(fmt, (media_packet_finalize_cb)_mm_util_transform_packet_finalize_callback, NULL, pkt);
        if (err != MEDIA_PACKET_ERROR_NONE) {
                mm_util_error("media_packet_create_alloc failed (%d)", err);
-               return MM_UTIL_ERROR_INVALID_PARAMETER;
+               return MM_UTIL_ERROR_INVALID_OPERATION;
        }
 
        err = media_packet_get_buffer_size(*pkt, &size);
        if (err != MEDIA_PACKET_ERROR_NONE) {
                mm_util_error("media_packet_get_buffer_size failed (%d)", err);
                media_packet_destroy(*pkt);
+               return MM_UTIL_ERROR_INVALID_OPERATION;
+       }
+
+       if (size < buffer_size) {
+               mm_util_error("The buffer(%lu) of media_packet is smaller than result(%d)", size, buffer_size);
+               media_packet_destroy(*pkt);
+               return MM_UTIL_ERROR_INVALID_OPERATION;
+       }
+
+       err = media_packet_get_buffer_data_ptr(*pkt, &ptr);
+       if (err != MM_UTIL_ERROR_NONE) {
+               mm_util_error("[src] media_packet_get_extra");
+               media_packet_destroy(*pkt);
                return MM_UTIL_ERROR_INVALID_PARAMETER;
        }
 
        mm_util_debug("Success - media_packet is created (%p, %lu)", *pkt, size);
-       *pkt_buf_size = (guint)size;
+
+       memcpy(ptr, buffer, buffer_size);
 
        return MM_UTIL_ERROR_NONE;
 }
@@ -1269,54 +1219,52 @@ static int __mm_create_media_packet(media_format_h fmt, media_packet_h *pkt, gui
 static int __mm_util_transform_exec(mm_util_s *handle, media_packet_h src_packet)
 {
        int ret = MM_UTIL_ERROR_NONE;
-       media_format_h src_fmt;
-       media_format_h dst_fmt;
-       unsigned int dst_width = 0, dst_height = 0;
+       media_format_h src_fmt = NULL;
+       media_format_h dst_fmt = NULL;
+
+       if ((handle == NULL) || (src_packet == NULL)) {
+               mm_util_error("Invalid parameter");
+               return MM_UTIL_ERROR_INVALID_PARAMETER;
+       }
 
        ret = __mm_get_info_from_media_packet(src_packet, &src_fmt, handle);
        if (ret != MM_UTIL_ERROR_NONE) {
                mm_util_error("__mm_get_info_from_packet failed");
                return ret;
        }
-       mm_util_debug("src: %p handle->src_packet: %p (%u X %u)", src_packet, handle->src_packet, handle->src_width, handle->src_height);
+       mm_util_debug("src: %p (%u X %u)", src_packet, handle->src_width, handle->src_height);
+
+       ret = __mm_util_processing(handle);
 
-       ret = __mm_get_dst_resolution(handle, &dst_width, &dst_height);
        if (ret != MM_UTIL_ERROR_NONE) {
-               mm_util_error("__mm_get_dst_resolution failed");
-               media_format_unref(src_fmt);
-               return ret;
+               mm_util_error("__mm_util_processing failed");
+               handle->dst_packet = NULL;
+               return MM_UTIL_ERROR_INVALID_PARAMETER;
        }
-       mm_util_debug("dst (%u X %u)", dst_width, dst_height);
 
-       ret = __mm_create_media_format(src_fmt, handle->dst_format_mime, dst_width, dst_height, &dst_fmt);
+       ret = __mm_create_media_format(src_fmt, handle->dst_format_mime, handle->dst_width, handle->dst_height, &dst_fmt);
        if (ret != MM_UTIL_ERROR_NONE) {
                mm_util_error("__mm_create_media_format failed");
                media_format_unref(src_fmt);
+               IMGP_FREE(handle->dst);
                return ret;
        }
        media_format_unref(src_fmt);
 
-       ret = __mm_create_media_packet(dst_fmt, &handle->dst_packet, &handle->dst_buf_size);
+       ret = __mm_create_media_packet_with_buffer(dst_fmt, handle->dst, handle->dst_buf_size, &handle->dst_packet);
        if (ret != MM_UTIL_ERROR_NONE) {
                mm_util_error("__mm_create_media_packet failed");
                media_format_unref(dst_fmt);
+               IMGP_FREE(handle->dst);
                return ret;
        }
 
        mm_util_debug("handle->src_packet: %p [%d] %d X %d (%d) => handle->dst_packet: %p [%d] %d X %d (%d)",
                handle->src_packet, handle->src_format, handle->src_width, handle->src_height, handle->src_buf_size,
-               handle->dst_packet, handle->dst_format, dst_width, dst_height, handle->dst_buf_size);
-
-       ret = __mm_util_processing(handle);
-
-       if (ret != MM_UTIL_ERROR_NONE) {
-               mm_util_error("__mm_util_processing failed");
-               media_packet_destroy(handle->dst_packet);
-               handle->dst_packet = NULL;
-               return MM_UTIL_ERROR_INVALID_PARAMETER;
-       }
+               handle->dst_packet, handle->dst_format, handle->dst_width, handle->dst_height, handle->dst_buf_size);
 
        media_format_unref(dst_fmt);
+       IMGP_FREE(handle->dst);
 
        return ret;
 }
index 4fbf371..756db84 100755 (executable)
@@ -1,6 +1,6 @@
 Name:       libmm-utility
 Summary:    Multimedia Framework Utility Library
-Version:    0.43
+Version:    0.44
 Release:    0
 Group:      System/Libraries
 License:    Apache-2.0