h264_ps: properly check cropping parameters against overflow

Message ID 20150321084456.BE2195DCE6@aruru.libav.org
State New
Headers show

Commit Message

Janne Grunau March 21, 2015, 8:44 a.m.
Module: libav
Branch: master
Commit: d8a45d2d49f54fde042b195f9d5859251252493d

Author:    Anton Khirnov <anton@khirnov.net>
Committer: Anton Khirnov <anton@khirnov.net>
Date:      Fri Mar 20 21:49:23 2015 +0100

h264_ps: properly check cropping parameters against overflow

CC: libav-stable@libav.org

---

 libavcodec/h264_ps.c |   20 ++++++++++++++++----
 1 file changed, 16 insertions(+), 4 deletions(-)

Patch

diff --git a/libavcodec/h264_ps.c b/libavcodec/h264_ps.c
index b439fa8..ad284da 100644
--- a/libavcodec/h264_ps.c
+++ b/libavcodec/h264_ps.c
@@ -439,10 +439,10 @@  int ff_h264_decode_seq_parameter_set(H264Context *h)
 #endif
     sps->crop = get_bits1(&h->gb);
     if (sps->crop) {
-        int crop_left   = get_ue_golomb(&h->gb);
-        int crop_right  = get_ue_golomb(&h->gb);
-        int crop_top    = get_ue_golomb(&h->gb);
-        int crop_bottom = get_ue_golomb(&h->gb);
+        unsigned int crop_left   = get_ue_golomb(&h->gb);
+        unsigned int crop_right  = get_ue_golomb(&h->gb);
+        unsigned int crop_top    = get_ue_golomb(&h->gb);
+        unsigned int crop_bottom = get_ue_golomb(&h->gb);
 
         if (h->avctx->flags2 & CODEC_FLAG2_IGNORE_CROP) {
             av_log(h->avctx, AV_LOG_DEBUG, "discarding sps cropping, original "
@@ -469,6 +469,18 @@  int ff_h264_decode_seq_parameter_set(H264Context *h)
                        crop_left);
             }
 
+            if (INT_MAX / step_x             <= crop_left               ||
+                INT_MAX / step_x - crop_left <= crop_right              ||
+                16 * sps->mb_width <= step_x * (crop_left + crop_right) ||
+                INT_MAX / step_y             <= crop_top                ||
+                INT_MAX / step_y - crop_top  <= crop_bottom             ||
+                16 * sps->mb_height <= step_y * (crop_top + crop_bottom)) {
+                av_log(h->avctx, AV_LOG_WARNING, "Invalid crop parameters\n");
+                if (h->avctx->err_recognition & AV_EF_EXPLODE)
+                    goto fail;
+                crop_left = crop_right = crop_top = crop_bottom = 0;
+            }
+
             sps->crop_left   = crop_left   * step_x;
             sps->crop_right  = crop_right  * step_x;
             sps->crop_top    = crop_top    * step_y;