video-converter: Guard against invalid frame input
authorJan Schmidt <jan@centricular.com>
Fri, 5 Jun 2020 13:34:44 +0000 (23:34 +1000)
committerGStreamer Merge Bot <gitlab-merge-bot@gstreamer-foundation.org>
Fri, 12 Jun 2020 06:49:56 +0000 (06:49 +0000)
If the frames passed in to gst_video_converter_frame()
have a different layout than was configured for, the
conversion code might go out of bounds and crash.

Do a sanity check on each frame passed in, and in the
absence of a return value in the API, just
refuse the conversion in invalid cases and leave the
destination frame untouched so it's obvious to
users that it was broken.

Part-of: <https://gitlab.freedesktop.org/gstreamer/gst-plugins-base/-/merge_requests/696>

gst-libs/gst/video/video-converter.c
tests/check/libs/video.c

index 0f1d62c..3f5fa44 100644 (file)
@@ -2674,6 +2674,27 @@ gst_video_converter_frame (GstVideoConverter * convert,
   g_return_if_fail (src != NULL);
   g_return_if_fail (dest != NULL);
 
+  /* Check the frames we've been passed match the layout
+   * we were configured for or we might go out of bounds */
+  if (G_UNLIKELY (GST_VIDEO_INFO_FORMAT (&convert->in_info) !=
+          GST_VIDEO_FRAME_FORMAT (src)
+          || GST_VIDEO_INFO_WIDTH (&convert->in_info) !=
+          GST_VIDEO_FRAME_WIDTH (src)
+          || GST_VIDEO_INFO_HEIGHT (&convert->in_info) !=
+          GST_VIDEO_FRAME_HEIGHT (src))) {
+    g_critical ("Input video frame does not match configuration");
+    return;
+  }
+  if (G_UNLIKELY (GST_VIDEO_INFO_FORMAT (&convert->out_info) !=
+          GST_VIDEO_FRAME_FORMAT (dest)
+          || GST_VIDEO_INFO_WIDTH (&convert->out_info) !=
+          GST_VIDEO_FRAME_WIDTH (dest)
+          || GST_VIDEO_INFO_HEIGHT (&convert->out_info) !=
+          GST_VIDEO_FRAME_HEIGHT (dest))) {
+    g_critical ("Output video frame does not match configuration");
+    return;
+  }
+
   convert->convert (convert, src, dest);
 }
 
index f33f56a..97b316f 100644 (file)
@@ -2683,6 +2683,15 @@ GST_START_TEST (test_video_convert)
           GST_VIDEO_CONVERTER_OPT_DEST_HEIGHT, G_TYPE_INT, 230, NULL));
 
   gst_video_converter_frame (convert, &inframe, &outframe);
+
+  /* Check that video convert doesn't crash if we give it frames with different info
+   * than we configured it with by swapping width/height */
+  gst_video_frame_unmap (&inframe);
+  fail_unless (gst_video_info_set_format (&ininfo, GST_VIDEO_FORMAT_ARGB, 240,
+          320));
+  gst_video_frame_map (&inframe, &ininfo, inbuffer, GST_MAP_READ);
+  ASSERT_CRITICAL (gst_video_converter_frame (convert, &inframe, &outframe));
+
   gst_video_converter_free (convert);
 
   gst_video_frame_unmap (&outframe);