File gstreamer-plugins-bad-CVE-2023-40474.patch of Package gstreamer-plugins-bad.32821

commit ce17e968e4cf900d28ca5b46f6e095febc42b4f0
Author: Sebastian Dröge <sebastian@centricular.com>
Date:   Thu Aug 10 15:45:01 2023 +0300

    mxfdemux: Fix integer overflow causing out of bounds writes when handling invalid uncompressed video
    
    Check ahead of time when parsing the track information whether
    width, height and bpp are valid and usable without overflows.
    
    Fixes ZDI-CAN-21660, CVE-2023-40474
    
    Fixes https://gitlab.freedesktop.org/gstreamer/gstreamer/-/issues/2896
    
    Part-of: <https://gitlab.freedesktop.org/gstreamer/gstreamer/-/merge_requests/5362>

diff -Nura gst-plugins-bad-1.16.3/gst/mxf/mxfup.c gst-plugins-bad-1.16.3_new/gst/mxf/mxfup.c
--- gst-plugins-bad-1.16.3/gst/mxf/mxfup.c	2019-04-19 17:16:36.000000000 +0800
+++ gst-plugins-bad-1.16.3_new/gst/mxf/mxfup.c	2023-11-10 20:09:01.269626114 +0800
@@ -134,6 +134,8 @@
     gpointer mapping_data, GstBuffer ** outbuf)
 {
   MXFUPMappingData *data = mapping_data;
+  gsize expected_in_stride = 0, out_stride = 0;
+  gsize expected_in_size = 0, out_size = 0;
 
   /* SMPTE 384M 7.1 */
   if (key->u[12] != 0x15 || (key->u[14] != 0x01 && key->u[14] != 0x02
@@ -162,22 +164,25 @@
     }
   }
 
-  if (gst_buffer_get_size (buffer) != data->bpp * data->width * data->height) {
+  // Checked for overflows when parsing the descriptor
+  expected_in_stride = data->bpp * data->width;
+  out_stride = GST_ROUND_UP_4 (expected_in_stride);
+  expected_in_size = expected_in_stride * data->height;
+  out_size = out_stride * data->height;
+
+  if (gst_buffer_get_size (buffer) != expected_in_size) {
     GST_ERROR ("Invalid buffer size");
     gst_buffer_unref (buffer);
     return GST_FLOW_ERROR;
   }
 
-  if (data->bpp != 4
-      || GST_ROUND_UP_4 (data->width * data->bpp) != data->width * data->bpp) {
+  if (data->bpp != 4 || out_stride != expected_in_stride) {
     guint y;
     GstBuffer *ret;
     GstMapInfo inmap, outmap;
     guint8 *indata, *outdata;
 
-    ret =
-        gst_buffer_new_and_alloc (GST_ROUND_UP_4 (data->width * data->bpp) *
-        data->height);
+    ret = gst_buffer_new_and_alloc (out_size);
     gst_buffer_map (buffer, &inmap, GST_MAP_READ);
     gst_buffer_map (ret, &outmap, GST_MAP_WRITE);
     indata = inmap.data;
@@ -185,8 +190,8 @@
 
     for (y = 0; y < data->height; y++) {
       memcpy (outdata, indata, data->width * data->bpp);
-      outdata += GST_ROUND_UP_4 (data->width * data->bpp);
-      indata += data->width * data->bpp;
+      outdata += out_stride;
+      indata += expected_in_stride;
     }
 
     gst_buffer_unmap (buffer, &inmap);
@@ -394,6 +399,36 @@
     return NULL;
   }
 
+  if (caps) {
+    MXFUPMappingData *data = *mapping_data;
+    gsize expected_in_stride = 0, out_stride = 0;
+    gsize expected_in_size = 0, out_size = 0;
+
+    // Do some checking of the parameters to see if they're valid and
+    // we can actually work with them.
+    if (data->image_start_offset > data->image_end_offset) {
+      GST_WARNING ("Invalid image start/end offset");
+      g_free (data);
+      *mapping_data = NULL;
+      gst_clear_caps (&caps);
+
+      return NULL;
+    }
+
+    if (!g_size_checked_mul (&expected_in_stride, data->bpp, data->width) ||
+        (out_stride = GST_ROUND_UP_4 (expected_in_stride)) < expected_in_stride
+        || !g_size_checked_mul (&expected_in_size, expected_in_stride,
+            data->height)
+        || !g_size_checked_mul (&out_size, out_stride, data->height)) {
+      GST_ERROR ("Invalid resolution or bit depth");
+      g_free (data);
+      *mapping_data = NULL;
+      gst_clear_caps (&caps);
+
+      return NULL;
+    }
+  }
+
   return caps;
 }
 
openSUSE Build Service is sponsored by