Fix stack memory corruption 42/229042/1
authorJeongmo Yang <jm80.yang@samsung.com>
Fri, 27 Mar 2020 08:04:41 +0000 (17:04 +0900)
committerJeongmo Yang <jm80.yang@samsung.com>
Fri, 27 Mar 2020 08:23:08 +0000 (17:23 +0900)
- The requested buffer count could be bigger than MAX_INPUT_BUFFER(16),
  but, there is no error handling and it caused stack memory corruption.
- Remove static memory declaration and use dynamic allocation with requested buffer count.

[Version] 1.16.2-2
[Profile] Common
[Issue Type] Bug fix

Change-Id: I6048881c8839661133e094079243b3e79f1cbda3
Signed-off-by: Jeongmo Yang <jm80.yang@samsung.com>
omx/gstomx.c
omx/gstomx.h
packaging/gst-omx.spec

index a4502b9..ac4f523 100644 (file)
@@ -2695,7 +2695,7 @@ gst_omx_port_tbm_allocate_dec_buffers (GstOMXPort * port)
   gint i = 0;
   gint num = 0;
   GList *buffers = NULL;
-  tbm_surface_h buffer[MAX_INPUT_BUFFER];
+  tbm_surface_h *surfaces = NULL;
   GstOMXComponent *comp;
   OMX_ERRORTYPE err = OMX_ErrorNone;
   OMX_CONFIG_RECTTYPE rect;
@@ -2717,44 +2717,57 @@ gst_omx_port_tbm_allocate_dec_buffers (GstOMXPort * port)
     rect.nHeight = port->port_def.format.video.nFrameHeight;
   }
 
-  g_mutex_lock (&port->comp->lock);
+  g_mutex_lock (&comp->lock);
 
   /* deallocate previous allocated buffers... */
   if (port->buffers)
       gst_omx_port_deallocate_buffers (port);
 
   if (port->use_buffer) {
+    surfaces = g_new0(tbm_surface_h, port->port_def.nBufferCountActual);
+    if (!surfaces) {
+      GST_ERROR_OBJECT (comp->parent, "tbm surface array failed");
+      goto error;
+    }
+
     for (i = 0; i < port->port_def.nBufferCountActual; i++) {
-      buffer[i] = tbm_surface_internal_create_with_flags (rect.nWidth, rect.nHeight, TBM_FORMAT_NV12, TBM_BO_WC);
-      if (!buffer[i]) {
-        g_mutex_unlock (&port->comp->lock);
+      surfaces[i] = tbm_surface_internal_create_with_flags (rect.nWidth, rect.nHeight, TBM_FORMAT_NV12, TBM_BO_WC);
+      if (!surfaces[i]) {
+        GST_ERROR_OBJECT (comp->parent, "tbm surface create failed [i:%d]", i);
         goto error;
       }
 
-      buffers = g_list_append (buffers, (gpointer) buffer[i]);
+      buffers = g_list_append (buffers, (gpointer) surfaces[i]);
 
       GST_INFO_OBJECT (comp->parent,
           "Allocating %d buffer surface : %p for %s port %u",
-          i, buffer[i], comp->name, (guint) port->index);
+          i, surfaces[i], comp->name, (guint) port->index);
     }
   }
 
   num = port->use_buffer ? g_list_length ((GList *) buffers) : -1;
   err = gst_omx_port_allocate_buffers_unlocked (port, buffers, NULL, num);
 
+  g_free(surfaces);
   g_list_free (buffers);
-  g_mutex_unlock (&port->comp->lock);
+  g_mutex_unlock (&comp->lock);
 
   return err;
 
 error:
-  for (i = 0; i < port->port_def.nBufferCountActual; i++) {
-    if (buffer[i]) {
-      tbm_surface_internal_destroy (buffer[i]);
-      buffer[i] = NULL;
+  if (surfaces) {
+    for (i = 0; i < port->port_def.nBufferCountActual; i++) {
+      if (surfaces[i])
+        tbm_surface_internal_destroy (surfaces[i]);
+      else
+        break;
     }
+    g_free(surfaces);
   }
+
   g_list_free (buffers);
+  g_mutex_unlock (&comp->lock);
+
   return OMX_ErrorInsufficientResources;
 }
 
@@ -2766,49 +2779,64 @@ gst_omx_port_tbm_allocate_enc_buffers (GstOMXPort * port)
   gint i = 0;
   gint num = 0;
   GList *buffers = NULL;
-  tbm_surface_h buffer[MAX_INPUT_BUFFER];
+  tbm_surface_h *surfaces = NULL;
+  GstOMXComponent *comp;
 
   g_return_val_if_fail (port != NULL, OMX_ErrorUndefined);
 
-  g_mutex_lock (&port->comp->lock);
+  comp = port->comp;
+
+  g_mutex_lock (&comp->lock);
 
   /* deallocate previous allocated buffers... */
   if (port->buffers)
     gst_omx_port_deallocate_buffers (port);
 
   if (port->use_buffer) {
+    surfaces = g_new0(tbm_surface_h, port->port_def.nBufferCountActual);
+    if (!surfaces) {
+      GST_ERROR_OBJECT (comp->parent, "tbm surface array failed");
+      goto error;
+    }
+
     for (i = 0; i < port->port_def.nBufferCountActual; i++) {
 
       /* Since the input buffer is queued via OMX_EmptyThisBuffer(),
        * a minimum amount of memory is sufficient.
        */
-      buffer[i] = tbm_surface_internal_create_with_flags (128, 128, TBM_FORMAT_NV12, TBM_BO_WC);
-
-      if (!buffer[i]) {
-        g_mutex_unlock (&port->comp->lock);
+      surfaces[i] = tbm_surface_internal_create_with_flags (128, 128, TBM_FORMAT_NV12, TBM_BO_WC);
+      if (!surfaces[i]) {
+        GST_ERROR_OBJECT (comp->parent, "tbm surface create failed [i:%d]", i);
         goto error;
       }
 
-      buffers = g_list_append (buffers, (gpointer) buffer[i]);
+      buffers = g_list_append (buffers, (gpointer) surfaces[i]);
     }
   }
 
   num = port->use_buffer ? g_list_length ((GList *) buffers) : -1;
   err = gst_omx_port_allocate_buffers_unlocked (port, buffers, NULL, num);
 
+  g_free(surfaces);
   g_list_free (buffers);
-  g_mutex_unlock (&port->comp->lock);
+  g_mutex_unlock (&comp->lock);
 
   return err;
 
 error:
-  for (i = 0; i < port->port_def.nBufferCountActual; i++) {
-    if (buffer[i]) {
-      tbm_surface_internal_destroy (buffer[i]);
-      buffer[i] = NULL;
+  if (surfaces) {
+    for (i = 0; i < port->port_def.nBufferCountActual; i++) {
+      if (surfaces[i])
+        tbm_surface_internal_destroy (surfaces[i]);
+      else
+        break;
     }
+    g_free(surfaces);
   }
+
   g_list_free (buffers);
+  g_mutex_unlock (&comp->lock);
+
   return OMX_ErrorInsufficientResources;
 }
 #endif
index fdf7d6d..607d3e7 100644 (file)
@@ -240,9 +240,6 @@ typedef enum GOmxVendor GOmxVendor; /* check omx vender */
 #define MFC_OUTPUT_BUFFER_PLANE     2
 #define MAX_BUFFER_PLANE            3
 
-#define MAX_INPUT_BUFFER            16
-#define MAX_OUTPUT_BUFFER           16
-
 #define ALIGN(x, a)       (((x) + (a) - 1) & ~((a) - 1))
 
 typedef struct _EnableGemBuffersParams EnableGemBuffersParams;
index d839292..b62c8e4 100755 (executable)
@@ -1,7 +1,7 @@
 Name:           gst-omx
 Summary:        GStreamer plug-in that allows communication with OpenMAX IL components
 Version:        1.16.2
-Release:        1
+Release:        2
 License:        LGPL-2.1+
 Group:          Multimedia/Framework
 Source0:        %{name}-%{version}.tar.gz