A ref count above 16 which is possible for field pictures causes an out
of bounds write into the following ref_cache array.

The bogus data results in a negative index for the reference list array
during decoding of the fuzzed sample HPCVFL_BRCM_A.264_s18662.
---
 libavcodec/h264_direct.c | 12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/libavcodec/h264_direct.c b/libavcodec/h264_direct.c
index f0c6eb5..1564bcd 100644
--- a/libavcodec/h264_direct.c
+++ b/libavcodec/h264_direct.c
@@ -56,14 +56,22 @@ void ff_h264_direct_dist_scale_factor(H264Context * const 
h){
     const int poc = h->s.current_picture_ptr->field_poc[ s->picture_structure 
== PICT_BOTTOM_FIELD ];
     const int poc1 = h->ref_list[1][0].poc;
     int i, field;
+    int ref_count = h->ref_count[0];
+
+    // FIXME: this function assumes ref_count never to exceed 16
+    if (ref_count > 16) {
+        ref_count = 16;
+        av_log_missing_feature(s->avctx, "Direct spatial prediction with "
+                               "ref_count > 16", 1);
+    }
     for(field=0; field<2; field++){
         const int poc  = h->s.current_picture_ptr->field_poc[field];
         const int poc1 = h->ref_list[1][0].field_poc[field];
-        for(i=0; i < 2*h->ref_count[0]; i++)
+        for (i = 0; i < 2 * ref_count; i++)
             h->dist_scale_factor_field[field][i^field] = get_scale_factor(h, 
poc, poc1, i+16);
     }
 
-    for(i=0; i<h->ref_count[0]; i++){
+    for (i = 0; i < ref_count; i++) {
         h->dist_scale_factor[i] = get_scale_factor(h, poc, poc1, i);
     }
 }
-- 
1.7.12.4

_______________________________________________
libav-devel mailing list
[email protected]
https://lists.libav.org/mailman/listinfo/libav-devel

Reply via email to